Skip to content

Commit 635ff2a

Browse files
committed
Adopt @tex3d's feedback in intrinsic lowering.
This also results in correctly disabling scalarization for a number of intrinsics too. ../tools/clang/test/CodeGenDXIL/hlsl/types/longvec-scalarized-intrinsics .hlsl ../tools/clang/test/CodeGenDXIL/hlsl/types/longvec-trivial-scalarized-in trinsics.hlsl
1 parent 1b6b934 commit 635ff2a

3 files changed

Lines changed: 114 additions & 170 deletions

File tree

lib/HLSL/HLOperationLower.cpp

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -484,16 +484,17 @@ Value *TrivialDxilVectorOperation(Function *Func, OP::OpCode Opcode,
484484
// Generates a DXIL operation with the overloaded type based on `Ty` and return
485485
// type `RetTy`. When Ty is a vector, it will either generate per-element calls
486486
// for each vector element and reconstruct the vector type from those results or
487-
// operate on and return native vectors depending on vector size and the value
488-
// of `SupportsVectors`, which is deteremined by version and opcode support.
487+
// operate on and return native vectors depending on vector size and the
488+
// legality of the vector overload.
489489
Value *TrivialDxilOperation(OP::OpCode opcode, ArrayRef<Value *> refArgs,
490490
Type *Ty, Type *RetTy, OP *hlslOP,
491-
IRBuilder<> &Builder,
492-
bool SupportsVectors = false) {
491+
IRBuilder<> &Builder) {
493492

494493
// If supported and the overload type is a vector with more than 1 element,
495494
// create a native vector operation.
496-
if (SupportsVectors && Ty->isVectorTy() && Ty->getVectorNumElements() > 1) {
495+
if (Ty->isVectorTy() && Ty->getVectorNumElements() > 1 &&
496+
hlslOP->GetModule()->GetHLModule().GetShaderModel()->IsSM69Plus() &&
497+
OP::IsOverloadLegal(opcode, Ty)) {
497498
Function *dxilFunc = hlslOP->GetOpFunc(opcode, Ty);
498499
return TrivialDxilVectorOperation(dxilFunc, opcode, refArgs, Ty, hlslOP,
499500
Builder);
@@ -540,40 +541,34 @@ Value *TrivialUnaryOperationRet(CallInst *CI, IntrinsicOp IOP,
540541
}
541542

542543
Value *TrivialDxilUnaryOperation(OP::OpCode OpCode, Value *Src, hlsl::OP *Op,
543-
IRBuilder<> &Builder,
544-
bool SupportsVectors = false) {
544+
IRBuilder<> &Builder) {
545545
Type *Ty = Src->getType();
546546

547547
Constant *OpArg = Op->GetU32Const((unsigned)OpCode);
548548
Value *Args[] = {OpArg, Src};
549549

550-
return TrivialDxilOperation(OpCode, Args, Ty, Ty, Op, Builder,
551-
SupportsVectors);
550+
return TrivialDxilOperation(OpCode, Args, Ty, Ty, Op, Builder);
552551
}
553552

554553
Value *TrivialDxilBinaryOperation(OP::OpCode opcode, Value *src0, Value *src1,
555-
hlsl::OP *hlslOP, IRBuilder<> &Builder,
556-
bool SupportsVectors = false) {
554+
hlsl::OP *hlslOP, IRBuilder<> &Builder) {
557555
Type *Ty = src0->getType();
558556

559557
Constant *opArg = hlslOP->GetU32Const((unsigned)opcode);
560558
Value *args[] = {opArg, src0, src1};
561559

562-
return TrivialDxilOperation(opcode, args, Ty, Ty, hlslOP, Builder,
563-
SupportsVectors);
560+
return TrivialDxilOperation(opcode, args, Ty, Ty, hlslOP, Builder);
564561
}
565562

566563
Value *TrivialDxilTrinaryOperation(OP::OpCode opcode, Value *src0, Value *src1,
567564
Value *src2, hlsl::OP *hlslOP,
568-
IRBuilder<> &Builder,
569-
bool SupportsVectors = false) {
565+
IRBuilder<> &Builder) {
570566
Type *Ty = src0->getType();
571567

572568
Constant *opArg = hlslOP->GetU32Const((unsigned)opcode);
573569
Value *args[] = {opArg, src0, src1, src2};
574570

575-
return TrivialDxilOperation(opcode, args, Ty, Ty, hlslOP, Builder,
576-
SupportsVectors);
571+
return TrivialDxilOperation(opcode, args, Ty, Ty, hlslOP, Builder);
577572
}
578573

579574
// Translate call that trivially converts to a dxil unary operation by passing
@@ -587,8 +582,7 @@ Value *TrivialUnaryOperation(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
587582
IRBuilder<> Builder(CI);
588583
hlsl::OP *hlslOP = &helper.hlslOP;
589584

590-
return TrivialDxilUnaryOperation(opcode, src0, hlslOP, Builder,
591-
helper.M.GetShaderModel()->IsSM69Plus());
585+
return TrivialDxilUnaryOperation(opcode, src0, hlslOP, Builder);
592586
}
593587

594588
// Translate call that trivially converts to a dxil binary operation by passing
@@ -603,8 +597,7 @@ Value *TrivialBinaryOperation(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
603597
Value *src1 = CI->getArgOperand(HLOperandIndex::kBinaryOpSrc1Idx);
604598
IRBuilder<> Builder(CI);
605599

606-
return TrivialDxilBinaryOperation(opcode, src0, src1, hlslOP, Builder,
607-
helper.M.GetShaderModel()->IsSM69Plus());
600+
return TrivialDxilBinaryOperation(opcode, src0, src1, hlslOP, Builder);
608601
}
609602

610603
// Translate call that trivially converts to a dxil trinary (aka tertiary)
@@ -621,8 +614,7 @@ Value *TrivialTrinaryOperation(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
621614
Value *src2 = CI->getArgOperand(HLOperandIndex::kTrinaryOpSrc2Idx);
622615
IRBuilder<> Builder(CI);
623616

624-
return TrivialDxilTrinaryOperation(opcode, src0, src1, src2, hlslOP, Builder,
625-
helper.M.GetShaderModel()->IsSM69Plus());
617+
return TrivialDxilTrinaryOperation(opcode, src0, src1, src2, hlslOP, Builder);
626618
}
627619

628620
Value *TrivialIsSpecialFloat(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
@@ -1969,11 +1961,9 @@ Value *TranslateClamp(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
19691961

19701962
IRBuilder<> Builder(CI);
19711963
// min(max(x, minVal), maxVal).
1972-
bool SupportsVectors = helper.M.GetShaderModel()->IsSM69Plus();
19731964
Value *maxXMinVal = TrivialDxilBinaryOperation(maxOp, x, minVal, hlslOP,
1974-
Builder, SupportsVectors);
1975-
return TrivialDxilBinaryOperation(minOp, maxXMinVal, maxVal, hlslOP, Builder,
1976-
SupportsVectors);
1965+
Builder);
1966+
return TrivialDxilBinaryOperation(minOp, maxXMinVal, maxVal, hlslOP, Builder);
19771967
}
19781968

19791969
Value *TranslateClip(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
@@ -2287,8 +2277,7 @@ Value *TranslateExp(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
22872277
}
22882278
val = Builder.CreateFMul(log2eConst, val);
22892279

2290-
return TrivialDxilUnaryOperation(OP::OpCode::Exp, val, hlslOP, Builder,
2291-
helper.M.GetShaderModel()->IsSM69Plus());
2280+
return TrivialDxilUnaryOperation(OP::OpCode::Exp, val, hlslOP, Builder);
22922281
}
22932282

22942283
Value *TranslateLog(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
@@ -2305,8 +2294,7 @@ Value *TranslateLog(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
23052294
}
23062295

23072296
Value *log =
2308-
TrivialDxilUnaryOperation(OP::OpCode::Log, val, hlslOP, Builder,
2309-
helper.M.GetShaderModel()->IsSM69Plus());
2297+
TrivialDxilUnaryOperation(OP::OpCode::Log, val, hlslOP, Builder);
23102298

23112299
return Builder.CreateFMul(ln2Const, log);
23122300
}
@@ -2325,8 +2313,7 @@ Value *TranslateLog10(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
23252313
ConstantVector::getSplat(Ty->getVectorNumElements(), log2_10Const);
23262314
}
23272315
Value *log =
2328-
TrivialDxilUnaryOperation(OP::OpCode::Log, val, hlslOP, Builder,
2329-
helper.M.GetShaderModel()->IsSM69Plus());
2316+
TrivialDxilUnaryOperation(OP::OpCode::Log, val, hlslOP, Builder);
23302317

23312318
return Builder.CreateFMul(log2_10Const, log);
23322319
}
@@ -2690,8 +2677,7 @@ Value *TranslateSmoothStep(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
26902677
Value *satVal = Builder.CreateFDiv(xSubMin, maxSubMin);
26912678

26922679
Value *s =
2693-
TrivialDxilUnaryOperation(DXIL::OpCode::Saturate, satVal, hlslOP, Builder,
2694-
helper.M.GetShaderModel()->IsSM69Plus());
2680+
TrivialDxilUnaryOperation(DXIL::OpCode::Saturate, satVal, hlslOP, Builder);
26952681
// return s * s *(3-2*s).
26962682
Constant *c2 = ConstantFP::get(CI->getType(), 2);
26972683
Constant *c3 = ConstantFP::get(CI->getType(), 3);
Lines changed: 93 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,115 @@
1-
// RUN: %dxc -T ps_6_9 %s | FileCheck %s
1+
// RUN: %dxc -T lib_6_9 %s | FileCheck %s
22

33
// Long vector tests for vec ops that scalarize to something more complex
44
// than a simple repetition of the same dx.op calls.
55

6-
StructuredBuffer< vector<float, 8> > buf;
7-
ByteAddressBuffer rbuf;
8-
9-
float4 main(uint i : SV_PrimitiveID, bool b : B) : SV_Target {
10-
vector<float, 8> vec1 = rbuf.Load< vector<float, 8> >(i++*32);
11-
vector<float, 8> vec2 = rbuf.Load< vector<float, 8> >(i++*32);
12-
vector<float, 8> vec3 = rbuf.Load< vector<float, 8> >(i++*32);
13-
14-
// CHECK: fdiv fast <8 x float>
15-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
16-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
17-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
18-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
19-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
20-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
21-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
22-
// CHECK: call float @dx.op.unary.f32(i32 17, float %{{.*}}) ; Atan(value)
23-
// CHECK: fadd fast <8 x float> %{{.*}}, <float 0x
24-
// CHECK: fadd fast <8 x float> %{{.*}}, <float 0x
25-
// CHECK: fcmp fast olt <8 x float>
26-
// CHECK: fcmp fast oeq <8 x float>
27-
// CHECK: fcmp fast oge <8 x float>
28-
// CHECK: fcmp fast olt <8 x float>
29-
// CHECK: and <8 x i1>
30-
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
31-
// CHECK: and <8 x i1>
32-
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
33-
// CHECK: and <8 x i1>
34-
// CHECK: select <8 x i1> %{{.*}}, <8 x float> <float 0x
35-
// CHECK: and <8 x i1>
36-
// CHECK: select <8 x i1> %{{.*}}, <8 x float> <float 0x
6+
// CHECK-LABEL: test_atan2
7+
// CHECK: fdiv fast <8 x float>
8+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 17, <8 x float> %{{.*}}) ; Atan(value)
9+
// CHECK: fadd fast <8 x float> %{{.*}}, <float 0x
10+
// CHECK: fadd fast <8 x float> %{{.*}}, <float 0x
11+
// CHECK: fcmp fast olt <8 x float>
12+
// CHECK: fcmp fast oeq <8 x float>
13+
// CHECK: fcmp fast oge <8 x float>
14+
// CHECK: fcmp fast olt <8 x float>
15+
// CHECK: and <8 x i1>
16+
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
17+
// CHECK: and <8 x i1>
18+
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
19+
// CHECK: and <8 x i1>
20+
// CHECK: select <8 x i1> %{{.*}}, <8 x float> <float 0x
21+
// CHECK: and <8 x i1>
22+
// CHECK: select <8 x i1> %{{.*}}, <8 x float> <float 0x
23+
export void test_atan2(inout vector<float, 8> vec1, vector<float, 8> vec2) {
3724
vec1 = atan2(vec1, vec2);
25+
}
3826

27+
// CHECK-LABEL: test_fmod
28+
// CHECK: fdiv fast <8 x float>
29+
// CHECK: fsub fast <8 x float> <float
30+
// CHECK: fcmp fast oge <8 x float>
31+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 6, <8 x float> %{{.*}}) ; FAbs(value)
32+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 22, <8 x float> %{{.*}}) ; Frc(value)
3933

40-
// CHECK: fdiv fast <8 x float>
41-
// CHECK: fsub fast <8 x float> <float
42-
// CHECK: fcmp fast oge <8 x float>
43-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
44-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
45-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
46-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
47-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
48-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
49-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
50-
// CHECK: call float @dx.op.unary.f32(i32 6, float %{{.*}}) ; FAbs(value)
51-
52-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
53-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
54-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
55-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
56-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
57-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
58-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
59-
// CHECK: call float @dx.op.unary.f32(i32 22, float %{{.*}}) ; Frc(value)
60-
61-
// CHECK: fsub fast <8 x float> <float
62-
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
63-
// CHECK: fmul fast <8 x float>
34+
// CHECK: fsub fast <8 x float> <float
35+
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float>
36+
// CHECK: fmul fast <8 x float>
37+
export void test_fmod(inout vector<float, 8> vec1, vector<float, 8> vec2) {
6438
vec1 = fmod(vec1, vec2);
39+
}
40+
41+
// CHECK-LABEL: test_ldexp
42+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 21, <8 x float> %{{.*}}) ; Exp(value)
43+
// CHECK: fmul fast <8 x float>
6544

66-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
67-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
68-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
69-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
70-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
71-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
72-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
73-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
74-
// CHECK: fmul fast <8 x float>
45+
export void test_ldexp(inout vector<float, 8> vec1, vector<float, 8> vec2) {
7546
vec1 = ldexp(vec1, vec2);
47+
}
48+
7649

77-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
78-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
79-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
80-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
81-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
82-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
83-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
84-
// CHECK: call float @dx.op.unary.f32(i32 23, float %{{.*}}) ; Log(value)
85-
// CHECK: fmul fast <8 x float>
86-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
87-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
88-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
89-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
90-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
91-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
92-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
93-
// CHECK: call float @dx.op.unary.f32(i32 21, float %{{.*}}) ; Exp(value)
50+
// CHECK-LABEL: test_pow
51+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 23, <8 x float> %{{.*}}) ; Log(value)
52+
// CHECK: fmul fast <8 x float>
53+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 21, <8 x float> %{{.*}}) ; Exp(value)
54+
export void test_pow(inout vector<float, 8> vec1, vector<float, 8> vec2) {
9455
vec1 = pow(vec1, vec2);
56+
}
9557

