From 1bfc3d0de591b6b4e18ee720bd24f58e45d597ef Mon Sep 17 00:00:00 2001 From: joaosaffran <126493771+joaosaffran@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:42:52 -0700 Subject: [PATCH] Implementing `asfloat` using `bit_cast` (#108686) This PR is implementing `asfloat` for HLSL. Fixes: #70098 Co-authored-by: Joao Saffran --- clang/lib/Headers/hlsl/hlsl_intrinsics.h | 17 ++++++++ clang/test/CodeGenHLSL/builtins/asfloat.hlsl | 40 +++++++++++++++++++ .../SemaHLSL/BuiltIns/asfloat-errors.hlsl | 35 ++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/asfloat.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/asfloat-errors.hlsl diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index b5c22f7c91b2d6..6a50d50ebd3479 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -361,6 +361,23 @@ bool any(double3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_any) bool any(double4); +//===----------------------------------------------------------------------===// +// asfloat builtins +//===----------------------------------------------------------------------===// + +/// \fn float asfloat(T Val) +/// \brief Interprets the bit pattern of x as float point number. +/// \param Val The input value. + +template +_HLSL_INLINE vector asfloat(vector V) { + return __detail::bit_cast(V); +} + +template _HLSL_INLINE float asfloat(T F) { + return __detail::bit_cast(F); +} + //===----------------------------------------------------------------------===// // asin builtins //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl new file mode 100644 index 00000000000000..59fc15fa60b1e5 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl @@ -0,0 +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: bitcast i32 [[VAL]] to float +float test_uint(uint p0) { + return asfloat(p0); +} + +// CHECK: define {{.*}}test_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast i32 [[VAL]] to float +float test_int(int p0) { + return asfloat(p0); +} + +// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret float [[VAL]] +float test_float(float p0) { + return asfloat(p0); +} + +// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float> + +float4 test_vector_uint(uint4 p0) { + return asfloat(p0); +} + +// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float> +float4 test_vector_int(int4 p0) { + return asfloat(p0); +} + +// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret <4 x float> [[VAL]] +float4 test_vector_float(float4 p0) { + return asfloat(p0); +} diff --git a/clang/test/SemaHLSL/BuiltIns/asfloat-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asfloat-errors.hlsl new file mode 100644 index 00000000000000..c2dd9e272e0937 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asfloat-errors.hlsl @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify + + +float4 test_float_too_many_arg(float p0, float p1) { + return asfloat(p0, p1); + // expected-error@-1 {{no matching function for call to 'asfloat'}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'V', but 2 arguments were provided}} + // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'F', but 2 arguments were provided}} +} + + +float test_float_double(double p1) { + return asfloat(p1); + // expected-error@hlsl/hlsl_intrinsics.h:* {{no matching function for call to 'bit_cast'}} + // expected-note@-2 {{in instantiation of function template specialization 'hlsl::asfloat'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector' against 'double'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = float, T = double]: no type named 'Type'}} +} + +float test_float_half(half p1) { + return asfloat(p1); + // expected-error@hlsl/hlsl_intrinsics.h:* {{no matching function for call to 'bit_cast'}} + // expected-note@-2 {{in instantiation of function template specialization 'hlsl::asfloat'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector' against 'half'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = float, T = half]: no type named 'Type'}} +} + + +float test_float_half(bool p1) { + return asfloat(p1); + // expected-error@hlsl/hlsl_intrinsics.h:* {{no matching function for call to 'bit_cast'}} + // expected-note@-2 {{in instantiation of function template specialization 'hlsl::asfloat'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector' against 'bool'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = float, T = bool]: no type named 'Type'}} +}