[clang] [llvm] [HLSL] Add HLSL unpack intrinsics (PR #228518)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 2 09:49:51 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-hlsl
Author: Alexander Johnston (Alexander-Johnston)
<details>
<summary>Changes</summary>
These HLSL intrinsics unpack a packed type (int8_t4_packed or uint8_t4_packed) into an appropriate 4 element vector, as specified by the specific unpack intrinsic used.
---
Patch is 33.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/228518.diff
25 Files Affected:
- (modified) clang/include/clang/Basic/Builtins.td (+24)
- (modified) clang/include/clang/Basic/HLSLIntrinsics.td (+24)
- (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+56)
- (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+4)
- (modified) clang/lib/Sema/SemaHLSL.cpp (+43)
- (added) clang/test/CodeGenHLSL/builtins/unpack_s8s16.hlsl (+21)
- (added) clang/test/CodeGenHLSL/builtins/unpack_s8s32.hlsl (+21)
- (added) clang/test/CodeGenHLSL/builtins/unpack_u8u16.hlsl (+21)
- (added) clang/test/CodeGenHLSL/builtins/unpack_u8u32.hlsl (+21)
- (added) clang/test/SemaHLSL/BuiltIns/unpack_s8s16-errors.hlsl (+21)
- (added) clang/test/SemaHLSL/BuiltIns/unpack_s8s32-errors.hlsl (+21)
- (added) clang/test/SemaHLSL/BuiltIns/unpack_u8u16-errors.hlsl (+21)
- (added) clang/test/SemaHLSL/BuiltIns/unpack_u8u32-errors.hlsl (+21)
- (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+5)
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+4)
- (modified) llvm/lib/Target/DirectX/DXIL.td (+35)
- (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+26)
- (added) llvm/test/CodeGen/DirectX/unpack_s8s16.ll (+18)
- (added) llvm/test/CodeGen/DirectX/unpack_s8s32.ll (+18)
- (added) llvm/test/CodeGen/DirectX/unpack_u8u16.ll (+18)
- (added) llvm/test/CodeGen/DirectX/unpack_u8u32.ll (+18)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s16.ll (+17)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s32.ll (+17)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u16.ll (+17)
- (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u32.ll (+17)
``````````diff
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 7a59aaa133d522..319403c343c1f9 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5973,6 +5973,30 @@ def HLSLDdyFine : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}
+def HLSLUnpackU8U16 : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_unpack_u8u16"];
+ let Attributes = [NoThrow, CustomTypeChecking];
+ let Prototype = "void(...)";
+}
+
+def HLSLUnpackU8U32 : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_unpack_u8u32"];
+ let Attributes = [NoThrow, CustomTypeChecking];
+ let Prototype = "void(...)";
+}
+
+def HLSLUnpackS8S16 : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_unpack_s8s16"];
+ let Attributes = [NoThrow, CustomTypeChecking];
+ let Prototype = "void(...)";
+}
+
+def HLSLUnpackS8S32 : LangBuiltin<"HLSL_LANG"> {
+ let Spellings = ["__builtin_hlsl_unpack_s8s32"];
+ let Attributes = [NoThrow, CustomTypeChecking];
+ let Prototype = "void(...)";
+}
+
// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index 4be051476395cd..0a503ee766e972 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -1927,3 +1927,27 @@ let VaryingLongVector = 1;
let IsConvergent = 1;
let Availability = SM6_0;
}
+
+def hlsl_unpack_u8u16 : HLSLBuiltin<"unpack_u8u16", "__builtin_hlsl_unpack_u8u16"> {
+ let Args = [UInt8PackedTy];
+ let ReturnType = VectorType<UInt16Ty, 4>;
+ let Availability = SM6_6;
+}
+
+def hlsl_unpack_u8u32 : HLSLBuiltin<"unpack_u8u32", "__builtin_hlsl_unpack_u8u32"> {
+ let Args = [UInt8PackedTy];
+ let ReturnType = VectorType<UIntTy, 4>;
+ let Availability = SM6_6;
+}
+
+def hlsl_unpack_s8s16 : HLSLBuiltin<"unpack_s8s16", "__builtin_hlsl_unpack_s8s16"> {
+ let Args = [Int8PackedTy];
+ let ReturnType = VectorType<Int16Ty, 4>;
+ let Availability = SM6_6;
+}
+
+def hlsl_unpack_s8s32 : HLSLBuiltin<"unpack_s8s32", "__builtin_hlsl_unpack_s8s32"> {
+ let Args = [Int8PackedTy];
+ let ReturnType = VectorType<IntTy, 4>;
+ let Availability = SM6_6;
+}
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 7ffadee3086a5c..158166214a52bb 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -416,6 +416,42 @@ static Value *handleInterlockedCompareOp(CodeGenFunction &CGF,
return Original;
}
+static Value *handleHLSLUnpackOp(CodeGenFunction &CGF, const CallExpr *E,
+ unsigned BuiltinID, const Twine &Name,
+ const bool Short) {
+ Value *Op0 = CGF.EmitScalarExpr(E->getArg(0));
+ IntegerType *IntSizeType =
+ Short ? CGF.Builder.getInt16Ty() : CGF.Builder.getInt32Ty();
+
+ if (CGF.CGM.getTarget().getTriple().isDXIL()) {
+ // DXIL Intrinsic returns struct of 4 i32 or i16
+ // We have to call intrinsic then reassemble these to a vector
+ StructType *StructType =
+ StructType::get(CGF.getLLVMContext(),
+ {IntSizeType, IntSizeType, IntSizeType, IntSizeType});
+ Value *StructVal = CGF.Builder.CreateIntrinsic(
+ /*ReturnType=*/StructType, BuiltinID, {Op0}, nullptr, Name);
+
+ llvm::Type *VecType = FixedVectorType::get(IntSizeType, 4);
+ Value *VecVal = PoisonValue::get(VecType);
+ for (unsigned I = 0; I < 4; ++I) {
+ Value *Elt = CGF.Builder.CreateExtractValue(StructVal, I);
+ VecVal =
+ CGF.Builder.CreateInsertElement(VecVal, Elt, CGF.Builder.getInt32(I));
+ }
+
+ return VecVal;
+ }
+
+ if (CGF.CGM.getTarget().getTriple().isSPIRV()) {
+ FixedVectorType *RetTy = FixedVectorType::get(IntSizeType, 4);
+ return CGF.Builder.CreateIntrinsic(/*ReturnType=*/RetTy, BuiltinID, {Op0},
+ nullptr, Name);
+ }
+
+ llvm_unreachable("Unpack_ is only supported for DXIL and SPIRV targets");
+}
+
static Value *emitBufferStride(CodeGenFunction *CGF, const Expr *HandleExpr,
LValue &Stride) {
// Figure out the stride of the buffer elements from the handle type.
@@ -1803,6 +1839,26 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
ArrayRef<Value *>{Op0}, nullptr,
"hlsl.ddy.fine");
}
+ case Builtin::BI__builtin_hlsl_unpack_u8u16: {
+ Intrinsic::ID ID = CGM.getHLSLRuntime().getUnpackU8U16Intrinsic();
+ return handleHLSLUnpackOp(*this, E, ID, "hlsl.unpack.u8u16",
+ /*Short=*/true);
+ }
+ case Builtin::BI__builtin_hlsl_unpack_u8u32: {
+ Intrinsic::ID ID = CGM.getHLSLRuntime().getUnpackU8U32Intrinsic();
+ return handleHLSLUnpackOp(*this, E, ID, "hlsl.unpack.u8u32",
+ /*Short=*/false);
+ }
+ case Builtin::BI__builtin_hlsl_unpack_s8s16: {
+ Intrinsic::ID ID = CGM.getHLSLRuntime().getUnpackS8S16Intrinsic();
+ return handleHLSLUnpackOp(*this, E, ID, "hlsl.unpack.s8s16",
+ /*Short=*/true);
+ }
+ case Builtin::BI__builtin_hlsl_unpack_s8s32: {
+ Intrinsic::ID ID = CGM.getHLSLRuntime().getUnpackS8S32Intrinsic();
+ return handleHLSLUnpackOp(*this, E, ID, "hlsl.unpack.s8s32",
+ /*Short=*/false);
+ }
case Builtin::BI__builtin_get_spirv_spec_constant_bool:
case Builtin::BI__builtin_get_spirv_spec_constant_short:
case Builtin::BI__builtin_get_spirv_spec_constant_ushort:
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index 11b3e0220dcfba..e6b7fe1bb3a663 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -214,6 +214,10 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(DdyCoarse, ddy_coarse)
GENERATE_HLSL_INTRINSIC_FUNCTION(DdxFine, ddx_fine)
GENERATE_HLSL_INTRINSIC_FUNCTION(DdyFine, ddy_fine)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(UnpackU8U16, unpack_u8u16)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(UnpackU8U32, unpack_u8u32)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(UnpackS8S16, unpack_s8s16)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(UnpackS8S32, unpack_s8s32)
//===----------------------------------------------------------------------===//
// End of reserved area for HLSL intrinsic getters.
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 73a6c8ae9672ab..df2c4f44ab18e6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4998,6 +4998,49 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
getASTContext().UnsignedIntTy);
break;
}
+ case Builtin::BI__builtin_hlsl_unpack_u8u16: {
+ if (SemaRef.checkArgCount(TheCall, 1))
+ return true;
+ if (CheckArgTypeMatches(&SemaRef, TheCall->getArg(0),
+ getASTContext().UInt8_4PackedTy))
+ return true;
+ QualType RetTy =
+ SemaRef.Context.getExtVectorType(getASTContext().UnsignedShortTy, 4);
+ TheCall->setType(RetTy);
+ break;
+ }
+ case Builtin::BI__builtin_hlsl_unpack_u8u32: {
+ if (SemaRef.checkArgCount(TheCall, 1))
+ return true;
+ if (CheckArgTypeMatches(&SemaRef, TheCall->getArg(0),
+ getASTContext().UInt8_4PackedTy))
+ return true;
+ QualType RetTy =
+ SemaRef.Context.getExtVectorType(getASTContext().UnsignedIntTy, 4);
+ TheCall->setType(RetTy);
+ break;
+ }
+ case Builtin::BI__builtin_hlsl_unpack_s8s16: {
+ if (SemaRef.checkArgCount(TheCall, 1))
+ return true;
+ if (CheckArgTypeMatches(&SemaRef, TheCall->getArg(0),
+ getASTContext().Int8_4PackedTy))
+ return true;
+ QualType RetTy =
+ SemaRef.Context.getExtVectorType(getASTContext().ShortTy, 4);
+ TheCall->setType(RetTy);
+ break;
+ }
+ case Builtin::BI__builtin_hlsl_unpack_s8s32: {
+ if (SemaRef.checkArgCount(TheCall, 1))
+ return true;
+ if (CheckArgTypeMatches(&SemaRef, TheCall->getArg(0),
+ getASTContext().Int8_4PackedTy))
+ return true;
+ QualType RetTy = SemaRef.Context.getExtVectorType(getASTContext().IntTy, 4);
+ TheCall->setType(RetTy);
+ break;
+ }
}
return false;
}
diff --git a/clang/test/CodeGenHLSL/builtins/unpack_s8s16.hlsl b/clang/test/CodeGenHLSL/builtins/unpack_s8s16.hlsl
new file mode 100644
index 00000000000000..d613b5a50b566c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/unpack_s8s16.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -fnative-int16-type -fnative-half-type -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -fnative-int16-type -fnative-half-type -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-SPV
+
+// CHECK: define {{.*}} <4 x i16> @_Z10test_s8s16u14int8_t4_packed
+// CHECK-DXIL: [[VAR:%.*]] = call { i16, i16, i16, i16 } @llvm.dx.unpack.s8s16(i32 %{{.*}})
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 0
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 1
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 2
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 3
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: ret <4 x i16>
+// CHECK-SPV: [[VAR:%.*]] = call <4 x i16> @llvm.spv.unpack.s8s16(i32 %{{.*}})
+// CHECK-SPV: ret <4 x i16> [[VAR]]
+int16_t4 test_s8s16(int8_t4_packed val) { return unpack_s8s16(val); }
diff --git a/clang/test/CodeGenHLSL/builtins/unpack_s8s32.hlsl b/clang/test/CodeGenHLSL/builtins/unpack_s8s32.hlsl
new file mode 100644
index 00000000000000..7f45a21cacdfd4
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/unpack_s8s32.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-SPV
+
+// CHECK: define {{.*}} <4 x i32> @_Z10test_s8s32u14int8_t4_packed
+// CHECK-DXIL: [[VAR:%.*]] = call { i32, i32, i32, i32 } @llvm.dx.unpack.s8s32(i32 %{{.*}})
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 0
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 1
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 2
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 3
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: ret <4 x i32>
+// CHECK-SPV: [[VAR:%.*]] = call <4 x i32> @llvm.spv.unpack.s8s32(i32 %{{.*}})
+// CHECK-SPV: ret <4 x i32> [[VAR]]
+int32_t4 test_s8s32(int8_t4_packed val) { return unpack_s8s32(val); }
diff --git a/clang/test/CodeGenHLSL/builtins/unpack_u8u16.hlsl b/clang/test/CodeGenHLSL/builtins/unpack_u8u16.hlsl
new file mode 100644
index 00000000000000..9f3a0c5b773323
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/unpack_u8u16.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -fnative-int16-type -fnative-half-type -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -fnative-int16-type -fnative-half-type -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-SPV
+
+// CHECK: define {{.*}} <4 x i16> @_Z10test_u8u16u15uint8_t4_packed
+// CHECK-DXIL: [[VAR:%.*]] = call { i16, i16, i16, i16 } @llvm.dx.unpack.u8u16(i32 %{{.*}})
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 0
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 1
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 2
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: %{{.*}} = extractvalue { i16, i16, i16, i16 } [[VAR]], 3
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i16>
+// CHECK-DXIL: ret <4 x i16>
+// CHECK-SPV: [[VAR:%.*]] = call <4 x i16> @llvm.spv.unpack.u8u16(i32 %{{.*}})
+// CHECK-SPV: ret <4 x i16> [[VAR]]
+uint16_t4 test_u8u16(uint8_t4_packed val) { return unpack_u8u16(val); }
diff --git a/clang/test/CodeGenHLSL/builtins/unpack_u8u32.hlsl b/clang/test/CodeGenHLSL/builtins/unpack_u8u32.hlsl
new file mode 100644
index 00000000000000..be7f18e457377c
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/unpack_u8u32.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-DXIL
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-pc-vulkan-library %s \
+// RUN: -emit-llvm -disable-llvm-passes -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK,CHECK-SPV
+
+// CHECK: define {{.*}} <4 x i32> @_Z10test_u8u32u15uint8_t4_packed
+// CHECK-DXIL: [[VAR:%.*]] = call { i32, i32, i32, i32 } @llvm.dx.unpack.u8u32(i32 %{{.*}})
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 0
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 1
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 2
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: %{{.*}} = extractvalue { i32, i32, i32, i32 } [[VAR]], 3
+// CHECK-DXIL: %{{.*}} = insertelement <4 x i32>
+// CHECK-DXIL: ret <4 x i32>
+// CHECK-SPV: [[VAR:%.*]] = call <4 x i32> @llvm.spv.unpack.u8u32(i32 %{{.*}})
+// CHECK-SPV: ret <4 x i32> [[VAR]]
+uint32_t4 test_u8u32(uint8_t4_packed val) { return unpack_u8u32(val); }
diff --git a/clang/test/SemaHLSL/BuiltIns/unpack_s8s16-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/unpack_s8s16-errors.hlsl
new file mode 100644
index 00000000000000..d038e462bf3adc
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/unpack_s8s16-errors.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type -emit-llvm-only -disable-llvm-passes -verify
+
+void test_builtin_no_args() {
+ __builtin_hlsl_unpack_s8s16();
+ // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+int16_t4 test_builtin_extra_args(int8_t4_packed p0) {
+ return __builtin_hlsl_unpack_s8s16(p0, p0);
+ // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+int16_t4 test_builtin_int_arg(int p0) {
+ return __builtin_hlsl_unpack_s8s16(p0);
+ // expected-error at -1 {{passing 'int' to parameter of incompatible type 'int8_t4_packed'}}
+}
+
+int16_t4 test_builtin_float_arg(float p0) {
+ return __builtin_hlsl_unpack_s8s16(p0);
+ // expected-error at -1 {{passing 'float' to parameter of incompatible type 'int8_t4_packed'}}
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/unpack_s8s32-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/unpack_s8s32-errors.hlsl
new file mode 100644
index 00000000000000..ba6d7cbac2ce91
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/unpack_s8s32-errors.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+void test_builtin_no_args() {
+ __builtin_hlsl_unpack_s8s32();
+ // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+int32_t4 test_builtin_extra_args(int8_t4_packed p0) {
+ return __builtin_hlsl_unpack_s8s32(p0, p0);
+ // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+int32_t4 test_builtin_int_arg(int p0) {
+ return __builtin_hlsl_unpack_s8s32(p0);
+ // expected-error at -1 {{passing 'int' to parameter of incompatible type 'int8_t4_packed'}}
+}
+
+int32_t4 test_builtin_float_arg(float p0) {
+ return __builtin_hlsl_unpack_s8s32(p0);
+ // expected-error at -1 {{passing 'float' to parameter of incompatible type 'int8_t4_packed'}}
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/unpack_u8u16-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/unpack_u8u16-errors.hlsl
new file mode 100644
index 00000000000000..6b8b0b549ce232
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/unpack_u8u16-errors.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type -emit-llvm-only -disable-llvm-passes -verify
+
+void test_builtin_no_args() {
+ __builtin_hlsl_unpack_u8u16();
+ // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+uint16_t4 test_builtin_extra_args(uint8_t4_packed p0) {
+ return __builtin_hlsl_unpack_u8u16(p0, p0);
+ // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+uint16_t4 test_builtin_int_arg(int p0) {
+ return __builtin_hlsl_unpack_u8u16(p0);
+ // expected-error at -1 {{passing 'int' to parameter of incompatible type 'uint8_t4_packed'}}
+}
+
+uint16_t4 test_builtin_float_arg(float p0) {
+ return __builtin_hlsl_unpack_u8u16(p0);
+ // expected-error at -1 {{passing 'float' to parameter of incompatible type 'uint8_t4_packed'}}
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/unpack_u8u32-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/unpack_u8u32-errors.hlsl
new file mode 100644
index 00000000000000..49bbbd267c8d3b
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/unpack_u8u32-errors.hlsl
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify
+
+void test_builtin_no_args() {
+ __builtin_hlsl_unpack_u8u32();
+ // expected-error at -1 {{too few arguments to function call, expected 1, have 0}}
+}
+
+uint32_t4 test_builtin_extra_args(uint8_t4_packed p0) {
+ return __builtin_hlsl_unpack_u8u32(p0, p0);
+ // expected-error at -1 {{too many arguments to function call, expected 1, have 2}}
+}
+
+uint32_t4 test_builtin_int_arg(int p0) {
+ return __builtin_hlsl_unpack_u8u32(p0);
+ // expected-error at -1 {{passing 'int' to parameter of incompatible type 'uint8_t4_packed'}}
+}
+
+uint32_t4 test_builtin_float_arg(float p0) {
+ return __builtin_hlsl_unpack_u8u32(p0);
+ // expected-error at -1 {{passing 'float' to parameter of incompatible type 'uint8_t4_packed'}}
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index e087216b822da3..740e9b22a210ea 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -359,4 +359,9 @@ def int_dx_store_output
[llvm_i32_ty /*SigElementId*/, llvm_i32_ty /*RowIndex*/,
llvm_i8_ty /*ColIndex*/, llvm_any_ty /*Value*/],
[IntrConvergent]>;
+
+def int_dx_unpack_u8u16 : DefaultAttrsIntrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_dx_unpack_u8u32 : DefaultAttrsIntrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_dx_unpack_s8s16 : DefaultAttrsIntrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_dx_unpack_s8s32 : DefaultAttrsIntrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
}
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 25b5a3c3854654..380b32c66d5579 100644
--- a/llvm/i...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/228518
More information about the cfe-commits
mailing list