Author: joaosaffran Date: 2024-09-13T21:11:25-04:00 New Revision: cab1ae9fa2d63b8f0f4bc5e0aa85c53704cb0079
URL: https://github.com/llvm/llvm-project/commit/cab1ae9fa2d63b8f0f4bc5e0aa85c53704cb0079 DIFF: https://github.com/llvm/llvm-project/commit/cab1ae9fa2d63b8f0f4bc5e0aa85c53704cb0079.diff LOG: Adding `asuint` implementation to hlsl (#107292) Implements support for the `asuint` HLSL function casting behaviour. Addressing the `splitdouble` scenario will be addressed in a future PR. Fixes: #70097 --------- Co-authored-by: Joao Saffran <jdereze...@microsoft.com> Co-authored-by: Justin Bogner <m...@justinbogner.com> Added: clang/lib/Headers/hlsl/hlsl_detail.h clang/test/CodeGenHLSL/builtins/asuint.hlsl clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl Modified: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/hlsl/hlsl_intrinsics.h Removed: ################################################################################ diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index a21e3901f63fea..4c75c638b41bae 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -87,6 +87,7 @@ set(hlsl_h set(hlsl_subdir_files hlsl/hlsl_basic_types.h hlsl/hlsl_intrinsics.h + hlsl/hlsl_detail.h ) set(hlsl_files ${hlsl_h} diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h new file mode 100644 index 00000000000000..9801d86208159f --- /dev/null +++ b/clang/lib/Headers/hlsl/hlsl_detail.h @@ -0,0 +1,38 @@ +//===----- detail.h - HLSL definitions for intrinsics ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _HLSL_HLSL_DETAILS_H_ +#define _HLSL_HLSL_DETAILS_H_ + +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 <typename U, typename T, int N> +_HLSL_INLINE typename enable_if<sizeof(U) == sizeof(T), vector<U, N> >::Type +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) { + return __builtin_bit_cast(U, F); +} + +} // namespace __detail +} // namespace hlsl +#endif //_HLSL_HLSL_DETAILS_H_ diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index d08dcd350d558b..b5c22f7c91b2d6 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -9,6 +9,8 @@ #ifndef _HLSL_HLSL_INTRINSICS_H_ #define _HLSL_HLSL_INTRINSICS_H_ +#include "hlsl_detail.h" + namespace hlsl { // Note: Functions in this file are sorted alphabetically, then grouped by base @@ -387,6 +389,23 @@ float3 asin(float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin) float4 asin(float4); +//===----------------------------------------------------------------------===// +// asuint builtins +//===----------------------------------------------------------------------===// + +/// \fn uint asuint(T Val) +/// \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) { + return __detail::bit_cast<uint, T, N>(V); +} + +template <typename T> _HLSL_INLINE uint asuint(T F) { + return __detail::bit_cast<uint, T>(F); +} + //===----------------------------------------------------------------------===// // atan builtins //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGenHLSL/builtins/asuint.hlsl b/clang/test/CodeGenHLSL/builtins/asuint.hlsl new file mode 100644 index 00000000000000..ac3dae26d6caed --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/asuint.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_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-NOT: bitcast +// CHECK: ret i32 [[VAL]] +uint test_int(int p0) { + return asuint(p0); +} + +// 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-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-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: 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/asuint-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl new file mode 100644 index 00000000000000..8c56fdddb1c24c --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify + + +uint4 test_asuint_too_many_arg(float p0, float p1) { + return asuint(p0, p1); + // expected-error@-1 {{no matching function for call to 'asuint'}} + // 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}} +} + +uint test_asuint_double(double p1) { + return asuint(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::asuint<double>'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<double, N>' against 'double'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = uint, T = double]: no type named 'Type'}} +} + +uint test_asuint_half(half p1) { + return asuint(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::asuint<half>'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<half, N>' against 'half'}} + // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = uint, T = half]: no type named 'Type'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits