[llvm] [SPIRV] Add support for `cl_khr_extended_bit_ops` (PR #120571)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 19 04:50:20 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Marcos Maronas (maarquitos14)

<details>
<summary>Changes</summary>

This PR adds support for `cl_khr_extended_bit_ops` in SPIRV Backend. Note that `cl_khr_extended_bit_ops` only supports types in
```
char, charn, uchar, ucharn, short, shortn, ushort, ushortn, int, intn, uint, uintn, long, longn, ulong, and ulongn
```
where `n is 2, 3, 4, 8, or 16`.

Subsequent PRs will introduce support for non-standard bit width required by `SPV_KHR_bit_instructions`. 

---

Patch is 63.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/120571.diff


4 Files Affected:

- (modified) llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp (+45) 
- (modified) llvm/lib/Target/SPIRV/SPIRVBuiltins.td (+11) 
- (added) llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/cl_khr_extended_bit_ops.cl (+1191) 
- (modified) llvm/test/CodeGen/SPIRV/lit.local.cfg (+6) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 73dce230575d84..d64d9177b49219 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -983,6 +983,38 @@ static bool buildBarrierInst(const SPIRV::IncomingCall *Call, unsigned Opcode,
   return true;
 }
 
+/// Helper function for building extended bit operations.
+static bool buildExtendedBitOpsInst(const SPIRV::IncomingCall *Call, unsigned Opcode,
+                             MachineIRBuilder &MIRBuilder,
+                             SPIRVGlobalRegistry *GR) {
+  const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+  const auto *ST =
+      static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
+  if ((Opcode == SPIRV::OpBitFieldInsert ||
+       Opcode == SPIRV::OpBitFieldSExtract ||
+       Opcode == SPIRV::OpBitFieldUExtract ||
+       Opcode == SPIRV::OpBitReverse) &&
+      !ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
+    std::string DiagMsg = std::string(Builtin->Name) +
+                          ": the builtin requires the following SPIR-V "
+                          "extension: SPV_KHR_bit_instructions";
+    report_fatal_error(DiagMsg.c_str(), false);
+  }
+
+  // Generate SPIRV instruction accordingly.
+  if (Call->isSpirvOp())
+    return buildOpFromWrapper(MIRBuilder, Opcode, Call, Register(0));
+
+  // Generate the instruction.
+  auto MIB = MIRBuilder.buildInstr(Opcode)
+      .addDef(Call->ReturnRegister)
+      .addUse(GR->getSPIRVTypeID(Call->ReturnType));
+  for (unsigned i = 0; i < Call->Arguments.size(); ++i)
+    MIB.addUse(Call->Arguments[i]);
+
+  return true;
+}
+
 static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim) {
   switch (dim) {
   case SPIRV::Dim::DIM_1D:
@@ -2041,6 +2073,17 @@ static bool generateSpecConstantInst(const SPIRV::IncomingCall *Call,
   }
 }
 
+static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
+                                MachineIRBuilder &MIRBuilder,
+                                SPIRVGlobalRegistry *GR) {
+  // Lookup the instruction opcode in the TableGen records.
+  const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+  unsigned Opcode =
+      SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
+
+  return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
+}
+
 static bool buildNDRange(const SPIRV::IncomingCall *Call,
                          MachineIRBuilder &MIRBuilder,
                          SPIRVGlobalRegistry *GR) {
@@ -2628,6 +2671,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
     return generateKernelClockInst(Call.get(), MIRBuilder, GR);
   case SPIRV::CoopMatr:
     return generateCoopMatrInst(Call.get(), MIRBuilder, GR);
+  case SPIRV::ExtendedBitOps:
+    return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
   }
   return false;
 }
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index e0dfc25723b0cc..9a146b331ffc10 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -64,6 +64,7 @@ def CastToPtr : BuiltinGroup;
 def Construct : BuiltinGroup;
 def CoopMatr : BuiltinGroup;
 def ICarryBorrow : BuiltinGroup;
+def ExtendedBitOps : BuiltinGroup;
 
 //===----------------------------------------------------------------------===//
 // Class defining a demangled builtin record. The information in the record
