diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index b139f9eb7d999..9d426de4cca2a 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -378,6 +378,22 @@ template constexpr float asfloat(T F) { return __detail::bit_cast(F); } +//===----------------------------------------------------------------------===// +// asint builtins +//===----------------------------------------------------------------------===// + +/// \fn int asint(T Val) +/// \brief Interprets the bit pattern of x as an integer. +/// \param Val The input value. + +template constexpr vector asint(vector V) { + return __detail::bit_cast(V); +} + +template constexpr int asint(T F) { + return __detail::bit_cast(F); +} + //===----------------------------------------------------------------------===// // asin builtins //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenHLSL/builtins/asint.hlsl b/clang/test/CodeGenHLSL/builtins/asint.hlsl new file mode 100644 index 0000000000000..e1d80df5015c9 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/asint.hlsl @@ -0,0 +1,41 @@ +// 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_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret i32 [[VAL]] +int test_int(int p0) { + return asint(p0); +} + +// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret i32 [[VAL]] +int test_uint(uint p0) { + return asint(p0); +} + +// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast float [[VAL]] to i32 +int test_float(float p0) { + return asint(p0); +} + +// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret <4 x i32> [[VAL]] +int4 test_vector_int(int4 p0) { + return asint(p0); +} + +// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK-NOT: bitcast +// CHECK: ret <4 x i32> [[VAL]] +int4 test_vector_uint(uint4 p0) { + return asint(p0); +} + +// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} +// CHECK: bitcast <4 x float> [[VAL]] to <4 x i32> +int4 test_vector_float(float4 p0) { + return asint(p0); +} diff --git a/clang/test/SemaHLSL/BuiltIns/asint-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asint-errors.hlsl new file mode 100644 index 0000000000000..815a0c35cb04c --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asint-errors.hlsl @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify + + +int4 test_asint_too_many_arg(float p0, float p1) { + return asint(p0, p1); + // expected-error@-1 {{no matching function for call to 'asint'}} + // 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}} +} + +int test_asint_double(double p1) { + return asint(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::asint'}} + // 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 = int, T = double]: no type named 'Type'}} +} + +int test_asint_half(half p1) { + return asint(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::asint'}} + // 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 = int, T = half]: no type named 'Type'}} +}