Skip to content

Commit be82734

Browse files
committed
Do not invert firstbithigh under SPIR-V or if the result is -1
1 parent ee25321 commit be82734

File tree

2 files changed

+193
-58
lines changed

2 files changed

+193
-58
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,27 @@ template <typename T> constexpr T ldexp_impl(T X, T Exp) {
148148
return exp2(Exp) * X;
149149
}
150150

151-
template <typename T, int Bitwidth> constexpr uint firstbithigh_impl(T X) {
152-
return (Bitwidth - 1) - __builtin_hlsl_elementwise_firstbithigh(X);
151+
template <typename T, int BitWidth> constexpr uint firstbithigh_impl(T X) {
152+
uint FBH = __builtin_hlsl_elementwise_firstbithigh(X);
153+
#if defined(__DIRECTX__)
154+
// The firstbithigh DXIL ops count bits from the wrong side, so we need to
155+
// invert it for DirectX.
156+
uint Inversion = (BitWidth - 1) - FBH;
157+
FBH = select(FBH == -1, FBH, Inversion);
158+
#endif
159+
return FBH;
153160
}
154161

155-
template <typename T, int N, int Bitwidth>
162+
template <typename T, int N, int BitWidth>
156163
constexpr vector<uint, N> firstbithigh_impl(vector<T, N> X) {
157-
return (Bitwidth - 1) - __builtin_hlsl_elementwise_firstbithigh(X);
164+
vector<uint, N> FBH = __builtin_hlsl_elementwise_firstbithigh(X);
165+
#if defined(__DIRECTX__)
166+
// The firstbithigh DXIL ops count bits from the wrong side, so we need to
167+
// invert it for DirectX.
168+
vector<uint, N> Inversion = (BitWidth - 1) - FBH;
169+
FBH = select(FBH == -1, FBH, Inversion);
170+
#endif
171+
return FBH;
158172
}
159173

160174
} // namespace __detail
Lines changed: 175 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,306 @@
11
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
22
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3-
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=dx
3+
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=dx --check-prefixes=CHECK,DXCHECK
44
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
55
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
6-
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=spv
6+
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=spv --check-prefixes=CHECK,SPVCHECK
77

88
#ifdef __HLSL_ENABLE_16_BIT
99
// CHECK-LABEL: test_firstbithigh_ushort
10-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i16
11-
// CHECK: sub i32 15, [[FBH]]
10+
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i16
11+
// DXCHECK: sub i32 15, {{.*}}
12+
// SPVCHECK-NOT: sub i32 15, {{.*}}
13+
// DXCHECK: icmp eq i32 {{.*}}, -1
14+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
15+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
16+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
1217
uint test_firstbithigh_ushort(uint16_t p0) {
1318
return firstbithigh(p0);
1419
}
1520

1621
// CHECK-LABEL: test_firstbithigh_ushort2
17-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
18-
// CHECK: sub <2 x i32> splat (i32 15), [[FBH]]
22+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
23+
// DXCHECK: sub <2 x i32> splat (i32 15), {{.*}}
24+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 15), {{.*}}
25+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
26+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
27+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
28+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
1929
uint2 test_firstbithigh_ushort2(uint16_t2 p0) {
2030
return firstbithigh(p0);
2131
}
2232

2333
// CHECK-LABEL: test_firstbithigh_ushort3
24-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
25-
// CHECK: sub <3 x i32> splat (i32 15), [[FBH]]
34+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
35+
// DXCHECK: sub <3 x i32> splat (i32 15), {{.*}}
36+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 15), {{.*}}
37+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
38+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
39+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
40+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
2641
uint3 test_firstbithigh_ushort3(uint16_t3 p0) {
2742
return firstbithigh(p0);
2843
}
2944

3045
// CHECK-LABEL: test_firstbithigh_ushort4
31-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
32-
// CHECK: sub <4 x i32> splat (i32 15), [[FBH]]
46+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
47+
// DXCHECK: sub <4 x i32> splat (i32 15), {{.*}}
48+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 15), {{.*}}
49+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
50+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
51+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
52+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
3353
uint4 test_firstbithigh_ushort4(uint16_t4 p0) {
3454
return firstbithigh(p0);
3555
}
3656

