Skip to content

Commit bbef9c7

Browse files
maarquitos14Icohedron
authored andcommitted
[SPIRV] Add support for cl_khr_extended_bit_ops (llvm#120571)
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`.
1 parent c25e4e7 commit bbef9c7

File tree

6 files changed

+2999
-0
lines changed

6 files changed

+2999
-0
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,38 @@ static bool buildBarrierInst(const SPIRV::IncomingCall *Call, unsigned Opcode,
10091009
return true;
10101010
}
10111011

1012+
/// Helper function for building extended bit operations.
1013+
static bool buildExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
1014+
unsigned Opcode,
1015+
MachineIRBuilder &MIRBuilder,
1016+
SPIRVGlobalRegistry *GR) {
1017+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
1018+
const auto *ST =
1019+
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
1020+
if ((Opcode == SPIRV::OpBitFieldInsert ||
1021+
Opcode == SPIRV::OpBitFieldSExtract ||
1022+
Opcode == SPIRV::OpBitFieldUExtract || Opcode == SPIRV::OpBitReverse) &&
1023+
!ST->canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1024+
std::string DiagMsg = std::string(Builtin->Name) +
1025+
": the builtin requires the following SPIR-V "
1026+
"extension: SPV_KHR_bit_instructions";
1027+
report_fatal_error(DiagMsg.c_str(), false);
1028+
}
1029+
1030+
// Generate SPIRV instruction accordingly.
1031+
if (Call->isSpirvOp())
1032+
return buildOpFromWrapper(MIRBuilder, Opcode, Call,
1033+
GR->getSPIRVTypeID(Call->ReturnType));
1034+
1035+
auto MIB = MIRBuilder.buildInstr(Opcode)
1036+
.addDef(Call->ReturnRegister)
1037+
.addUse(GR->getSPIRVTypeID(Call->ReturnType));
1038+
for (unsigned i = 0; i < Call->Arguments.size(); ++i)
1039+
MIB.addUse(Call->Arguments[i]);
1040+
1041+
return true;
1042+
}
1043+
10121044
static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim) {
10131045
switch (dim) {
10141046
case SPIRV::Dim::DIM_1D:
@@ -2180,6 +2212,17 @@ static bool generateSpecConstantInst(const SPIRV::IncomingCall *Call,
21802212
}
21812213
}
21822214

2215+
static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
2216+
MachineIRBuilder &MIRBuilder,
2217+
SPIRVGlobalRegistry *GR) {
2218+
// Lookup the instruction opcode in the TableGen records.
2219+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
2220+
unsigned Opcode =
2221+
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
2222+
2223+
return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
2224+
}
2225+
21832226
static bool buildNDRange(const SPIRV::IncomingCall *Call,
21842227
MachineIRBuilder &MIRBuilder,
21852228
SPIRVGlobalRegistry *GR) {
@@ -2755,6 +2798,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
27552798
return generateKernelClockInst(Call.get(), MIRBuilder, GR);
27562799
case SPIRV::CoopMatr:
27572800
return generateCoopMatrInst(Call.get(), MIRBuilder, GR);
2801+
case SPIRV::ExtendedBitOps:
2802+
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
27582803
}
27592804
return false;
27602805
}

llvm/lib/Target/SPIRV/SPIRVBuiltins.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def CastToPtr : BuiltinGroup;
6565
def Construct : BuiltinGroup;
6666
def CoopMatr : BuiltinGroup;
6767
def ICarryBorrow : BuiltinGroup;
68+
def ExtendedBitOps : BuiltinGroup;
6869

6970
//===----------------------------------------------------------------------===//
7071
// Class defining a demangled builtin record. The information in the record
@@ -1465,6 +1466,16 @@ defm : DemangledNativeBuiltin<"__spirv_SatConvertSToU", OpenCL_std, Convert, 1,
14651466
defm : DemangledNativeBuiltin<"__spirv_SatConvertUToS", OpenCL_std, Convert, 1, 1, OpSatConvertUToS>;
14661467
defm : DemangledNativeBuiltin<"__spirv_ConvertUToPtr", OpenCL_std, Convert, 1, 1, OpConvertUToPtr>;
14671468

1469+
// cl_khr_extended_bit_ops / SPV_KHR_bit_instructions
1470+
defm : DemangledNativeBuiltin<"bitfield_insert", OpenCL_std, ExtendedBitOps, 4, 4, OpBitFieldInsert>;
1471+
defm : DemangledNativeBuiltin<"__spirv_BitFieldInsert", OpenCL_std, ExtendedBitOps, 4, 4, OpBitFieldInsert>;
1472+
defm : DemangledNativeBuiltin<"bitfield_extract_signed", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldSExtract>;
1473+
defm : DemangledNativeBuiltin<"__spirv_BitFieldSExtract", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldSExtract>;
1474+
defm : DemangledNativeBuiltin<"bitfield_extract_unsigned", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldUExtract>;
1475+
defm : DemangledNativeBuiltin<"__spirv_BitFieldUExtract", OpenCL_std, ExtendedBitOps, 3, 3, OpBitFieldUExtract>;
1476+
defm : DemangledNativeBuiltin<"bit_reverse", OpenCL_std, ExtendedBitOps, 1, 1, OpBitReverse>;
1477+
defm : DemangledNativeBuiltin<"__spirv_BitReverse", OpenCL_std, ExtendedBitOps, 1, 1, OpBitReverse>;
1478+
14681479
// cl_intel_bfloat16_conversions / SPV_INTEL_bfloat16_conversion
14691480
// Multiclass used to define at the same time both a demangled builtin records
14701481
// and a corresponding convert builtin records.

0 commit comments

Comments
 (0)