@@ -1441,6 +1442,16 @@ defm : DemangledNativeBuiltin<"__spirv_SatConvertSToU", OpenCL_std, Convert, 1,
 defm : DemangledNativeBuiltin<"__spirv_SatConvertUToS", OpenCL_std, Convert, 1, 1, OpSatConvertUToS>;
 defm : DemangledNativeBuiltin<"__spirv_ConvertUToPtr", OpenCL_std, Convert, 1, 1, OpConvertUToPtr>;
 
+// cl_khr_extended_bit_ops / SPV_KHR_bit_instructions
+defm : DemangledNativeBuiltin<"bitfield_insert", OpenCL_std, ExtendedBitOps, 4, 4, OpBitFieldInsert>;
+defm : DemangledNativeBuiltin<"__spirv_BitFieldInsert", OpenCL_std, ExtendedBitOps, 4, 4, OpBitFieldInsert>;
+defm : DemangledNativeBuiltin<"bitfield_extract_signed", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldSExtract>;
+defm : DemangledNativeBuiltin<"__spirv_BitFieldSExtract", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldSExtract>;
+defm : DemangledNativeBuiltin<"bitfield_extract_unsigned", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldUExtract>;
+defm : DemangledNativeBuiltin<"__spirv_BitFieldUExtract", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldUExtract>;
+defm : DemangledNativeBuiltin<"bit_reverse", OpenCL_std, ExtendedBitOps, 1, 1, OpBitReverse>;
+defm : DemangledNativeBuiltin<"__spirv_BitReverse", OpenCL_std, ExtendedBitOps, 1, 1, OpBitReverse>;
+
 // cl_intel_bfloat16_conversions / SPV_INTEL_bfloat16_conversion
 // Multiclass used to define at the same time both a demangled builtin records
 // and a corresponding convert builtin records.
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/cl_khr_extended_bit_ops.cl b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/cl_khr_extended_bit_ops.cl
new file mode 100644
index 00000000000000..4f7fd131f6f9a9
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/cl_khr_extended_bit_ops.cl
@@ -0,0 +1,1191 @@
+// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header -emit-llvm-bc %s -o %t.bc
+// RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %t.bc --spirv-ext=+SPV_KHR_bit_instructions -o - | FileCheck %s --check-prefix=CHECK-EXTENSION
+// RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %t.bc -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-NO-EXTENSION
+
+// CHECK-SPIRV: Capability BitInstructions
+// CHECK-SPIRV: Extension "SPV_KHR_bit_instructions"
+// CHECK-NO-EXTENSION: LLVM ERROR: bitfield_insert: the builtin requires the following SPIR-V extension: SPV_KHR_bit_instructions
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_long:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_long:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_long]] %[[#insertinsert_long]]
+kernel void testInsert_long(long b, long i, global long *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ulong:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ulong:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ulong]] %[[#insertinsert_ulong]]
+kernel void testInsert_ulong(ulong b, ulong i, global ulong *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_int:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_int:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_int]] %[[#insertinsert_int]]
+kernel void testInsert_int(int b, int i, global int *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uint:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uint:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uint]] %[[#insertinsert_uint]]
+kernel void testInsert_uint(uint b, uint i, global uint *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_short:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_short:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_short]] %[[#insertinsert_short]]
+kernel void testInsert_short(short b, short i, global short *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ushort:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ushort:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ushort]] %[[#insertinsert_ushort]]
+kernel void testInsert_ushort(ushort b, ushort i, global ushort *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_long2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_long2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_long2]] %[[#insertinsert_long2]]
+kernel void testInsert_long2(long2 b, long2 i, global long2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ulong2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ulong2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ulong2]] %[[#insertinsert_ulong2]]
+kernel void testInsert_ulong2(ulong2 b, ulong2 i, global ulong2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_int2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_int2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_int2]] %[[#insertinsert_int2]]
+kernel void testInsert_int2(int2 b, int2 i, global int2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uint2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uint2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uint2]] %[[#insertinsert_uint2]]
+kernel void testInsert_uint2(uint2 b, uint2 i, global uint2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_short2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_short2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_short2]] %[[#insertinsert_short2]]
+kernel void testInsert_short2(short2 b, short2 i, global short2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ushort2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ushort2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ushort2]] %[[#insertinsert_ushort2]]
+kernel void testInsert_ushort2(ushort2 b, ushort2 i, global ushort2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_char2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_char2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_char2]] %[[#insertinsert_char2]]
+kernel void testInsert_char2(char2 b, char2 i, global char2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uchar2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uchar2:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uchar2]] %[[#insertinsert_uchar2]]
+kernel void testInsert_uchar2(uchar2 b, uchar2 i, global uchar2 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_long3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_long3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_long3]] %[[#insertinsert_long3]]
+kernel void testInsert_long3(long3 b, long3 i, global long3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ulong3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ulong3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ulong3]] %[[#insertinsert_ulong3]]
+kernel void testInsert_ulong3(ulong3 b, ulong3 i, global ulong3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_int3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_int3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_int3]] %[[#insertinsert_int3]]
+kernel void testInsert_int3(int3 b, int3 i, global int3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uint3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uint3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uint3]] %[[#insertinsert_uint3]]
+kernel void testInsert_uint3(uint3 b, uint3 i, global uint3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_short3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_short3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_short3]] %[[#insertinsert_short3]]
+kernel void testInsert_short3(short3 b, short3 i, global short3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ushort3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ushort3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ushort3]] %[[#insertinsert_ushort3]]
+kernel void testInsert_ushort3(ushort3 b, ushort3 i, global ushort3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_char3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_char3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_char3]] %[[#insertinsert_char3]]
+kernel void testInsert_char3(char3 b, char3 i, global char3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uchar3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uchar3:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uchar3]] %[[#insertinsert_uchar3]]
+kernel void testInsert_uchar3(uchar3 b, uchar3 i, global uchar3 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_long4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_long4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_long4]] %[[#insertinsert_long4]]
+kernel void testInsert_long4(long4 b, long4 i, global long4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ulong4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ulong4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ulong4]] %[[#insertinsert_ulong4]]
+kernel void testInsert_ulong4(ulong4 b, ulong4 i, global ulong4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_int4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_int4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_int4]] %[[#insertinsert_int4]]
+kernel void testInsert_int4(int4 b, int4 i, global int4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uint4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uint4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uint4]] %[[#insertinsert_uint4]]
+kernel void testInsert_uint4(uint4 b, uint4 i, global uint4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_short4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_short4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_short4]] %[[#insertinsert_short4]]
+kernel void testInsert_short4(short4 b, short4 i, global short4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ushort4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ushort4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ushort4]] %[[#insertinsert_ushort4]]
+kernel void testInsert_ushort4(ushort4 b, ushort4 i, global ushort4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_char4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_char4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_char4]] %[[#insertinsert_char4]]
+kernel void testInsert_char4(char4 b, char4 i, global char4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uchar4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uchar4:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uchar4]] %[[#insertinsert_uchar4]]
+kernel void testInsert_uchar4(uchar4 b, uchar4 i, global uchar4 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_long8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_long8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_long8]] %[[#insertinsert_long8]]
+kernel void testInsert_long8(long8 b, long8 i, global long8 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_ulong8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_ulong8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_ulong8]] %[[#insertinsert_ulong8]]
+kernel void testInsert_ulong8(ulong8 b, ulong8 i, global ulong8 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_int8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_int8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_int8]] %[[#insertinsert_int8]]
+kernel void testInsert_int8(int8 b, int8 i, global int8 *res) {
+  *res = bitfield_insert(b, i, 4, 2);
+}
+
+// CHECK-EXTENSION: %[[#]] = OpFunction %[[#]] None %[[#]]
+// CHECK-EXTENSION: %[[#insertbase_uint8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#insertinsert_uint8:]] = OpFunctionParameter %[[#]]
+// CHECK-EXTENSION: %[[#]] = OpBitFieldInsert %[[#]] %[[#insertbase_uint8]] %[[#insertinsert_uint8]]
+kernel void testInsert_uint8(uint8 b, uint8 i, global uint8 *res) {
+  *res = ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/120571


More information about the llvm-commits mailing list