3757
// CHECK-LABEL: test_firstbithigh_short
38-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i16
39-
// CHECK: sub i32 15, [[FBH]]
58+
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i16
59+
// DXCHECK: sub i32 15, {{.*}}
60+
// SPVCHECK-NOT: sub i32 15, {{.*}}
61+
// DXCHECK: icmp eq i32 {{.*}}, -1
62+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
63+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
64+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
4065
uint test_firstbithigh_short(int16_t p0) {
4166
return firstbithigh(p0);
4267
}
4368

4469
// CHECK-LABEL: test_firstbithigh_short2
45-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
46-
// CHECK: sub <2 x i32> splat (i32 15), [[FBH]]
70+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
71+
// DXCHECK: sub <2 x i32> splat (i32 15), {{.*}}
72+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 15), {{.*}}
73+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
74+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
75+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
76+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
4777
uint2 test_firstbithigh_short2(int16_t2 p0) {
4878
return firstbithigh(p0);
4979
}
5080

5181
// CHECK-LABEL: test_firstbithigh_short3
52-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
53-
// CHECK: sub <3 x i32> splat (i32 15), [[FBH]]
82+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
83+
// DXCHECK: sub <3 x i32> splat (i32 15), {{.*}}
84+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 15), {{.*}}
85+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
86+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
87+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
88+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
5489
uint3 test_firstbithigh_short3(int16_t3 p0) {
5590
return firstbithigh(p0);
5691
}
5792

5893
// CHECK-LABEL: test_firstbithigh_short4
59-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
60-
// CHECK: sub <4 x i32> splat (i32 15), [[FBH]]
94+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
95+
// DXCHECK: sub <4 x i32> splat (i32 15), {{.*}}
96+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 15), {{.*}}
97+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
98+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
99+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
100+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
61101
uint4 test_firstbithigh_short4(int16_t4 p0) {
62102
return firstbithigh(p0);
63103
}
64104
#endif // __HLSL_ENABLE_16_BIT
65105

66106
// CHECK-LABEL: test_firstbithigh_uint
67-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i32
68-
// CHECK: sub i32 31, [[FBH]]
107+
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i32
108+
// DXCHECK: sub i32 31, {{.*}}
109+
// SPVCHECK-NOT: sub i32 31, {{.*}}
110+
// DXCHECK: icmp eq i32 {{.*}}, -1
111+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
112+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
113+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
69114
uint test_firstbithigh_uint(uint p0) {
70115
return firstbithigh(p0);
71116
}
72117

73118
// CHECK-LABEL: test_firstbithigh_uint2
74-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
75-
// CHECK: sub <2 x i32> splat (i32 31), [[FBH]]
119+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
120+
// DXCHECK: sub <2 x i32> splat (i32 31), {{.*}}
121+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 31), {{.*}}
122+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
123+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
124+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
125+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
76126
uint2 test_firstbithigh_uint2(uint2 p0) {
77127
return firstbithigh(p0);
78128
}
79129

80130
// CHECK-LABEL: test_firstbithigh_uint3
81-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
82-
// CHECK: sub <3 x i32> splat (i32 31), [[FBH]]
131+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
132+
// DXCHECK: sub <3 x i32> splat (i32 31), {{.*}}
133+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 31), {{.*}}
134+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
135+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
136+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
137+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
83138
uint3 test_firstbithigh_uint3(uint3 p0) {
84139
return firstbithigh(p0);
85140
}
86141

87142
// CHECK-LABEL: test_firstbithigh_uint4
88-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
89-
// CHECK: sub <4 x i32> splat (i32 31), [[FBH]]
143+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
144+
// DXCHECK: sub <4 x i32> splat (i32 31), {{.*}}
145+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 31), {{.*}}
146+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
147+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
148+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
149+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
90150
uint4 test_firstbithigh_uint4(uint4 p0) {
91151
return firstbithigh(p0);
92152
}
93153

