https://github.com/Alexander-Johnston created https://github.com/llvm/llvm-project/pull/228518
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. >From b6b4e2e4bbe3101b219bc0aac760b03738ce5219 Mon Sep 17 00:00:00 2001 From: Alexander Johnston <[email protected]> Date: Fri, 2 Oct 2026 17:29:10 +0100 Subject: [PATCH 1/3] [DirectX] Add HLSL unpack intrinsics to DirectX backend --- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 ++++ llvm/lib/Target/DirectX/DXIL.td | 35 +++++++++++++++++++++++ llvm/test/CodeGen/DirectX/unpack_s8s16.ll | 18 ++++++++++++ llvm/test/CodeGen/DirectX/unpack_s8s32.ll | 18 ++++++++++++ llvm/test/CodeGen/DirectX/unpack_u8u16.ll | 18 ++++++++++++ llvm/test/CodeGen/DirectX/unpack_u8u32.ll | 18 ++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/unpack_s8s16.ll create mode 100644 llvm/test/CodeGen/DirectX/unpack_s8s32.ll create mode 100644 llvm/test/CodeGen/DirectX/unpack_u8u16.ll create mode 100644 llvm/test/CodeGen/DirectX/unpack_u8u32.ll 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/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 5e63e94a1c069a..ecc126ff7eff1f 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -329,6 +329,9 @@ defvar QuadOpKind_ReadAcrossX = 0; defvar QuadOpKind_ReadAcrossY = 1; defvar QuadOpKind_ReadAcrossDiagonal = 2; +defvar Unpack_Unsigned = 0; +defvar Unpack_Signed = 1; + // Intrinsic arg selection class IntrinArgSelectType; def IntrinArgSelect_Index : IntrinArgSelectType; @@ -1560,3 +1563,35 @@ def CreateHandleFromHeap : DXILOp<218, createHandleFromHeap> { let stages = [Stages<DXIL1_6, [all_stages]>]; let attributes = [Attributes<DXIL1_0, [ReadNone]>]; } + +def Unpack4x8 : DXILOp<219, unpack4x8> { + let Doc = "unpack 4 integer values from a single 32 bit value"; + let intrinsics = [ + IntrinSelect<int_dx_unpack_u8u16, + [ + IntrinArgI8<Unpack_Unsigned>, + IntrinArgIndex<0> + ]>, + IntrinSelect<int_dx_unpack_u8u32, + [ + IntrinArgI8<Unpack_Unsigned>, + IntrinArgIndex<0> + ]>, + IntrinSelect<int_dx_unpack_s8s16, + [ + IntrinArgI8<Unpack_Signed>, + IntrinArgIndex<0> + ]>, + IntrinSelect<int_dx_unpack_s8s32, + [ + IntrinArgI8<Unpack_Signed>, + IntrinArgIndex<0> + ]>, + ]; + + let arguments = [Int8Ty, Int32Ty]; + let result = OverloadTy; + let overloads = [Overloads<DXIL1_6, [Int16Ty, Int32Ty]>]; + let stages = [Stages<DXIL1_6, [all_stages]>]; + let attributes = [Attributes<DXIL1_6, [ReadNone]>]; +} diff --git a/llvm/test/CodeGen/DirectX/unpack_s8s16.ll b/llvm/test/CodeGen/DirectX/unpack_s8s16.ll new file mode 100644 index 00000000000000..d65db0c83faf50 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/unpack_s8s16.ll @@ -0,0 +1,18 @@ +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-library %s | FileCheck %s + +define noundef <4 x i16> @test_unpack_s8s16(i32 noundef %a) { + ; CHECK: %{{.*}} = call { i16, i16, i16, i16 } @dx.op.unpack4x8.i16(i32 219, i8 1, i32 {{.*}}) + %unpacked = call { i16, i16, i16, i16 } @llvm.dx.unpack.s8s16(i32 %a) + %1 = extractvalue { i16, i16, i16, i16 } %unpacked, 0 + %2 = extractvalue { i16, i16, i16, i16 } %unpacked, 1 + %3 = extractvalue { i16, i16, i16, i16 } %unpacked, 2 + %4 = extractvalue { i16, i16, i16, i16 } %unpacked, 3 + %5 = insertelement <4 x i16> poison, i16 %1, i32 0 + %6 = insertelement <4 x i16> %5, i16 %2, i32 1 + %7 = insertelement <4 x i16> %6, i16 %3, i32 2 + %8 = insertelement <4 x i16> %7, i16 %4, i32 3 + ret <4 x i16> %8 +} + +; CHECK-DAG: declare { i16, i16, i16, i16 } @dx.op.unpack4x8.i16(i32, i8, i32) +declare { i16, i16, i16, i16 } @llvm.dx.unpack.s8s16(i32) diff --git a/llvm/test/CodeGen/DirectX/unpack_s8s32.ll b/llvm/test/CodeGen/DirectX/unpack_s8s32.ll new file mode 100644 index 00000000000000..22d7736fa2a1d2 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/unpack_s8s32.ll @@ -0,0 +1,18 @@ +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-library %s | FileCheck %s + +define noundef <4 x i32> @test_unpack_s8s32(i32 noundef %a) { + ; CHECK: %{{.*}} = call { i32, i32, i32, i32 } @dx.op.unpack4x8.i32(i32 219, i8 1, i32 {{.*}}) + %unpacked = call { i32, i32, i32, i32 } @llvm.dx.unpack.s8s32(i32 %a) + %1 = extractvalue { i32, i32, i32, i32 } %unpacked, 0 + %2 = extractvalue { i32, i32, i32, i32 } %unpacked, 1 + %3 = extractvalue { i32, i32, i32, i32 } %unpacked, 2 + %4 = extractvalue { i32, i32, i32, i32 } %unpacked, 3 + %5 = insertelement <4 x i32> poison, i32 %1, i32 0 + %6 = insertelement <4 x i32> %5, i32 %2, i32 1 + %7 = insertelement <4 x i32> %6, i32 %3, i32 2 + %8 = insertelement <4 x i32> %7, i32 %4, i32 3 + ret <4 x i32> %8 +} + +; CHECK-DAG: declare { i32, i32, i32, i32 } @dx.op.unpack4x8.i32(i32, i8, i32) +declare { i32, i32, i32, i32 } @llvm.dx.unpack.s8s32(i32) diff --git a/llvm/test/CodeGen/DirectX/unpack_u8u16.ll b/llvm/test/CodeGen/DirectX/unpack_u8u16.ll new file mode 100644 index 00000000000000..34ee17bdf6dda0 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/unpack_u8u16.ll @@ -0,0 +1,18 @@ +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-library %s | FileCheck %s + +define noundef <4 x i16> @test_unpack_u8u16(i32 noundef %a) { + ; CHECK: %{{.*}} = call { i16, i16, i16, i16 } @dx.op.unpack4x8.i16(i32 219, i8 0, i32 {{.*}}) + %unpacked = call { i16, i16, i16, i16 } @llvm.dx.unpack.u8u16(i32 %a) + %1 = extractvalue { i16, i16, i16, i16 } %unpacked, 0 + %2 = extractvalue { i16, i16, i16, i16 } %unpacked, 1 + %3 = extractvalue { i16, i16, i16, i16 } %unpacked, 2 + %4 = extractvalue { i16, i16, i16, i16 } %unpacked, 3 + %5 = insertelement <4 x i16> poison, i16 %1, i32 0 + %6 = insertelement <4 x i16> %5, i16 %2, i32 1 + %7 = insertelement <4 x i16> %6, i16 %3, i32 2 + %8 = insertelement <4 x i16> %7, i16 %4, i32 3 + ret <4 x i16> %8 +} + +; CHECK-DAG: declare { i16, i16, i16, i16 } @dx.op.unpack4x8.i16(i32, i8, i32) +declare { i16, i16, i16, i16 } @llvm.dx.unpack.u8u16(i32) diff --git a/llvm/test/CodeGen/DirectX/unpack_u8u32.ll b/llvm/test/CodeGen/DirectX/unpack_u8u32.ll new file mode 100644 index 00000000000000..3943e487bef4f0 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/unpack_u8u32.ll @@ -0,0 +1,18 @@ +; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-library %s | FileCheck %s + +define noundef <4 x i32> @test_unpack_u8u32(i32 noundef %a) { + ; CHECK: %{{.*}} = call { i32, i32, i32, i32 } @dx.op.unpack4x8.i32(i32 219, i8 0, i32 {{.*}}) + %unpacked = call { i32, i32, i32, i32 } @llvm.dx.unpack.u8u32(i32 %a) + %1 = extractvalue { i32, i32, i32, i32 } %unpacked, 0 + %2 = extractvalue { i32, i32, i32, i32 } %unpacked, 1 + %3 = extractvalue { i32, i32, i32, i32 } %unpacked, 2 + %4 = extractvalue { i32, i32, i32, i32 } %unpacked, 3 + %5 = insertelement <4 x i32> poison, i32 %1, i32 0 + %6 = insertelement <4 x i32> %5, i32 %2, i32 1 + %7 = insertelement <4 x i32> %6, i32 %3, i32 2 + %8 = insertelement <4 x i32> %7, i32 %4, i32 3 + ret <4 x i32> %8 +} + +; CHECK-DAG: declare { i32, i32, i32, i32 } @dx.op.unpack4x8.i32(i32, i8, i32) +declare { i32, i32, i32, i32 } @llvm.dx.unpack.u8u32(i32) >From 9c7c571228a08c80134fbc77bc9ba5dab3a51961 Mon Sep 17 00:00:00 2001 From: Alexander Johnston <[email protected]> Date: Fri, 2 Oct 2026 17:31:52 +0100 Subject: [PATCH 2/3] [SPIRV] Add HLSL unpack intrinsics to SPIRV backend --- llvm/include/llvm/IR/IntrinsicsSPIRV.td | 4 +++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 26 +++++++++++++++++++ .../SPIRV/hlsl-intrinsics/unpack_s8s16.ll | 17 ++++++++++++ .../SPIRV/hlsl-intrinsics/unpack_s8s32.ll | 17 ++++++++++++ .../SPIRV/hlsl-intrinsics/unpack_u8u16.ll | 17 ++++++++++++ .../SPIRV/hlsl-intrinsics/unpack_u8u32.ll | 17 ++++++++++++ 6 files changed, 98 insertions(+) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s16.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s32.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u16.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u32.ll diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td index 25b5a3c3854654..380b32c66d5579 100644 --- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td +++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td @@ -376,4 +376,8 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty] def int_spv_packhalf2x16 : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]>; + def int_spv_unpack_u8u16 : DefaultAttrsIntrinsic<[llvm_v4i16_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_spv_unpack_u8u32 : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_spv_unpack_s8s16 : DefaultAttrsIntrinsic<[llvm_v4i16_ty], [llvm_i32_ty], [IntrNoMem]>; + def int_spv_unpack_s8s32 : DefaultAttrsIntrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>; } diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 143e1c0e3ef2ab..a6bdb6a8096a24 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -485,6 +485,8 @@ class SPIRVInstructionSelector : public InstructionSelector { MachineInstr &I) const; bool selectDerivativeInst(Register ResVReg, SPIRVTypeInst ResType, MachineInstr &I, const unsigned DPdOpCode) const; + bool selectUnpackInst(Register ResVReg, SPIRVTypeInst ResType, + MachineInstr &I, const bool Signed) const; // Utilities Register buildI32Constant(uint32_t Val, MachineInstr &I, SPIRVTypeInst ResType = nullptr) const; @@ -5262,6 +5264,24 @@ bool SPIRVInstructionSelector::selectDerivativeInst( return true; } +bool SPIRVInstructionSelector::selectUnpackInst(Register ResVReg, + SPIRVTypeInst ResType, + MachineInstr &I, + const bool Signed) const { + MachineIRBuilder MIRBuilder(I); + SPIRVTypeInst I8Type = GR.getOrCreateSPIRVIntegerType(8, MIRBuilder); + SPIRVTypeInst I8x4Type = + GR.getOrCreateSPIRVVectorType(I8Type, 4, MIRBuilder, true); + + Register I8x4Reg = MRI->createVirtualRegister(GR.getRegClass(I8x4Type)); + if (!selectOpWithSrcs(I8x4Reg, I8x4Type, I, {I.getOperand(2).getReg()}, + SPIRV::OpBitcast)) + return false; + + unsigned ConvertOpcode = Signed ? SPIRV::OpSConvert : SPIRV::OpUConvert; + return selectOpWithSrcs(ResVReg, ResType, I, {I8x4Reg}, ConvertOpcode); +} + bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, SPIRVTypeInst ResType, MachineInstr &I) const { @@ -5853,6 +5873,12 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg, MIB.constrainAllUses(TII, TRI, RBI); return true; } + case Intrinsic::spv_unpack_u8u16: + case Intrinsic::spv_unpack_u8u32: + return selectUnpackInst(ResVReg, ResType, I, false); + case Intrinsic::spv_unpack_s8s16: + case Intrinsic::spv_unpack_s8s32: + return selectUnpackInst(ResVReg, ResType, I, true); default: return diagnoseUnsupported(I, "intrinsic selection not implemented."); } diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s16.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s16.ll new file mode 100644 index 00000000000000..2d494cca2ec883 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s16.ll @@ -0,0 +1,17 @@ +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: [[int8:%.*]] = OpTypeInt 8 0 +; CHECK-DAG: [[int8x4:%.*]] = OpTypeVector [[int8]] 4 +; CHECK-DAG: [[int16:%.*]] = OpTypeInt 16 0 +; CHECK-DAG: [[int16x4:%.*]] = OpTypeVector [[int16]] 4 + +define noundef <4 x i16> @unpack_s8s16(i32 noundef %a) { +; CHECK: [[in:%.*]] = OpFunctionParameter +; CHECK: [[cast:%.*]] = OpBitcast [[int8x4]] [[in]] +; CHECK: [[converted:%.*]] = OpSConvert [[int16x4]] [[cast]] + %unpacked = call <4 x i16> @llvm.spv.unpack.s8s16(i32 %a) + ret <4 x i16> %unpacked +} + +declare <4 x i16> @llvm.spv.unpack.s8s16(i32) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s32.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s32.ll new file mode 100644 index 00000000000000..6745b053c2e487 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_s8s32.ll @@ -0,0 +1,17 @@ +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: [[int8:%.*]] = OpTypeInt 8 0 +; CHECK-DAG: [[int8x4:%.*]] = OpTypeVector [[int8]] 4 +; CHECK-DAG: [[int32:%.*]] = OpTypeInt 32 0 +; CHECK-DAG: [[int32x4:%.*]] = OpTypeVector [[int32]] 4 + +define noundef <4 x i32> @unpack_s8s32(i32 noundef %a) { +; CHECK: [[in:%.*]] = OpFunctionParameter +; CHECK: [[cast:%.*]] = OpBitcast [[int8x4]] [[in]] +; CHECK: [[converted:%.*]] = OpSConvert [[int32x4]] [[cast]] + %unpacked = call <4 x i32> @llvm.spv.unpack.s8s32(i32 %a) + ret <4 x i32> %unpacked +} + +declare <4 x i32> @llvm.spv.unpack.s8s32(i32) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u16.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u16.ll new file mode 100644 index 00000000000000..8c0ce6265215e6 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u16.ll @@ -0,0 +1,17 @@ +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: [[int8:%.*]] = OpTypeInt 8 0 +; CHECK-DAG: [[int8x4:%.*]] = OpTypeVector [[int8]] 4 +; CHECK-DAG: [[int16:%.*]] = OpTypeInt 16 0 +; CHECK-DAG: [[int16x4:%.*]] = OpTypeVector [[int16]] 4 + +define noundef <4 x i16> @unpack_u8u16(i32 noundef %a) { +; CHECK: [[in:%.*]] = OpFunctionParameter +; CHECK: [[cast:%.*]] = OpBitcast [[int8x4]] [[in]] +; CHECK: [[converted:%.*]] = OpUConvert [[int16x4]] [[cast]] + %unpacked = call <4 x i16> @llvm.spv.unpack.u8u16(i32 %a) + ret <4 x i16> %unpacked +} + +declare <4 x i16> @llvm.spv.unpack.u8u16(i32) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u32.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u32.ll new file mode 100644 index 00000000000000..a4952950a800dc --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/unpack_u8u32.ll @@ -0,0 +1,17 @@ +; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv-unknown-vulkan %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-vulkan %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: [[int8:%.*]] = OpTypeInt 8 0 +; CHECK-DAG: [[int8x4:%.*]] = OpTypeVector [[int8]] 4 +; CHECK-DAG: [[int32:%.*]] = OpTypeInt 32 0 +; CHECK-DAG: [[int32x4:%.*]] = OpTypeVector [[int32]] 4 + +define noundef <4 x i32> @unpack_u8u32(i32 noundef %a) { +; CHECK: [[in:%.*]] = OpFunctionParameter +; CHECK: [[cast:%.*]] = OpBitcast [[int8x4]] [[in]] +; CHECK: [[converted:%.*]] = OpUConvert [[int32x4]] [[cast]] + %unpacked = call <4 x i32> @llvm.spv.unpack.u8u32(i32 %a) + ret <4 x i32> %unpacked +} + +declare <4 x i32> @llvm.spv.unpack.u8u32(i32) >From abd051e5531fac3c39973a0862ab94eeee8ae458 Mon Sep 17 00:00:00 2001 From: Alexander Johnston <[email protected]> Date: Fri, 2 Oct 2026 17:32:32 +0100 Subject: [PATCH 3/3] [HLSL] Add HLSL unpack intrinsics to Clang These intrinsics unpack a packed type (int8_t4_packed or uint8_t4_packed) into an appropriate 4 element vector. --- clang/include/clang/Basic/Builtins.td | 24 ++++++++ clang/include/clang/Basic/HLSLIntrinsics.td | 24 ++++++++ clang/lib/CodeGen/CGHLSLBuiltins.cpp | 56 +++++++++++++++++++ clang/lib/CodeGen/CGHLSLRuntime.h | 4 ++ clang/lib/Sema/SemaHLSL.cpp | 43 ++++++++++++++ .../CodeGenHLSL/builtins/unpack_s8s16.hlsl | 21 +++++++ .../CodeGenHLSL/builtins/unpack_s8s32.hlsl | 21 +++++++ .../CodeGenHLSL/builtins/unpack_u8u16.hlsl | 21 +++++++ .../CodeGenHLSL/builtins/unpack_u8u32.hlsl | 21 +++++++ .../BuiltIns/unpack_s8s16-errors.hlsl | 21 +++++++ .../BuiltIns/unpack_s8s32-errors.hlsl | 21 +++++++ .../BuiltIns/unpack_u8u16-errors.hlsl | 21 +++++++ .../BuiltIns/unpack_u8u32-errors.hlsl | 21 +++++++ 13 files changed, 319 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/unpack_s8s16.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/unpack_s8s32.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/unpack_u8u16.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/unpack_u8u32.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/unpack_s8s16-errors.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/unpack_s8s32-errors.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/unpack_u8u16-errors.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/unpack_u8u32-errors.hlsl 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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-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@-1 {{passing 'float' to parameter of incompatible type 'uint8_t4_packed'}} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
