Skip to content

Commit 48ed7af

Browse files
committed
[HLSL] Implement asint casting using bit_cast
Using clang's `__builtin_bit_cast`, implement the hlsl intrinsic `asint`. Follows implementation details of `asuint/asfloat`. Fixes #99091
1 parent d288574 commit 48ed7af

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

clang/lib/Headers/hlsl/hlsl_intrinsics.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,22 @@ template <typename T> constexpr float asfloat(T F) {
378378
return __detail::bit_cast<float, T>(F);
379379
}
380380

381+
//===----------------------------------------------------------------------===//
382+
// asint builtins
383+
//===----------------------------------------------------------------------===//
384+
385+
/// \fn int asint(T Val)
386+
/// \brief Interprets the bit pattern of x as an integer.
387+
/// \param Val The input value.
388+
389+
template <typename T, int N> constexpr vector<int, N> asint(vector<T, N> V) {
390+
return __detail::bit_cast<int, T, N>(V);
391+
}
392+
393+
template <typename T> constexpr int asint(T F) {
394+
return __detail::bit_cast<int, T>(F);
395+
}
396+
381397
//===----------------------------------------------------------------------===//
382398
// asin builtins
383399
//===----------------------------------------------------------------------===//
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_int{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}}
4+
// CHECK-NOT: bitcast
5+
// CHECK: ret i32 [[VAL]]
6+
int test_int(int p0) {
7+
return asint(p0);
8+
}
9+
10+
// CHECK: define {{.*}}test_uint{{.*}}(i32 {{.*}} [[VAL:%.*]]){{.*}}
11+
// CHECK-NOT: bitcast
12+
// CHECK: ret i32 [[VAL]]
13+
int test_uint(uint p0) {
14+
return asint(p0);
15+
}
16+
17+
// CHECK: define {{.*}}test_float{{.*}}(float {{.*}} [[VAL:%.*]]){{.*}}
18+
// CHECK: bitcast float [[VAL]] to i32
19+
int test_float(float p0) {
20+
return asint(p0);
21+
}
22+
23+
// CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}}
24+
// CHECK-NOT: bitcast
25+
// CHECK: ret <4 x i32> [[VAL]]
26+
int4 test_vector_int(int4 p0) {
27+
return asint(p0);
28+
}
29+
30+
// CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}}
31+
// CHECK-NOT: bitcast
32+
// CHECK: ret <4 x i32> [[VAL]]
33+
int4 test_vector_uint(uint4 p0) {
34+
return asint(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+
int4 test_vector_float(float4 p0) {
40+
return asint(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+
int4 test_asint_too_many_arg(float p0, float p1) {
5+
return asint(p0, p1);
6+
// expected-error@-1 {{no matching function for call to 'asint'}}
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+
int test_asint_double(double p1) {
12+
return asint(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::asint<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 = int, T = double]: no type named 'Type'}}
17+
}
18+
19+
int test_asint_half(half p1) {
20+
return asint(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::asint<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 = int, T = half]: no type named 'Type'}}
25+
}

0 commit comments

Comments
 (0)