94154
// CHECK-LABEL: test_firstbithigh_ulong
95-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i64
96-
// CHECK: sub i32 63, [[FBH]]
155+
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i64
156+
// DXCHECK: sub i32 63, {{.*}}
157+
// SPVCHECK-NOT: sub i32 63, {{.*}}
158+
// DXCHECK: icmp eq i32 {{.*}}, -1
159+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
160+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
161+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
97162
uint test_firstbithigh_ulong(uint64_t p0) {
98163
return firstbithigh(p0);
99164
}
100165

101166
// CHECK-LABEL: test_firstbithigh_ulong2
102-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
103-
// CHECK: sub <2 x i32> splat (i32 63), [[FBH]]
167+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
168+
// DXCHECK: sub <2 x i32> splat (i32 63), {{.*}}
169+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 63), {{.*}}
170+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
171+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
172+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
173+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
104174
uint2 test_firstbithigh_ulong2(uint64_t2 p0) {
105175
return firstbithigh(p0);
106176
}
107177

108178
// CHECK-LABEL: test_firstbithigh_ulong3
109-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
110-
// CHECK: sub <3 x i32> splat (i32 63), [[FBH]]
179+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
180+
// DXCHECK: sub <3 x i32> splat (i32 63), {{.*}}
181+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 63), {{.*}}
182+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
183+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
184+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
185+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
111186
uint3 test_firstbithigh_ulong3(uint64_t3 p0) {
112187
return firstbithigh(p0);
113188
}
114189

115190
// CHECK-LABEL: test_firstbithigh_ulong4
116-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
117-
// CHECK: sub <4 x i32> splat (i32 63), [[FBH]]
191+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
192+
// DXCHECK: sub <4 x i32> splat (i32 63), {{.*}}
193+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 63), {{.*}}
194+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
195+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
196+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
197+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
118198
uint4 test_firstbithigh_ulong4(uint64_t4 p0) {
119199
return firstbithigh(p0);
120200
}
121201

122202
// CHECK-LABEL: test_firstbithigh_int
123-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i32
124-
// CHECK: sub i32 31, [[FBH]]
203+
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i32
204+
// DXCHECK: sub i32 31, {{.*}}
205+
// SPVCHECK-NOT: sub i32 31, {{.*}}
206+
// DXCHECK: icmp eq i32 {{.*}}, -1
207+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
208+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
209+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
125210
uint test_firstbithigh_int(int p0) {
126211
return firstbithigh(p0);
127212
}
128213

129214
// CHECK-LABEL: test_firstbithigh_int2
130-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
131-
// CHECK: sub <2 x i32> splat (i32 31), [[FBH]]
215+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
216+
// DXCHECK: sub <2 x i32> splat (i32 31), {{.*}}
217+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 31), {{.*}}
218+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
219+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
220+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
221+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
132222
uint2 test_firstbithigh_int2(int2 p0) {
133223
return firstbithigh(p0);
134224
}
135225

136226
// CHECK-LABEL: test_firstbithigh_int3
137-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
138-
// CHECK: sub <3 x i32> splat (i32 31), [[FBH]]
227+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
228+
// DXCHECK: sub <3 x i32> splat (i32 31), {{.*}}
229+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 31), {{.*}}
230+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
231+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
232+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
233+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
139234
uint3 test_firstbithigh_int3(int3 p0) {
140235
return firstbithigh(p0);
141236
}
142237

143238
// CHECK-LABEL: test_firstbithigh_int4
144-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
145-
// CHECK: sub <4 x i32> splat (i32 31), [[FBH]]
239+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
240+
// DXCHECK: sub <4 x i32> splat (i32 31), {{.*}}
241+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 31), {{.*}}
242+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
243+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
244+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
245+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
146246
uint4 test_firstbithigh_int4(int4 p0) {
147247
return firstbithigh(p0);
148248
}
149249

