Author: Chris B Date: 2024-09-20T16:42:53-05:00 New Revision: 4b4ea6d84bddb5e7b3f144d18630390755e8f7b6
URL: https://github.com/llvm/llvm-project/commit/4b4ea6d84bddb5e7b3f144d18630390755e8f7b6 DIFF: https://github.com/llvm/llvm-project/commit/4b4ea6d84bddb5e7b3f144d18630390755e8f7b6.diff LOG: [HLSL] Make casting functions constexpr (#108902) This marks the `bit_cast` helper as `constexpr` and allows the casts implemented with it to also be `constexpr`. This is largely not a functional change, but it enables using the casts in expressions that need to be resolved at compile time as demonstrated with the static asserts in the new tests. --------- Co-authored-by: joaosaffran <126493771+joaosaff...@users.noreply.github.com> Added: clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl Modified: clang/lib/Headers/hlsl/hlsl_detail.h clang/lib/Headers/hlsl/hlsl_intrinsics.h clang/test/CodeGenHLSL/builtins/asuint.hlsl Removed: ################################################################################ diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h index 9801d86208159f..8d5fd941331531 100644 --- a/clang/lib/Headers/hlsl/hlsl_detail.h +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -13,23 +13,23 @@ namespace hlsl { namespace __detail { -#define _HLSL_INLINE \ - __attribute__((__always_inline__, __nodebug__)) static inline - template <bool B, typename T> struct enable_if {}; template <typename T> struct enable_if<true, T> { using Type = T; }; +template <bool B, class T = void> +using enable_if_t = typename enable_if<B, T>::Type; + template <typename U, typename T, int N> -_HLSL_INLINE typename enable_if<sizeof(U) == sizeof(T), vector<U, N> >::Type +constexpr enable_if_t<sizeof(U) == sizeof(T), vector<U, N>> bit_cast(vector<T, N> V) { return __builtin_bit_cast(vector<U, N>, V); } template <typename U, typename T> -_HLSL_INLINE typename enable_if<sizeof(U) == sizeof(T), U>::Type bit_cast(T F) { +constexpr enable_if_t<sizeof(U) == sizeof(T), U> bit_cast(T F) { return __builtin_bit_cast(U, F); } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 6cd6a2caf19994..b139f9eb7d999b 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -370,11 +370,11 @@ bool any(double4); /// \param Val The input value. template <typename T, int N> -_HLSL_INLINE vector<float, N> asfloat(vector<T, N> V) { +constexpr vector<float, N> asfloat(vector<T, N> V) { return __detail::bit_cast<float, T, N>(V); } -template <typename T> _HLSL_INLINE float asfloat(T F) { +template <typename T> constexpr float asfloat(T F) { return __detail::bit_cast<float, T>(F); } @@ -414,12 +414,11 @@ float4 asin(float4); /// \brief Interprets the bit pattern of x as an unsigned integer. /// \param Val The input value. -template <typename T, int N> -_HLSL_INLINE vector<uint, N> asuint(vector<T, N> V) { +template <typename T, int N> constexpr vector<uint, N> asuint(vector<T, N> V) { return __detail::bit_cast<uint, T, N>(V); } -template <typename T> _HLSL_INLINE uint asuint(T F) { +template <typename T> constexpr uint asuint(T F) { return __detail::bit_cast<uint, T>(F); } diff --git a/clang/test/CodeGenHLSL/builtins/asuint.hlsl b/clang/test/CodeGenHLSL/builtins/asuint.hlsl index ac3dae26d6caed..252a434ccce0dc 100644 --- a/clang/test/CodeGenHLSL/builtins/asuint.hlsl +++ b/clang/test/CodeGenHLSL/builtins/asuint.hlsl @@ -1,40 +1,40 @@ // RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s -// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} // CHECK-NOT: bitcast // CHECK: ret i32 [[VAL]] uint test_uint(uint p0) { return asuint(p0); } -// CHECK: define {{.*}}test_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} // CHECK-NOT: bitcast // CHECK: ret i32 [[VAL]] uint test_int(int p0) { return asuint(p0); } -// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}} // CHECK: bitcast float [[VAL]] to i32 uint test_float(float p0) { return asuint(p0); } -// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} // CHECK-NOT: bitcast // CHECK: ret <4 x i32> [[VAL]] uint4 test_vector_uint(uint4 p0) { return asuint(p0); } -// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} // CHECK-NOT: bitcast // CHECK: ret <4 x i32> [[VAL]] uint4 test_vector_int(int4 p0) { return asuint(p0); } -// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} // CHECK: bitcast <4 x float> [[VAL]] to <4 x i32> uint4 test_vector_float(float4 p0) { return asuint(p0); diff --git a/clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl b/clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl new file mode 100644 index 00000000000000..fb90d927a9a437 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify + +// expected-no-diagnostics + +// Because asfloat should be constant evaluated, all the static asserts below +// should work! +void ConstExprTest() { + static_assert(asfloat(0x3f800000) == 1.0f, "One"); + static_assert(asfloat(0x40000000.xxx).y == 2.0f, "Two"); +} diff --git a/clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl b/clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl new file mode 100644 index 00000000000000..be6afda3be6636 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify + +// expected-no-diagnostics + +// Because asuint should be constant evaluated, all the static asserts below +// should work! +void ConstExprTest() { + static_assert(asuint(1) == 1u, "One"); + static_assert(asuint(2.xxx).y == 2u, "Two"); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits