Skip to content

Commit a8fc996

Browse files
committed
Invert firstbithigh
1 parent 92a1eb3 commit a8fc996

File tree

4 files changed

+124
-102
lines changed

4 files changed

+124
-102
lines changed

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,78 +1073,6 @@ float3 f16tof32(uint3);
10731073
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_f16tof32)
10741074
float4 f16tof32(uint4);
10751075

1076-
//===----------------------------------------------------------------------===//
1077-
// firstbithigh builtins
1078-
//===----------------------------------------------------------------------===//
1079-
1080-
/// \fn T firstbithigh(T Val)
1081-
/// \brief Returns the location of the first set bit starting from the highest
1082-
/// order bit and working downward, per component.
1083-
/// \param Val the input value.
1084-
1085-
#ifdef __HLSL_ENABLE_16_BIT
1086-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1087-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1088-
uint firstbithigh(int16_t);
1089-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1090-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1091-
uint2 firstbithigh(int16_t2);
1092-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1093-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1094-
uint3 firstbithigh(int16_t3);
1095-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1096-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1097-
uint4 firstbithigh(int16_t4);
1098-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1099-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1100-
uint firstbithigh(uint16_t);
1101-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1102-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1103-
uint2 firstbithigh(uint16_t2);
1104-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1105-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1106-
uint3 firstbithigh(uint16_t3);
1107-
_HLSL_AVAILABILITY(shadermodel, 6.2)
1108-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1109-
uint4 firstbithigh(uint16_t4);
1110-
#endif
1111-
1112-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1113-
uint firstbithigh(int);
1114-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1115-
uint2 firstbithigh(int2);
1116-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1117-
uint3 firstbithigh(int3);
1118-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1119-
uint4 firstbithigh(int4);
1120-
1121-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1122-
uint firstbithigh(uint);
1123-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1124-
uint2 firstbithigh(uint2);
1125-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1126-
uint3 firstbithigh(uint3);
1127-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1128-
uint4 firstbithigh(uint4);
1129-
1130-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1131-
uint firstbithigh(int64_t);
1132-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1133-
uint2 firstbithigh(int64_t2);
1134-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1135-
uint3 firstbithigh(int64_t3);
1136-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1137-
uint4 firstbithigh(int64_t4);
1138-
1139-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1140-
uint firstbithigh(uint64_t);
1141-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1142-
uint2 firstbithigh(uint64_t2);
1143-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1144-
uint3 firstbithigh(uint64_t3);
1145-
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_firstbithigh)
1146-
uint4 firstbithigh(uint64_t4);
1147-
11481076
//===----------------------------------------------------------------------===//
11491077
// firstbitlow builtins
11501078
//===----------------------------------------------------------------------===//

clang/lib/Headers/hlsl/hlsl_intrinsic_helpers.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ 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);
153+
}
154+
155+
template <typename T, int N, int Bitwidth>
156+
constexpr vector<uint, N> firstbithigh_impl(vector<T, N> X) {
157+
return (Bitwidth - 1) - __builtin_hlsl_elementwise_firstbithigh(X);
158+
}
159+
151160
} // namespace __detail
152161
} // namespace hlsl
153162

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,67 @@ faceforward(__detail::HLSL_FIXED_VECTOR<float, L> N,
261261
return __detail::faceforward_impl(N, I, Ng);
262262
}
263263

264+
//===----------------------------------------------------------------------===//
265+
// firstbithigh builtins
266+
//===----------------------------------------------------------------------===//
267+
268+
/// \fn T firstbithigh(T Val)
269+
/// \brief Returns the location of the first set bit starting from the lowest
270+
/// order bit and working upward, per component.
271+
/// \param Val the input value.
272+
273+
#ifdef __HLSL_ENABLE_16_BIT
274+
275+
template <typename T>
276+
_HLSL_AVAILABILITY(shadermodel, 6.2)
277+
const inline __detail::enable_if_t<__detail::is_same<int16_t, T>::value ||
278+
__detail::is_same<uint16_t, T>::value,
279+
uint> firstbithigh(T X) {
280+
return __detail::firstbithigh_impl<T, 16>(X);
281+
}
282+
283+
template <typename T, int N>
284+
_HLSL_AVAILABILITY(shadermodel, 6.2)
285+
const
286+
inline __detail::enable_if_t<__detail::is_same<int16_t, T>::value ||
287+
__detail::is_same<uint16_t, T>::value,
288+
vector<uint, N>> firstbithigh(vector<T, N> X) {
289+
return __detail::firstbithigh_impl<T, N, 16>(X);
290+
}
291+
292+
#endif
293+
294+
template <typename T>
295+
const inline __detail::enable_if_t<
296+
__detail::is_same<int, T>::value || __detail::is_same<uint, T>::value, uint>
297+
firstbithigh(T X) {
298+
return __detail::firstbithigh_impl<T, 32>(X);
299+
}
300+
301+
template <typename T, int N>
302+
const inline __detail::enable_if_t<__detail::is_same<int, T>::value ||
303+
__detail::is_same<uint, T>::value,
304+
vector<uint, N>>
305+
firstbithigh(vector<T, N> X) {
306+
return __detail::firstbithigh_impl<T, N, 32>(X);
307+
}
308+
309+
template <typename T>
310+
const inline __detail::enable_if_t<__detail::is_same<int64_t, T>::value ||
311+
__detail::is_same<uint64_t, T>::value,
312+
uint>
313+
firstbithigh(T X) {
314+
return __detail::firstbithigh_impl<T, 64>(X);
315+
}
316+
317+
template <typename T, int N>
318+
const inline __detail::enable_if_t<__detail::is_same<int64_t, T>::value ||
319+
__detail::is_same<uint64_t, T>::value,
320+
vector<uint, N>>
321+
firstbithigh(vector<T, N> X) {
322+
return __detail::firstbithigh_impl<T, N, 64>(X);
323+
}
324+
264325
//===----------------------------------------------------------------------===//
265326
// fmod builtins
266327
//===----------------------------------------------------------------------===//