96-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
97-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
98-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
99-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
100-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
101-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
102-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
103-
// CHECK: call float @dx.op.unary.f32(i32 29, float %{{.*}}) ; Round_z(value)
104-
// CHECK: fsub fast <8 x float>
58+
// CHECK-LABEL: test_modf
59+
// CHECK: call <8 x float> @dx.op.unary.v8f32(i32 29, <8 x float> %{{.*}}) ; Round_z(value)
60+
// CHECK: fsub fast <8 x float>
61+
export void test_modf(inout vector<float, 8> vec1, vector<float, 8> vec2) {
10562
vec1 = modf(vec1, vec2);
63+
}
10664

107-
// CHECK: [[el:%.*]] = extractelement <8 x float>
108-
// CHECK: [[mul:%.*]] = fmul fast float [[el]]
109-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mul]]) ; FMad(a,b,c)
110-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
111-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
112-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
113-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
114-
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
115-
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
65+
// CHECK-LABEL: test_dot
66+
// CHECK: [[el:%.*]] = extractelement <8 x float>
67+
// CHECK: [[mul:%.*]] = fmul fast float [[el]]
68+
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[mul]]) ; FMad(a,b,c)
69+
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
70+
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
71+
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
72+
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
73+
// CHECK: [[pong:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[ping]]) ; FMad(a,b,c)
74+
// CHECK: [[ping:%.*]] = call float @dx.op.tertiary.f32(i32 46, float %{{.*}}, float %{{.*}}, float [[pong]]) ; FMad(a,b,c)
75+
export void test_dot(inout vector<float, 8> vec1, vector<float, 8> vec2) {
11676
vec1 = dot(vec1, vec2);
77+
}
11778

