Skip to content

Adding asuint implementation to hlsl #107292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
38 changes: 38 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_detail.h
Original file line number Diff line number Diff line change
@@ -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_
19 changes: 19 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
41 changes: 41 additions & 0 deletions clang/test/CodeGenHLSL/builtins/asuint.hlsl
Original file line number Diff line number Diff line change
@@ -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);
}
25 changes: 25 additions & 0 deletions clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl
Original file line number Diff line number Diff line change
@@ -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'}}
}
Loading