Skip to content

Commit cab1ae9

Browse files
joaosaffranjoaosaffran-zzbogner
authored
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 <[email protected]> Co-authored-by: Justin Bogner <[email protected]>
1 parent d200965 commit cab1ae9

File tree

5 files changed

+124
-0
lines changed

5 files changed

+124
-0
lines changed

clang/lib/Headers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ set(hlsl_h
8787
set(hlsl_subdir_files
8888
hlsl/hlsl_basic_types.h
8989
hlsl/hlsl_intrinsics.h
90+
hlsl/hlsl_detail.h
9091
)
9192
set(hlsl_files
9293
${hlsl_h}

clang/lib/Headers/hlsl/hlsl_detail.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----- detail.h - HLSL definitions for intrinsics ----------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _HLSL_HLSL_DETAILS_H_
10+
#define _HLSL_HLSL_DETAILS_H_
11+
12+
namespace hlsl {
13+
14+
namespace __detail {
15+
16+
#define _HLSL_INLINE \
17+
__attribute__((__always_inline__, __nodebug__)) static inline
18+
19+
template <bool B, typename T> struct enable_if {};
20+
21+
template <typename T> struct enable_if<true, T> {
22+
using Type = T;
23+
};
24+
25+
template <typename U, typename T, int N>
26+
_HLSL_INLINE typename enable_if<sizeof(U) == sizeof(T), vector<U, N> >::Type
27+
bit_cast(vector<T, N> V) {
28+
return __builtin_bit_cast(vector<U, N>, V);
29+
}
30+
31+
template <typename U, typename T>
32+
_HLSL_INLINE typename enable_if<sizeof(U) == sizeof(T), U>::Type bit_cast(T F) {
33+
return __builtin_bit_cast(U, F);
34+
}
35+
36+
} // namespace __detail
37+
} // namespace hlsl
38+
#endif //_HLSL_HLSL_DETAILS_H_

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef _HLSL_HLSL_INTRINSICS_H_
1010
#define _HLSL_HLSL_INTRINSICS_H_
1111

12+
#include "hlsl_detail.h"
13+
1214
namespace hlsl {
1315

1416
// Note: Functions in this file are sorted alphabetically, then grouped by base
@@ -387,6 +389,23 @@ float3 asin(float3);
387389
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_asin)
388390
float4 asin(float4);
389391

392+
//===----------------------------------------------------------------------===//
393+
// asuint builtins
394+
//===----------------------------------------------------------------------===//
395+
396+
/// \fn uint asuint(T Val)
397+
/// \brief Interprets the bit pattern of x as an unsigned integer.
398+
/// \param Val The input value.
399+
400+
template <typename T, int N>
401+
_HLSL_INLINE vector<uint, N> asuint(vector<T, N> V) {
402+
return __detail::bit_cast<uint, T, N>(V);
403+
}
404+
405+
template <typename T> _HLSL_INLINE uint asuint(T F) {
406+
return __detail::bit_cast<uint, T>(F);
407+
}
408+
390409
//===----------------------------------------------------------------------===//
391410
// atan builtins
392411
//===----------------------------------------------------------------------===//
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s
2+
3+
// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}}
4+
// CHECK-NOT: bitcast
5+
// CHECK: ret i32 [[VAL]]
6+
uint test_uint(uint p0) {
7+
return asuint(p0);
8+
}
9+
10+
// CHECK: define {{.*}}test_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}}
11+
// CHECK-NOT: bitcast
12+
// CHECK: ret i32 [[VAL]]
13+
uint test_int(int p0) {
14+
return asuint(p0);
15+
}
16+
17+
// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}}
18+
// CHECK: bitcast float [[VAL]] to i32
19+
uint test_float(float p0) {
20+
return asuint(p0);
21+
}
22+
23+
// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}}
24+
// CHECK-NOT: bitcast
25+
// CHECK: ret <4 x i32> [[VAL]]
26+
uint4 test_vector_uint(uint4 p0) {
27+
return asuint(p0);
28+
}
29+
30+
// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}}
31+
// CHECK-NOT: bitcast
32+
// CHECK: ret <4 x i32> [[VAL]]
33+
uint4 test_vector_int(int4 p0) {
34+
return asuint(p0);
35+
}
36+
37+
// CHECK: define {{.*}}test_vector_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}}
38+
// CHECK: bitcast <4 x float> [[VAL]] to <4 x i32>
39+
uint4 test_vector_float(float4 p0) {
40+
return asuint(p0);
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify
2+
3+
4+
uint4 test_asuint_too_many_arg(float p0, float p1) {
5+
return asuint(p0, p1);
6+
// expected-error@-1 {{no matching function for call to 'asuint'}}
7+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'V', but 2 arguments were provided}}
8+
// expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires single argument 'F', but 2 arguments were provided}}
9+
}
10+
11+
uint test_asuint_double(double p1) {
12+
return asuint(p1);
13+
// expected-error@hlsl/hlsl_intrinsics.h:* {{no matching function for call to 'bit_cast'}}
14+
// expected-note@-2 {{in instantiation of function template specialization 'hlsl::asuint<double>'}}
15+
// expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<double, N>' against 'double'}}
16+
// expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = uint, T = double]: no type named 'Type'}}
17+
}
18+
19+
uint test_asuint_half(half p1) {
20+
return asuint(p1);
21+
// expected-error@hlsl/hlsl_intrinsics.h:* {{no matching function for call to 'bit_cast'}}
22+
// expected-note@-2 {{in instantiation of function template specialization 'hlsl::asuint<half>'}}
23+
// expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<half, N>' against 'half'}}
24+
// expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = uint, T = half]: no type named 'Type'}}
25+
}

0 commit comments

Comments
 (0)