150250
// CHECK-LABEL: test_firstbithigh_long
151-
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i64
152-
// CHECK: sub i32 63, [[FBH]]
251+
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i64
252+
// DXCHECK: sub i32 63, {{.*}}
253+
// SPVCHECK-NOT: sub i32 63, {{.*}}
254+
// DXCHECK: icmp eq i32 {{.*}}, -1
255+
// SPVCHECK-NOT: icmp eq i32 {{.*}}, -1
256+
// DXCHECK: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
257+
// SPVCHECK-NOT: select i1 {{.*}}, i32 {{.*}}, i32 {{.*}}
153258
uint test_firstbithigh_long(int64_t p0) {
154259
return firstbithigh(p0);
155260
}
156261

157262
// CHECK-LABEL: test_firstbithigh_long2
158-
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
159-
// CHECK: sub <2 x i32> splat (i32 63), [[FBH]]
263+
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
264+
// DXCHECK: sub <2 x i32> splat (i32 63), {{.*}}
265+
// SPVCHECK-NOT: sub <2 x i32> splat (i32 63), {{.*}}
266+
// DXCHECK: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
267+
// SPVCHECK-NOT: icmp eq <2 x i32> {{.*}}, splat (i32 -1)
268+
// DXCHECK: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
269+
// SPVCHECK-NOT: select i1 {{.*}}, <2 x i32> {{.*}}, <2 x i32> {{.*}}
160270
uint2 test_firstbithigh_long2(int64_t2 p0) {
161271
return firstbithigh(p0);
162272
}
163273

164274
// CHECK-LABEL: test_firstbithigh_long3
165-
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
166-
// CHECK: sub <3 x i32> splat (i32 63), [[FBH]]
275+
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
276+
// DXCHECK: sub <3 x i32> splat (i32 63), {{.*}}
277+
// SPVCHECK-NOT: sub <3 x i32> splat (i32 63), {{.*}}
278+
// DXCHECK: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
279+
// SPVCHECK-NOT: icmp eq <3 x i32> {{.*}}, splat (i32 -1)
280+
// DXCHECK: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
281+
// SPVCHECK-NOT: select i1 {{.*}}, <3 x i32> {{.*}}, <3 x i32> {{.*}}
167282
uint3 test_firstbithigh_long3(int64_t3 p0) {
168283
return firstbithigh(p0);
169284
}
170285

171286
// CHECK-LABEL: test_firstbithigh_long4
172-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
173-
// CHECK: sub <4 x i32> splat (i32 63), [[FBH]]
287+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
288+
// DXCHECK: sub <4 x i32> splat (i32 63), {{.*}}
289+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 63), {{.*}}
290+
// DXCHECK: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
291+
// SPVCHECK-NOT: icmp eq <4 x i32> {{.*}}, splat (i32 -1)
292+
// DXCHECK: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
293+
// SPVCHECK-NOT: select i1 {{.*}}, <4 x i32> {{.*}}, <4 x i32> {{.*}}
174294
uint4 test_firstbithigh_long4(int64_t4 p0) {
175295
return firstbithigh(p0);
176296
}
177297

178298
// CHECK-LABEL: test_firstbithigh_upcast
179-
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}})
180-
// CHECK: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]]
181-
// CHECK: [[CONV:%.*]] = zext <4 x i32> [[SUB]] to <4 x i64>
182-
// CHECK: ret <4 x i64> [[CONV]]
299+
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}})
300+
// DXCHECK: sub <4 x i32> splat (i32 31), {{.*}}
301+
// SPVCHECK-NOT: sub <4 x i32> splat (i32 31), {{.*}}
302+
// CHECK: zext <4 x i32> {{.*}} to <4 x i64>
303+
// CHECK: ret <4 x i64> {{.*}}
183304
uint64_t4 test_firstbithigh_upcast(uint4 p0) {
184305
return firstbithigh(p0);
185306
}

0 commit comments

Comments
 (0)