Skip to content

Commit d6dc036

Browse files
authored
Fix and/or intrinsics with non-int parameters (cp to 1.8.2502) (microsoft#7099)
And/or intrinsics were set to allow any parameters, which is consistent with the behavior of the && and || operators they were meant to replace, however this meant that if they were passed floating point values, those values would be applied to the binary and/or operands, which isn't allowed. Instead, they should be converted to booleans to be consistent with the behavior of && and ||. This can be done simply by restricting the parameters to booleans which forces the appropriate conversions. Adds tests for for using bools, ints, and floats in scalars, different sized vectors, and matrices as parameters to or and and. Fixes: microsoft#7057 FIxes: microsoft#6995 (cherry picked from commit 25faa88)
1 parent e72bc64 commit d6dc036

File tree

6 files changed

+387
-2
lines changed

6 files changed

+387
-2
lines changed

docs/ReleaseNotes.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ The included licenses apply to the following files:
2222
- The incomplete WaveMatrix implementation has been removed.
2323
- DXIL Validator Hash is open sourced.
2424
- DXIL container validation for PSV0 part allows any content ordering inside string and semantic index tables.
25+
- The and() and or() intrinsics will now accept non-integer parameters by casting them to bools.
2526

2627
### Version 1.8.2407
2728

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32
2+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32
3+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32
4+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32
5+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32
6+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32
7+
8+
// I32: %dx.types.ResRet.[[TY:i32]] = type { [[TYPE:i32]]
9+
// F32: %dx.types.ResRet.[[TY:f32]] = type { [[TYPE:float]]
10+
11+
// CHECK-LABEL: define void @main
12+
13+
ByteAddressBuffer buf;
14+
15+
float4 main() : SV_Target {
16+
17+
// CHECK-DAG: [[SAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 0
18+
// CHECK-DAG: [[SAX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0
19+
// I32-DAG: [[SA:%.*]] = icmp ne i32 [[SAX]], 0
20+
// F32-DAG: [[SA:%.*]] = fcmp fast une float [[SAX]], 0.000000e+00
21+
22+
// CHECK-DAG: [[SBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 8
23+
// CHECK-DAG: [[SBX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0
24+
// I32-DAG: [[SB:%.*]] = icmp ne i32 [[SBX]], 0
25+
// F32-DAG: [[SB:%.*]] = fcmp fast une float [[SBX]], 0.000000e+00
26+
27+
TYPE sb = buf.Load<TYPE>(8);
28+
TYPE sa = buf.Load<TYPE>(0);
29+
30+
// CHECK: and i1 [[SB]], [[SA]]
31+
TYPE res = and(sa, sb);
32+
33+
// CHECK-DAG: [[V1AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 16
34+
// CHECK-DAG: [[V1AX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0
35+
// I32-DAG: [[V1A:%.*]] = icmp ne i32 [[V1AX]], 0
36+
// F32-DAG: [[V1A:%.*]] = fcmp fast une float [[V1AX]], 0.000000e+00
37+
38+
// CHECK-DAG: [[V1BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 24
39+
// CHECK-DAG: [[V1BX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0
40+
// I32-DAG: [[V1B:%.*]] = icmp ne i32 [[V1BX]], 0
41+
// F32-DAG: [[V1B:%.*]] = fcmp fast une float [[V1BX]], 0.000000e+00
42+
43+
vector<TYPE, 1> v1b = buf.Load< vector<TYPE, 1> >(24);
44+
vector<TYPE, 1> v1a = buf.Load< vector<TYPE, 1> >(16);
45+
46+
// CHECK: and i1 [[V1B]], [[V1A]]
47+
vector<TYPE, 1> res1 = and(v1a, v1b);
48+
49+
// CHECK-DAG: [[V3AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 32
50+
// CHECK-DAG: [[V3AX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0
51+
// CHECK-DAG: [[V3AX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1
52+
// CHECK-DAG: [[V3AX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2
53+
54+
// I32-DAG: [[V3A0:%.*]] = icmp ne i32 [[V3AX0]], 0
55+
// I32-DAG: [[V3A1:%.*]] = icmp ne i32 [[V3AX1]], 0
56+
// I32-DAG: [[V3A2:%.*]] = icmp ne i32 [[V3AX2]], 0
57+
58+
// F32-DAG: [[V3A0:%.*]] = fcmp fast une float [[V3AX0]], 0.000000e+00
59+
// F32-DAG: [[V3A1:%.*]] = fcmp fast une float [[V3AX1]], 0.000000e+00
60+
// F32-DAG: [[V3A2:%.*]] = fcmp fast une float [[V3AX2]], 0.000000e+00
61+
62+
// CHECK-DAG: [[V3BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 56
63+
// CHECK-DAG: [[V3BX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0
64+
// CHECK-DAG: [[V3BX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1
65+
// CHECK-DAG: [[V3BX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2
66+
67+
// I32-DAG: [[V3B0:%.*]] = icmp ne i32 [[V3BX0]], 0
68+
// I32-DAG: [[V3B1:%.*]] = icmp ne i32 [[V3BX1]], 0
69+
// I32-DAG: [[V3B2:%.*]] = icmp ne i32 [[V3BX2]], 0
70+
71+
// F32-DAG: [[V3B0:%.*]] = fcmp fast une float [[V3BX0]], 0.000000e+00
72+
// F32-DAG: [[V3B1:%.*]] = fcmp fast une float [[V3BX1]], 0.000000e+00
73+
// F32-DAG: [[V3B2:%.*]] = fcmp fast une float [[V3BX2]], 0.000000e+00
74+
75+
vector<TYPE, 3> v3b = buf.Load< vector<TYPE, 3> >(56);
76+
vector<TYPE, 3> v3a = buf.Load< vector<TYPE, 3> >(32);
77+
78+
// CHECK: and i1 [[V3B0]], [[V3A0]]
79+
// CHECK: and i1 [[V3B1]], [[V3A1]]
80+
// CHECK: and i1 [[V3B2]], [[V3A2]]
81+
vector<TYPE, 3> res3 = and(v3a, v3b);
82+
83+
// CHECK-DAG: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 80
84+
// CHECK-DAG: [[MAX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
85+
// CHECK-DAG: [[MAX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
86+
// CHECK-DAG: [[MAX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2
87+
// CHECK-DAG: [[MAX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3
88+
// CHECK-DAG: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 96
89+
// CHECK-DAG: [[MAX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
90+
// CHECK-DAG: [[MAX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
91+
92+
// I32-DAG: [[MA0:%.*]] = icmp ne i32 [[MAX0]], 0
93+
// I32-DAG: [[MA1:%.*]] = icmp ne i32 [[MAX1]], 0
94+
// I32-DAG: [[MA2:%.*]] = icmp ne i32 [[MAX2]], 0
95+
// I32-DAG: [[MA3:%.*]] = icmp ne i32 [[MAX3]], 0
96+
// I32-DAG: [[MA4:%.*]] = icmp ne i32 [[MAX4]], 0
97+
// I32-DAG: [[MA5:%.*]] = icmp ne i32 [[MAX5]], 0
98+
99+
// F32-DAG: [[MA0:%.*]] = fcmp fast une float [[MAX0]], 0.000000e+00
100+
// F32-DAG: [[MA1:%.*]] = fcmp fast une float [[MAX1]], 0.000000e+00
101+
// F32-DAG: [[MA2:%.*]] = fcmp fast une float [[MAX2]], 0.000000e+00
102+
// F32-DAG: [[MA3:%.*]] = fcmp fast une float [[MAX3]], 0.000000e+00
103+
// F32-DAG: [[MA4:%.*]] = fcmp fast une float [[MAX4]], 0.000000e+00
104+
// F32-DAG: [[MA5:%.*]] = fcmp fast une float [[MAX5]], 0.000000e+00
105+
106+
// CHECK-DAG: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 128
107+
// CHECK-DAG: [[MBX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
108+
// CHECK-DAG: [[MBX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
109+
// CHECK-DAG: [[MBX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2
110+
// CHECK-DAG: [[MBX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3
111+
// CHECK-DAG: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 144
112+
// CHECK-DAG: [[MBX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
113+
// CHECK-DAG: [[MBX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
114+
115+
// I32-DAG: [[MB0:%.*]] = icmp ne i32 [[MBX0]], 0
116+
// I32-DAG: [[MB1:%.*]] = icmp ne i32 [[MBX1]], 0
117+
// I32-DAG: [[MB2:%.*]] = icmp ne i32 [[MBX2]], 0
118+
// I32-DAG: [[MB3:%.*]] = icmp ne i32 [[MBX3]], 0
119+
// I32-DAG: [[MB4:%.*]] = icmp ne i32 [[MBX4]], 0
120+
// I32-DAG: [[MB5:%.*]] = icmp ne i32 [[MBX5]], 0
121+
122+
// F32-DAG: [[MB0:%.*]] = fcmp fast une float [[MBX0]], 0.000000e+00
123+
// F32-DAG: [[MB1:%.*]] = fcmp fast une float [[MBX1]], 0.000000e+00
124+
// F32-DAG: [[MB2:%.*]] = fcmp fast une float [[MBX2]], 0.000000e+00
125+
// F32-DAG: [[MB3:%.*]] = fcmp fast une float [[MBX3]], 0.000000e+00
126+
// F32-DAG: [[MB4:%.*]] = fcmp fast une float [[MBX4]], 0.000000e+00
127+
// F32-DAG: [[MB5:%.*]] = fcmp fast une float [[MBX5]], 0.000000e+00
128+
129+
matrix<TYPE, 2, 3> matb = buf.Load< matrix<TYPE, 2, 3> >(128);
130+
matrix<TYPE, 2, 3> mata = buf.Load< matrix<TYPE, 2, 3> >(80);
131+
132+
// CHECK: and i1 [[MB0]], [[MA0]]
133+
// CHECK: and i1 [[MB1]], [[MA1]]
134+
// CHECK: and i1 [[MB2]], [[MA2]]
135+
// CHECK: and i1 [[MB3]], [[MA3]]
136+
// CHECK: and i1 [[MB4]], [[MA4]]
137+
// CHECK: and i1 [[MB5]], [[MA5]]
138+
matrix<TYPE, 2, 3> resmat = and(mata, matb);
139+
140+
return float4(res3 + resmat[0] + resmat[1], res + res1.x);
141+
}
+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32
2+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=bool %s | FileCheck %s --check-prefixes=CHECK,I32
3+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32
4+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=int %s | FileCheck %s --check-prefixes=CHECK,I32
5+
// RUN: %dxc -T ps_6_0 -HV 2021 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32
6+
// RUN: %dxc -T ps_6_0 -HV 2018 -DTYPE=float %s | FileCheck %s --check-prefixes=CHECK,F32
7+
8+
// I32: %dx.types.ResRet.[[TY:i32]] = type { [[TYPE:i32]]
9+
// F32: %dx.types.ResRet.[[TY:f32]] = type { [[TYPE:float]]
10+
11+
// CHECK-LABEL: define void @main
12+
13+
ByteAddressBuffer buf;
14+
15+
float4 main() : SV_Target {
16+
17+
// CHECK: [[SAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 0
18+
// F32: [[SAX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0
19+
// I32: [[SA:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SAR]], 0
20+
21+
// CHECK: [[SBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 8
22+
// F32: [[SBX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0
23+
// I32: [[SB:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[SBR]], 0
24+
25+
// F32: [[SA:%.*]] = fcmp fast une float [[SAX]], 0.000000e+00
26+
// F32: [[SB:%.*]] = fcmp fast une float [[SBX]], 0.000000e+00
27+
28+
TYPE sa = buf.Load<TYPE>(0);
29+
TYPE sb = buf.Load<TYPE>(8);
30+
31+
// I32: or i32 [[SB]], [[SA]]
32+
// F32: or i1 [[SA]], [[SB]]
33+
34+
TYPE res = or(sb, sa);
35+
36+
// CHECK: [[V1AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 16
37+
// F32: [[V1AX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0
38+
// I32: [[V1A:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1AR]], 0
39+
40+
// CHECK: [[V1BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 24
41+
// F32: [[V1BX:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0
42+
// I32: [[V1B:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V1BR]], 0
43+
44+
// F32: [[V1B:%.*]] = fcmp fast une float [[V1BX]], 0.000000e+00
45+
// F32: [[V1A:%.*]] = fcmp fast une float [[V1AX]], 0.000000e+00
46+
47+
vector<TYPE, 1> v1a = buf.Load< vector<TYPE, 1> >(16);
48+
vector<TYPE, 1> v1b = buf.Load< vector<TYPE, 1> >(24);
49+
50+
// I32: or i32 [[V1B]], [[V1A]]
51+
// F32: or i1 [[V1A]], [[V1B]]
52+
53+
vector<TYPE, 1> res1 = or(v1a, v1b);
54+
55+
// CHECK: [[V3AR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 32
56+
// F32: [[V3AX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0
57+
// F32: [[V3AX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1
58+
// F32: [[V3AX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2
59+
60+
// I32: [[V3A0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 0
61+
// I32: [[V3A1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 1
62+
// I32: [[V3A2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3AR]], 2
63+
64+
// CHECK: [[V3BR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 56
65+
// F32: [[V3BX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0
66+
// F32: [[V3BX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1
67+
// F32: [[V3BX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2
68+
69+
// I32: [[V3B0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 0
70+
// I32: [[V3B1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 1
71+
// I32: [[V3B2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[V3BR]], 2
72+
73+
// F32: [[V3B0:%.*]] = fcmp fast une float [[V3BX0]], 0.000000e+00
74+
// F32: [[V3B1:%.*]] = fcmp fast une float [[V3BX1]], 0.000000e+00
75+
// F32: [[V3B2:%.*]] = fcmp fast une float [[V3BX2]], 0.000000e+00
76+
77+
// F32: [[V3A0:%.*]] = fcmp fast une float [[V3AX0]], 0.000000e+00
78+
// F32: [[V3A1:%.*]] = fcmp fast une float [[V3AX1]], 0.000000e+00
79+
// F32: [[V3A2:%.*]] = fcmp fast une float [[V3AX2]], 0.000000e+00
80+
81+
vector<TYPE, 3> v3a = buf.Load< vector<TYPE, 3> >(32);
82+
vector<TYPE, 3> v3b = buf.Load< vector<TYPE, 3> >(56);
83+
84+
// I32: or i32 [[V3B0]], [[V3A0]]
85+
// I32: or i32 [[V3B1]], [[V3A1]]
86+
// I32: or i32 [[V3B2]], [[V3A2]]
87+
88+
// F32: or i1 [[V3A0]], [[V3B0]]
89+
// F32: or i1 [[V3A1]], [[V3B1]]
90+
// F32: or i1 [[V3A2]], [[V3B2]]
91+
92+
vector<TYPE, 3> res3 = or(v3a, v3b);
93+
94+
// CHECK: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 80
95+
// F32: [[MAX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
96+
// F32: [[MAX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
97+
// F32: [[MAX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2
98+
// F32: [[MAX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3
99+
100+
// I32: [[MA0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
101+
// I32: [[MA1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
102+
// I32: [[MA2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 2
103+
// I32: [[MA3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 3
104+
105+
// CHECK: [[MAR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 96
106+
// F32: [[MAX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
107+
// F32: [[MAX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
108+
109+
// I32: [[MA4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 0
110+
// I32: [[MA5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MAR]], 1
111+
112+
// CHECK: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 128
113+
// F32: [[MBX0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
114+
// F32: [[MBX1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
115+
// F32: [[MBX2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2
116+
// F32: [[MBX3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3
117+
118+
// I32: [[MB0:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
119+
// I32: [[MB1:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
120+
// I32: [[MB2:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 2
121+
// I32: [[MB3:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 3
122+
123+
// CHECK: [[MBR:%.*]] = call %dx.types.ResRet.[[TY]] @dx.op.bufferLoad.[[TY]](i32 68, %dx.types.Handle %{{.*}}, i32 144
124+
// F32: [[MBX4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
125+
// F32: [[MBX5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
126+
127+
// I32: [[MB4:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 0
128+
// I32: [[MB5:%.*]] = extractvalue %dx.types.ResRet.[[TY]] [[MBR]], 1
129+
130+
// F32: [[MB0:%.*]] = fcmp fast une float [[MBX0]], 0.000000e+00
131+
// F32: [[MB1:%.*]] = fcmp fast une float [[MBX1]], 0.000000e+00
132+
// F32: [[MB2:%.*]] = fcmp fast une float [[MBX2]], 0.000000e+00
133+
// F32: [[MB3:%.*]] = fcmp fast une float [[MBX3]], 0.000000e+00
134+
// F32: [[MB4:%.*]] = fcmp fast une float [[MBX4]], 0.000000e+00
135+
// F32: [[MB5:%.*]] = fcmp fast une float [[MBX5]], 0.000000e+00
136+
137+
// F32: [[MA0:%.*]] = fcmp fast une float [[MAX0]], 0.000000e+00
138+
// F32: [[MA1:%.*]] = fcmp fast une float [[MAX1]], 0.000000e+00
139+
// F32: [[MA2:%.*]] = fcmp fast une float [[MAX2]], 0.000000e+00
140+
// F32: [[MA3:%.*]] = fcmp fast une float [[MAX3]], 0.000000e+00
141+
// F32: [[MA4:%.*]] = fcmp fast une float [[MAX4]], 0.000000e+00
142+
// F32: [[MA5:%.*]] = fcmp fast une float [[MAX5]], 0.000000e+00
143+
144+
matrix<TYPE, 2, 3> mata = buf.Load< matrix<TYPE, 2, 3> >(80);
145+
matrix<TYPE, 2, 3> matb = buf.Load< matrix<TYPE, 2, 3> >(128);
146+
147+
// I32: or i32 [[MB0]], [[MA0]]
148+
// I32: or i32 [[MB1]], [[MA1]]
149+
// I32: or i32 [[MB2]], [[MA2]]
150+
// I32: or i32 [[MB3]], [[MA3]]
151+
// I32: or i32 [[MB4]], [[MA4]]
152+
// I32: or i32 [[MB5]], [[MA5]]
153+
154+
// F32: or i1 [[MA0]], [[MB0]]
155+
// F32: or i1 [[MA1]], [[MB1]]
156+
// F32: or i1 [[MA2]], [[MB2]]
157+
// F32: or i1 [[MA3]], [[MB3]]
158+
// F32: or i1 [[MA4]], [[MB4]]
159+
// F32: or i1 [[MA5]], [[MB5]]
160+
161+
matrix<TYPE, 2, 3> resmat = or(mata, matb);
162+
163+
return float4(res3 + resmat[0] + resmat[1], res + res1.x);
164+
}

tools/clang/test/CodeGenSPIRV/intrinsics.and.hlsl

+45
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %dxc -T ps_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s
22
// RUN: %dxc -T ps_6_0 -E main -HV 2018 -fcgl %s -spirv | FileCheck %s
33

4+
// CHECK-DAG: [[v3_0:%[0-9]+]] = OpConstantComposite %v3int %int_0 %int_0 %int_0
5+
// CHECK-DAG: [[v3_1:%[0-9]+]] = OpConstantComposite %v3int %int_1 %int_1 %int_1
6+
47
void main() {
58
// CHECK-LABEL: %bb_entry = OpLabel
69

@@ -33,4 +36,46 @@ void main() {
3336
// CHECK-NEXT: [[and3:%[0-9]+]] = OpLogicalAnd %bool [[a1]] [[b1]]
3437
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %v2bool [[and3]] %true
3538
bool2 t = bool2(and(a, b), true);
39+
40+
int a_0, b_0, c_0;
41+
// Plain assign (scalar)
42+
// CHECK: [[a0_int:%[0-9]+]] = OpLoad %int %a_0
43+
// CHECK-NEXT: [[a0:%[0-9]+]] = OpINotEqual %bool [[a0_int]] %int_0
44+
// CHECK-NEXT: [[b0_int:%[0-9]+]] = OpLoad %int %b_0
45+
// CHECK-NEXT: [[b0:%[0-9]+]] = OpINotEqual %bool [[b0_int]] %int_0
46+
// CHECK-NEXT: [[and0:%[0-9]+]] = OpLogicalAnd %bool [[a0]] [[b0]]
47+
// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %int [[and0]] %int_1 %int_0
48+
// CHECK-NEXT: OpStore %c_0 [[sel]]
49+
c_0 = and(a_0, b_0);
50+
51+
int1 i_0, j_0, k_0;
52+
int3 o_0, p_0, q_0;
53+
// Plain assign (vector)
54+
// CHECK-NEXT: [[i0_int:%[0-9]+]] = OpLoad %int %i_0
55+
// CHECK-NEXT: [[i0:%[0-9]+]] = OpINotEqual %bool [[i0_int]] %int_0
56+
// CHECK-NEXT: [[j0_int:%[0-9]+]] = OpLoad %int %j_0
57+
// CHECK-NEXT: [[j0:%[0-9]+]] = OpINotEqual %bool [[j0_int]] %int_0
58+
// CHECK-NEXT: [[and1:%[0-9]+]] = OpLogicalAnd %bool [[i0]] [[j0]]
59+
// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %int [[and1]] %int_1 %int_0
60+
// CHECK-NEXT: OpStore %k_0 [[sel]]
61+
k_0 = and(i_0, j_0);
62+
63+
// CHECK-NEXT: [[o0_int:%[0-9]+]] = OpLoad %v3int %o_0
64+
// CHECK-NEXT: [[o0:%[0-9]+]] = OpINotEqual %v3bool [[o0_int]] [[v3_0]]
65+
// CHECK-NEXT: [[p0_int:%[0-9]+]] = OpLoad %v3int %p_0
66+
// CHECK-NEXT: [[p0:%[0-9]+]] = OpINotEqual %v3bool [[p0_int]] [[v3_0]]
67+
// CHECK-NEXT: [[and2:%[0-9]+]] = OpLogicalAnd %v3bool [[o0]] [[p0]]
68+
// CHECK-NEXT: [[sel:%[0-9]+]] = OpSelect %v3int [[and2]] [[v3_1]] [[v3_0]]
69+
// CHECK-NEXT: OpStore %q_0 [[sel]]
70+
q_0 = and(o_0, p_0);
71+
72+
// The result of '&&' could be 'const bool'. In such cases, make sure
73+
// the result type is correct.
74+
// CHECK: [[a0_int:%[0-9]+]] = OpLoad %int %a_0
75+
// CHECK-NEXT: [[a0:%[0-9]+]] = OpINotEqual %bool [[a0_int]] %int_0
76+
// CHECK-NEXT: [[b0_int:%[0-9]+]] = OpLoad %int %b_0
77+
// CHECK-NEXT: [[b0:%[0-9]+]] = OpINotEqual %bool [[b0_int]] %int_0
78+
// CHECK-NEXT: [[and0:%[0-9]+]] = OpLogicalAnd %bool [[a0]] [[b0]]
79+
// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %v2bool [[and0]] %true
80+
t = bool2(and(a_0, b_0), true);
3681
}

0 commit comments

Comments
 (0)