118-
vector<bool, 8> bvec = b;
119-
// CHECK: or i1
120-
// CHECK: or i1
121-
// CHECK: or i1
122-
// CHECK: or i1
123-
// CHECK: or i1
124-
// CHECK: or i1
125-
// CHECK: or i1
79+
// CHECK-LABEL: test_any
80+
// CHECK: or i1
81+
// CHECK: or i1
82+
// CHECK: or i1
83+
// CHECK: or i1
84+
// CHECK: or i1
85+
// CHECK: or i1
86+
// CHECK: or i1
87+
export void test_any(vector<float, 8> vec1, inout vector<bool, 8> bvec) {
12688
bvec &= any(vec1);
89+
}
12790

128-
// CHECK: and i1
129-
// CHECK: and i1
130-
// CHECK: and i1
131-
// CHECK: and i1
132-
// CHECK: and i1
133-
// CHECK: and i1
134-
// CHECK: and i1
135-
bvec &= all(vec2);
91+
// CHECK-LABEL: test_all
92+
// CHECK: and i1
93+
// CHECK: and i1
94+
// CHECK: and i1
95+
// CHECK: and i1
96+
// CHECK: and i1
97+
// CHECK: and i1
98+
// CHECK: and i1
99+
export void test_all(vector<float, 8> vec1, inout vector<bool, 8> bvec) {
100+
bvec &= all(vec1);
101+
}
136102

137-
// call {{.*}} @dx.op.wave
138-
// call {{.*}} @dx.op.wave
139-
// call {{.*}} @dx.op.wave
140-
// call {{.*}} @dx.op.wave
141-
// call {{.*}} @dx.op.wave
142-
// call {{.*}} @dx.op.wave
143-
// call {{.*}} @dx.op.wave
144-
// call {{.*}} @dx.op.wave
145-
// call {{.*}} @dx.op.wave
103+
// CHECK-LABEL: test_WaveMatch
104+
// call {{.*}} @dx.op.wave
105+
// call {{.*}} @dx.op.wave
106+
// call {{.*}} @dx.op.wave
107+
// call {{.*}} @dx.op.wave
108+
// call {{.*}} @dx.op.wave
109+
// call {{.*}} @dx.op.wave
110+
// call {{.*}} @dx.op.wave
111+
// call {{.*}} @dx.op.wave
112+
// call {{.*}} @dx.op.wave
113+
export uint4 test_WaveMatch(vector<bool, 8> bvec) {
146114
return WaveMatch(bvec);
147115
}

0 commit comments

Comments
 (0)