Skip to content

Commit 4c605e9

Browse files
authored
[HLSL] [DirectX] Invert the result of firstbithigh (llvm#166419)
Fixes llvm#145752 This PR inverts the result of `firstbithigh` when targeting DirectX by subtracting it from integer bitwidth - 1 to match the result from DXC. The result is not inverted if `firstbithigh` returned -1 or when targeting a backend other than DirectX.
1 parent c145f28 commit 4c605e9

File tree

5 files changed

+205
-105
lines changed

5 files changed

+205
-105
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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ template <typename T> constexpr T ldexp_impl(T X, T Exp) {
148148
return exp2(Exp) * X;
149149
}
150150

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

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<uint, 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<vector<uint, N>, vector<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<uint, 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<vector<uint, N>, vector<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<uint, 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<vector<uint, N>, vector<T, N>, 64>(X);
323+
}
324+
264325
//===----------------------------------------------------------------------===//
265326
// fmod builtins
266327
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)