clang/test/CodeGenHLSL/builtins/firstbithigh.hlsl

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,184 @@
11
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
2-
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \
3-
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -DTARGET=dx
2+
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
3+
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=dx
44
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
5-
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
6-
// RUN: -emit-llvm -disable-llvm-passes \
7-
// RUN: -o - | FileCheck %s -DTARGET=spv
5+
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
6+
// RUN: -fnative-int16-type -emit-llvm -o - | FileCheck %s -DTARGET=spv
87

98
#ifdef __HLSL_ENABLE_16_BIT
109
// CHECK-LABEL: test_firstbithigh_ushort
11-
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i16
10+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i16
11+
// CHECK: sub i32 15, [[FBH]]
1212
uint test_firstbithigh_ushort(uint16_t p0) {
1313
return firstbithigh(p0);
1414
}
1515

1616
// CHECK-LABEL: test_firstbithigh_ushort2
17-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
17+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i16
18+
// CHECK: sub <2 x i32> splat (i32 15), [[FBH]]
1819
uint2 test_firstbithigh_ushort2(uint16_t2 p0) {
1920
return firstbithigh(p0);
2021
}
2122

2223
// CHECK-LABEL: test_firstbithigh_ushort3
23-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
24+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i16
25+
// CHECK: sub <3 x i32> splat (i32 15), [[FBH]]
2426
uint3 test_firstbithigh_ushort3(uint16_t3 p0) {
2527
return firstbithigh(p0);
2628
}
2729

2830
// CHECK-LABEL: test_firstbithigh_ushort4
29-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
31+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i16
32+
// CHECK: sub <4 x i32> splat (i32 15), [[FBH]]
3033
uint4 test_firstbithigh_ushort4(uint16_t4 p0) {
3134
return firstbithigh(p0);
3235
}
3336

3437
// CHECK-LABEL: test_firstbithigh_short
35-
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i16
38+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i16
39+
// CHECK: sub i32 15, [[FBH]]
3640
uint test_firstbithigh_short(int16_t p0) {
3741
return firstbithigh(p0);
3842
}
3943

4044
// CHECK-LABEL: test_firstbithigh_short2
41-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
45+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i16
46+
// CHECK: sub <2 x i32> splat (i32 15), [[FBH]]
4247
uint2 test_firstbithigh_short2(int16_t2 p0) {
4348
return firstbithigh(p0);
4449
}
4550

4651
// CHECK-LABEL: test_firstbithigh_short3
47-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
52+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i16
53+
// CHECK: sub <3 x i32> splat (i32 15), [[FBH]]
4854
uint3 test_firstbithigh_short3(int16_t3 p0) {
4955
return firstbithigh(p0);
5056
}
5157

5258
// CHECK-LABEL: test_firstbithigh_short4
53-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
59+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i16
60+
// CHECK: sub <4 x i32> splat (i32 15), [[FBH]]
5461
uint4 test_firstbithigh_short4(int16_t4 p0) {
5562
return firstbithigh(p0);
5663
}
5764
#endif // __HLSL_ENABLE_16_BIT
5865

5966
// CHECK-LABEL: test_firstbithigh_uint
60-
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i32
67+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i32
68+
// CHECK: sub i32 31, [[FBH]]
6169
uint test_firstbithigh_uint(uint p0) {
6270
return firstbithigh(p0);
6371
}
6472

6573
// CHECK-LABEL: test_firstbithigh_uint2
66-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
74+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i32
75+
// CHECK: sub <2 x i32> splat (i32 31), [[FBH]]
6776
uint2 test_firstbithigh_uint2(uint2 p0) {
6877
return firstbithigh(p0);
6978
}
7079

7180
// CHECK-LABEL: test_firstbithigh_uint3
72-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
81+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i32
82+
// CHECK: sub <3 x i32> splat (i32 31), [[FBH]]
7383
uint3 test_firstbithigh_uint3(uint3 p0) {
7484
return firstbithigh(p0);
7585
}
7686

7787
// CHECK-LABEL: test_firstbithigh_uint4
78-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
88+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32
89+
// CHECK: sub <4 x i32> splat (i32 31), [[FBH]]
7990
uint4 test_firstbithigh_uint4(uint4 p0) {
8091
return firstbithigh(p0);
8192
}
8293

8394
// CHECK-LABEL: test_firstbithigh_ulong
84-
// CHECK: call i32 @llvm.[[TARGET]].firstbituhigh.i64
95+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbituhigh.i64
96+
// CHECK: sub i32 63, [[FBH]]
8597
uint test_firstbithigh_ulong(uint64_t p0) {
8698
return firstbithigh(p0);
8799
}
88100

89101
// CHECK-LABEL: test_firstbithigh_ulong2
90-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
102+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbituhigh.v2i64
103+
// CHECK: sub <2 x i32> splat (i32 63), [[FBH]]
91104
uint2 test_firstbithigh_ulong2(uint64_t2 p0) {
92105
return firstbithigh(p0);
93106
}
94107

95108
// CHECK-LABEL: test_firstbithigh_ulong3
96-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
109+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbituhigh.v3i64
110+
// CHECK: sub <3 x i32> splat (i32 63), [[FBH]]
97111
uint3 test_firstbithigh_ulong3(uint64_t3 p0) {
98112
return firstbithigh(p0);
99113
}
100114

101115
// CHECK-LABEL: test_firstbithigh_ulong4
102-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
116+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i64
117+
// CHECK: sub <4 x i32> splat (i32 63), [[FBH]]
103118
uint4 test_firstbithigh_ulong4(uint64_t4 p0) {
104119
return firstbithigh(p0);
105120
}
106121

107122
// CHECK-LABEL: test_firstbithigh_int
108-
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i32
123+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i32
124+
// CHECK: sub i32 31, [[FBH]]
109125
uint test_firstbithigh_int(int p0) {
110126
return firstbithigh(p0);
111127
}
112128

113129
// CHECK-LABEL: test_firstbithigh_int2
114-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
130+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i32
131+
// CHECK: sub <2 x i32> splat (i32 31), [[FBH]]
115132
uint2 test_firstbithigh_int2(int2 p0) {
116133
return firstbithigh(p0);
117134
}
118135

119136
// CHECK-LABEL: test_firstbithigh_int3
120-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
137+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i32
138+
// CHECK: sub <3 x i32> splat (i32 31), [[FBH]]
121139
uint3 test_firstbithigh_int3(int3 p0) {
122140
return firstbithigh(p0);
123141
}
124142

125143
// CHECK-LABEL: test_firstbithigh_int4
126-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
144+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i32
145+
// CHECK: sub <4 x i32> splat (i32 31), [[FBH]]
127146
uint4 test_firstbithigh_int4(int4 p0) {
128147
return firstbithigh(p0);
129148
}
130149

131150
// CHECK-LABEL: test_firstbithigh_long
132-
// CHECK: call i32 @llvm.[[TARGET]].firstbitshigh.i64
151+
// CHECK: [[FBH:%.*]] = call i32 @llvm.[[TARGET]].firstbitshigh.i64
152+
// CHECK: sub i32 63, [[FBH]]
133153
uint test_firstbithigh_long(int64_t p0) {
134154
return firstbithigh(p0);
135155
}
136156

137157
// CHECK-LABEL: test_firstbithigh_long2
138-
// CHECK: call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
158+
// CHECK: [[FBH:%.*]] = call <2 x i32> @llvm.[[TARGET]].firstbitshigh.v2i64
159+
// CHECK: sub <2 x i32> splat (i32 63), [[FBH]]
139160
uint2 test_firstbithigh_long2(int64_t2 p0) {
140161
return firstbithigh(p0);
141162
}
142163

143164
// CHECK-LABEL: test_firstbithigh_long3
144-
// CHECK: call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
165+
// CHECK: [[FBH:%.*]] = call <3 x i32> @llvm.[[TARGET]].firstbitshigh.v3i64
166+
// CHECK: sub <3 x i32> splat (i32 63), [[FBH]]
145167
uint3 test_firstbithigh_long3(int64_t3 p0) {
146168
return firstbithigh(p0);
147169
}
148170

149171
// CHECK-LABEL: test_firstbithigh_long4
150-
// CHECK: call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
172+
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbitshigh.v4i64
173+
// CHECK: sub <4 x i32> splat (i32 63), [[FBH]]
151174
uint4 test_firstbithigh_long4(int64_t4 p0) {
152175
return firstbithigh(p0);
153176
}
154177

155178
// CHECK-LABEL: test_firstbithigh_upcast
156179
// CHECK: [[FBH:%.*]] = call <4 x i32> @llvm.[[TARGET]].firstbituhigh.v4i32(<4 x i32> %{{.*}})
157-
// CHECK: [[CONV:%.*]] = zext <4 x i32> [[FBH]] to <4 x i64>
180+
// CHECK: [[SUB:%.*]] = sub <4 x i32> splat (i32 31), [[FBH]]
181+
// CHECK: [[CONV:%.*]] = zext <4 x i32> [[SUB]] to <4 x i64>
158182
// CHECK: ret <4 x i64> [[CONV]]
159183
uint64_t4 test_firstbithigh_upcast(uint4 p0) {
160184
return firstbithigh(p0);

0 commit comments

Comments
 (0)