Skip to content

Hlsl asint16 intrinsic #131900

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 20 commits into from
Mar 21, 2025
Merged

Hlsl asint16 intrinsic #131900

merged 20 commits into from
Mar 21, 2025

Conversation

metkarpoonam
Copy link
Contributor

@metkarpoonam metkarpoonam commented Mar 18, 2025

Implemented the asint16 function and added test cases for codegen, Sema, and SPIR-V backend.
fixes #99184

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics HLSL HLSL Language Support backend:SPIR-V labels Mar 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 18, 2025

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-spir-v

Author: None (metkarpoonam)

Changes

Implemented the asint16 function and added test cases for codegen, Sema, and SPIR-V backend.


Full diff: https://github.com/llvm/llvm-project/pull/131900.diff

4 Files Affected:

  • (modified) clang/lib/Headers/hlsl/hlsl_intrinsics.h (+18)
  • (added) clang/test/CodeGenHLSL/builtins/asint16.hlsl (+48)
  • (added) clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl (+29)
  • (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asint16.ll (+55)
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index a48a8e998a015..e0366693deae0 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -80,6 +80,24 @@ void asuint(double3, out uint3, out uint3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_splitdouble)
 void asuint(double4, out uint4, out uint4);
 
+//===----------------------------------------------------------------------===//
+// asint16 builtins
+//===----------------------------------------------------------------------===//
+
+/// \fn int16_t asint16(T Val)
+/// \brief Interprets the bit pattern of x as an 16-bit integer.
+/// \param Val The input value.
+#ifdef __HLSL_ENABLE_16_BIT
+
+template <typename T, int N> constexpr vector<int16_t, N> asint16(vector<T, N> V) {
+  return __detail::bit_cast<int16_t, T, N>(V);
+}
+
+template <typename T> constexpr int16_t asint16(T F) {
+  return __detail::bit_cast<int16_t, T>(F);
+}
+#endif
+
 //===----------------------------------------------------------------------===//
 // distance builtins
 //===----------------------------------------------------------------------===//
diff --git a/clang/test/CodeGenHLSL/builtins/asint16.hlsl b/clang/test/CodeGenHLSL/builtins/asint16.hlsl
new file mode 100644
index 0000000000000..0cd6ee63fa078
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/asint16.hlsl
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.2-library %s -fnative-half-type -emit-llvm -O1 -o - | FileCheck %s
+// CHECK: define {{.*}}test_ints{{.*}}(i16 {{.*}} [[VAL:%.*]]){{.*}}
+// CHECK-NOT: bitcast
+// CHECK: ret i16 [[VAL]]
+int16_t test_int(int16_t p0)
+{
+    return asint16(p0);
+}
+
+//CHECK: define {{.*}}test_uint{{.*}}(i16 {{.*}} [[VAL:%.*]]){{.*}}
+//CHECK-NOT: bitcast
+//CHECK: ret i16 [[VAL]]
+int16_t test_uint(uint16_t p0)
+{
+    return asint16(p0);
+}
+
+//CHECK: define {{.*}}test_half{{.*}}(half {{.*}} [[VAL:%.*]]){{.*}}
+//CHECK: [[RES:%.*]] = bitcast half [[VAL]] to i16
+//CHECK : ret i16 [[RES]]
+int16_t test_half(half p0)
+{
+    return asint16(p0);
+}
+
+//CHECK: define {{.*}}test_vector_int{{.*}}(<4 x i16> {{.*}} [[VAL:%.*]]){{.*}}
+//CHECK-NOT: bitcast
+//CHECK: ret <4 x i16> [[VAL]]
+int16_t4 test_vector_int(int16_t4 p0)
+{
+    return asint16(p0);
+}
+
+//CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i16> {{.*}} [[VAL:%.*]]){{.*}}
+//CHECK-NOT: bitcast
+//CHECK: ret <4 x i16> [[VAL]]
+int16_t4 test_vector_uint(uint16_t4 p0)
+{
+    return asint16(p0);
+}
+
+//CHECK: define {{.*}}fn{{.*}}(<4 x half> {{.*}} [[VAL:%.*]]){{.*}}
+//CHECK: [[RES:%.*]] = bitcast <4 x half> [[VAL]] to <4 x i16>
+//CHECK: ret <4 x i16> [[RES]]
+int16_t4 fn(half4 p1)
+{
+    return asint16(p1);
+}
\ No newline at end of file
diff --git a/clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl
new file mode 100644
index 0000000000000..03a3e46bd1d46
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.2-library %s -fnative-half-type -verify
+
+
+int16_t4 test_asint_too_many_arg(uint16_t p0, uint16_t p1)
+{
+    return asint16(p0, p1);
+  // expected-error@-1 {{no matching function for call to 'asint16'}}
+  // 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}}
+}
+
+
+int16_t test_asint_int(int p1)
+{
+    return asint16(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::asint16<int>'}}
+    // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<int, N>' against 'int'}}
+    // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = int16_t, T = int]: no type named 'Type'}}
+}
+
+int16_t test_asint_float(float p1)
+{
+    return asint16(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::asint16<float>'}}
+    // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector<float, N>' against 'float'}}
+    // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = int16_t, T = float]: no type named 'Type'}}
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asint16.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asint16.ll
new file mode 100644
index 0000000000000..4c3c4337bc62a
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asint16.ll
@@ -0,0 +1,55 @@
+; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpCapability Int16
+; CHECK: OpCapability Float16
+; CHECK-DAG: %[[#int_16:]] = OpTypeInt 16 0
+; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
+; CHECK-DAG: %[[#vec4_int_16:]] = OpTypeVector %[[#int_16]] 4
+; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
+
+
+define i16 @test_int16(i16 returned %p0) {
+entry:
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#int_16]]
+  ; CHECK: OpReturnValue %[[#arg0]]
+  ret i16 %p0
+}
+
+define i16 @test_half(half nofpclass(nan inf) %p0) {
+entry:
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#float_16:]]
+  ; CHECK: %[[#]] = OpBitcast %[[#int_16]] %[[#arg0]]
+  %0 = bitcast half %p0 to i16
+  ;CHECK: OpReturnValue %[[#]]
+  ret i16 %0
+
+}
+
+; Function Attrs: alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <4 x i16> @test_vector_int4(<4 x i16> returned %p0) {
+entry:
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_int_16]]
+  ; CHECK: OpReturnValue %[[#arg0]]
+  ret <4 x i16> %p0
+}
+
+; Function Attrs: alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <4 x i16> @test_vector_half4(<4 x half> nofpclass(nan inf) %p1) {
+entry:
+  ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#vec4_float_16]]
+  ; CHECK: %[[#]] = OpBitcast %[[#vec4_int_16]] %[[#arg0]]
+  %0 = bitcast <4 x half> %p1 to <4 x i16>
+  ;CHECK: OpReturnValue %[[#]]
+  ret <4 x i16> %0
+}
+
+attributes #0 = { alwaysinline mustprogress nofree norecurse nosync nounwind willreturn memory(none) "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+
+!llvm.module.flags = !{!0}
+!dx.valver = !{!1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, i32 8}
+!2 = !{!"clang version 21.0.0git (https://github.com/llvm/llvm-project.git 5929de8c7731748bf58ad9b1fedfed75e7aae455)"}
\ No newline at end of file

Copy link

github-actions bot commented Mar 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@V-FEXrt
Copy link
Contributor

V-FEXrt commented Mar 19, 2025

I'm assuming this PR resolves an issue right? We typically add Fixes #1234 (without the `) as part of the description so it will close the issue when the PR is merged

Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test changes needed aswell as some type constraints to template type T.

@metkarpoonam metkarpoonam requested a review from farzonl March 20, 2025 01:18
Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM don't forget to add the newline to the end of clang/test/SemaHLSL/BuiltIns/asint16-errors.hlsl

Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be something odd with this PR. Looks like a ton of people just got added to it... Will need to investigate in the morning.

@farzonl
Copy link
Member

farzonl commented Mar 21, 2025

There seems to be something odd with this PR. Looks like a ton of people just got added to it... Will need to investigate in the morning.

I removed all the extra reviewers. Don't see any artifacts of what could have caused it. Will confer with the team if this is safe to merge in the morning.

@metkarpoonam metkarpoonam requested a review from farzonl March 21, 2025 16:18
Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@farzonl farzonl merged commit 718838d into llvm:main Mar 21, 2025
10 of 11 checks passed
@metkarpoonam metkarpoonam deleted the hlsl_asint16_intrinsic branch March 21, 2025 23:58
@damyanp damyanp moved this to Closed in HLSL Support Apr 25, 2025
@damyanp damyanp removed this from HLSL Support Jun 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:SPIR-V backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics clang Clang issues not falling into any other category HLSL HLSL Language Support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement the asint16 HLSL Function
5 participants