https://github.com/llvm-beanz created https://github.com/llvm/llvm-project/pull/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. >From 9deebd707410a6ad8474f615a97c943937ceeb34 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Mon, 16 Sep 2024 18:21:38 -0500 Subject: [PATCH] [HLSL] Make casting functions constexpr 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. --- clang/lib/Headers/hlsl/hlsl_detail.h | 10 +++++----- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 8 ++++---- clang/test/CodeGenHLSL/builtins/asuint.hlsl | 12 ++++++------ clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl | 10 ++++++++++ clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl | 10 ++++++++++ 5 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 clang/test/SemaHLSL/BuiltIns/asfloat-constexpr.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/asuint-constexpr.hlsl diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h index 9801d86208159f..40849dcdf187e4 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 6a50d50ebd3479..12f58ef0718695 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); } @@ -415,11 +415,11 @@ float4 asin(float4); /// \param Val The input value. template <typename T, int N> -_HLSL_INLINE vector<uint, N> asuint(vector<T, N> V) { +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..b2a54d23173e57 --- /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 asuint 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