Skip to content

Add support for SPIR-V extension: SPV_INTEL_media_block_io #118024

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 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/docs/SPIRVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
- Adds decorations that can be applied to global (module scope) variables.
* - ``SPV_INTEL_global_variable_fpga_decorations``
- Adds decorations that can be applied to global (module scope) variables to help code generation for FPGA devices.
* - ``SPV_INTEL_media_block_io``
- Adds additional subgroup block read and write functionality that allow applications to flexibly specify the width and height of the block to read from or write to a 2D image.
* - ``SPV_INTEL_optnone``
- Adds OptNoneINTEL value for Function Control mask that indicates a request to not optimize the function.
* - ``SPV_INTEL_split_barrier``
Expand Down
24 changes: 19 additions & 5 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ struct IntelSubgroupsBuiltin {
uint32_t Opcode;
bool IsBlock;
bool IsWrite;
bool IsMedia;
};

#define GET_IntelSubgroupsBuiltins_DECL
Expand Down Expand Up @@ -215,6 +216,8 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall) {
// - "__spirv_ReadClockKHR"
// - "__spirv_SubgroupBlockReadINTEL"
// - "__spirv_SubgroupImageBlockReadINTEL"
// - "__spirv_SubgroupImageMediaBlockReadINTEL"
// - "__spirv_SubgroupImageMediaBlockWriteINTEL"
// - "__spirv_Convert"
// - "__spirv_UConvert"
// - "__spirv_SConvert"
Expand All @@ -225,7 +228,9 @@ std::string lookupBuiltinNameHelper(StringRef DemangledCall) {
static const std::regex SpvWithR(
"(__spirv_(ImageSampleExplicitLod|ImageRead|ImageQuerySizeLod|UDotKHR|"
"SDotKHR|SUDotKHR|SDotAccSatKHR|UDotAccSatKHR|SUDotAccSatKHR|"
"ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|Convert|"
"ReadClockKHR|SubgroupBlockReadINTEL|SubgroupImageBlockReadINTEL|"
"SubgroupImageMediaBlockReadINTEL|SubgroupImageMediaBlockWriteINTEL|"
"Convert|"
"UConvert|SConvert|FConvert|SatConvert).*)_R.*");
std::smatch Match;
if (std::regex_match(BuiltinName, Match, SpvWithR) && Match.size() > 2)
Expand Down Expand Up @@ -1196,19 +1201,28 @@ static bool generateIntelSubgroupsInst(const SPIRV::IncomingCall *Call,
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
MachineFunction &MF = MIRBuilder.getMF();
const auto *ST = static_cast<const SPIRVSubtarget *>(&MF.getSubtarget());
if (!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
const SPIRV::IntelSubgroupsBuiltin *IntelSubgroups =
SPIRV::lookupIntelSubgroupsBuiltin(Builtin->Name);

if (IntelSubgroups->IsMedia &&
!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
std::string DiagMsg = std::string(Builtin->Name) +
": the builtin requires the following SPIR-V "
"extension: SPV_INTEL_media_block_io";
report_fatal_error(DiagMsg.c_str(), false);
} else if (!IntelSubgroups->IsMedia &&
!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
std::string DiagMsg = std::string(Builtin->Name) +
": the builtin requires the following SPIR-V "
"extension: SPV_INTEL_subgroups";
report_fatal_error(DiagMsg.c_str(), false);
}
const SPIRV::IntelSubgroupsBuiltin *IntelSubgroups =
SPIRV::lookupIntelSubgroupsBuiltin(Builtin->Name);

uint32_t OpCode = IntelSubgroups->Opcode;
if (Call->isSpirvOp()) {
bool IsSet = OpCode != SPIRV::OpSubgroupBlockWriteINTEL &&
OpCode != SPIRV::OpSubgroupImageBlockWriteINTEL;
OpCode != SPIRV::OpSubgroupImageBlockWriteINTEL &&
OpCode != SPIRV::OpSubgroupImageMediaBlockWriteINTEL;
return buildOpFromWrapper(MIRBuilder, OpCode, Call,
IsSet ? GR->getSPIRVTypeID(Call->ReturnType)
: Register(0));
Expand Down
24 changes: 19 additions & 5 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -1156,14 +1156,19 @@ class IntelSubgroupsBuiltin<string name, Op operation> {
string Name = name;
Op Opcode = operation;
bit IsBlock = !or(!eq(operation, OpSubgroupBlockReadINTEL),
!eq(operation, OpSubgroupBlockWriteINTEL));
bit IsWrite = !eq(operation, OpSubgroupBlockWriteINTEL);
!eq(operation, OpSubgroupBlockWriteINTEL),
!eq(operation, OpSubgroupImageMediaBlockReadINTEL),
!eq(operation, OpSubgroupImageMediaBlockWriteINTEL));
bit IsWrite = !or(!eq(operation, OpSubgroupBlockWriteINTEL),
!eq(operation, OpSubgroupImageMediaBlockWriteINTEL));
bit IsMedia = !or(!eq(operation, OpSubgroupImageMediaBlockReadINTEL),
!eq(operation, OpSubgroupImageMediaBlockWriteINTEL));
}

// Table gathering all the Intel sub group builtins.
def IntelSubgroupsBuiltins : GenericTable {
let FilterClass = "IntelSubgroupsBuiltin";
let Fields = ["Name", "Opcode", "IsBlock", "IsWrite"];
let Fields = ["Name", "Opcode", "IsBlock", "IsWrite", "IsMedia"];
}

// Function to lookup group builtins by their name and set.
Expand Down Expand Up @@ -1191,17 +1196,24 @@ foreach i = ["", "2", "4", "8"] in {
// cl_intel_subgroups_short
defm : DemangledIntelSubgroupsBuiltin<!strconcat("block_read_ui", i), 1, 2, OpSubgroupBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("block_write_ui", i), 2, 3, OpSubgroupBlockWriteINTEL>;
// cl_intel_media_block_io
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_read", i), 4, 4, OpSubgroupImageMediaBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_read_ui", i), 4, 4, OpSubgroupImageMediaBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_write", i), 5, 5, OpSubgroupImageMediaBlockWriteINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_write_ui", i), 5, 5, OpSubgroupImageMediaBlockWriteINTEL>;
}
// cl_intel_subgroups_char, cl_intel_subgroups_short, cl_intel_subgroups_long
// cl_intel_subgroups_char, cl_intel_subgroups_short, cl_intel_subgroups_long, cl_intel_media_block_io
foreach i = ["", "2", "4", "8", "16"] in {
foreach j = ["c", "s", "l"] in {
defm : DemangledIntelSubgroupsBuiltin<!strconcat("block_read_u", j, i), 1, 2, OpSubgroupBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("block_write_u", j, i), 2, 3, OpSubgroupBlockWriteINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_read_u", j, i), 4, 4, OpSubgroupImageMediaBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltin<!strconcat("media_block_write_u", j, i), 5, 5, OpSubgroupImageMediaBlockWriteINTEL>;
}
}
// OpSubgroupImageBlockReadINTEL and OpSubgroupImageBlockWriteINTEL are to be resolved later on (in code)

// Multiclass used to define builtin wrappers for the SPV_INTEL_subgroups extension.
// Multiclass used to define builtin wrappers for the SPV_INTEL_subgroups and the SPV_INTEL_media_block_io extensions.
multiclass DemangledIntelSubgroupsBuiltinWrapper<string name, bits<8> numArgs, Op operation> {
def : DemangledBuiltin<!strconcat("__spirv_", name), OpenCL_std, IntelSubgroups, numArgs, numArgs>;
def : IntelSubgroupsBuiltin<!strconcat("__spirv_", name), operation>;
Expand All @@ -1215,6 +1227,8 @@ defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupBlockReadINTEL", 1, OpSubg
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupBlockWriteINTEL", 2, OpSubgroupBlockWriteINTEL>;
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageBlockReadINTEL", 2, OpSubgroupImageBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageBlockWriteINTEL", 3, OpSubgroupImageBlockWriteINTEL>;
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageMediaBlockReadINTEL", 4, OpSubgroupImageMediaBlockReadINTEL>;
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageMediaBlockWriteINTEL", 5, OpSubgroupImageMediaBlockWriteINTEL>;

//===----------------------------------------------------------------------===//
// Class defining a builtin for group operations within uniform control flow.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_INTEL_split_barrier},
{"SPV_INTEL_subgroups",
SPIRV::Extension::Extension::SPV_INTEL_subgroups},
{"SPV_INTEL_media_block_io",
SPIRV::Extension::Extension::SPV_INTEL_media_block_io},
{"SPV_KHR_uniform_group_instructions",
SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
{"SPV_KHR_no_integer_wrap_decoration",
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,12 @@ def OpSubgroupImageBlockReadINTEL: Op<5577, (outs ID:$res), (ins TYPE:$type, ID:
def OpSubgroupImageBlockWriteINTEL: Op<5578, (outs), (ins ID:$image, ID:$coordinate, ID:$data),
"OpSubgroupImageBlockWriteINTEL $image $coordinate $data">;

// SPV_INTEL_media_block_io
def OpSubgroupImageMediaBlockReadINTEL: Op<5580, (outs ID:$res), (ins TYPE:$type, ID:$image, ID:$coordinate, ID:$width, ID:$height),
"$res = OpSubgroupImageMediaBlockReadINTEL $type $image $coordinate $width $height">;
def OpSubgroupImageMediaBlockWriteINTEL: Op<5581, (outs), (ins ID:$image, ID:$coordinate, ID:$width, ID:$height, ID:$data),
"OpSubgroupImageMediaBlockWriteINTEL $image $coordinate $width $height $data">;

// - SPV_KHR_uniform_group_instructions
def OpGroupIMulKHR: Op<6401, (outs ID:$res), (ins TYPE:$type, ID:$scope, i32imm:$groupOp, ID:$value),
"$res = OpGroupIMulKHR $type $scope $groupOp $value">;
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,13 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
}
break;
case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
Reqs.addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
}
break;
case SPIRV::OpAssumeTrueKHR:
case SPIRV::OpExpectKHR:
if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ defm RayTracingNV : CapabilityOperand<5340, 0, 0, [], [Shader]>;
defm SubgroupShuffleINTEL : CapabilityOperand<5568, 0, 0, [SPV_INTEL_subgroups], []>;
defm SubgroupBufferBlockIOINTEL : CapabilityOperand<5569, 0, 0, [SPV_INTEL_subgroups], []>;
defm SubgroupImageBlockIOINTEL : CapabilityOperand<5570, 0, 0, [SPV_INTEL_subgroups], []>;
defm SubgroupImageMediaBlockIOINTEL : CapabilityOperand<5579, 0, 0, [], []>;
defm SubgroupImageMediaBlockIOINTEL : CapabilityOperand<5579, 0, 0, [SPV_INTEL_media_block_io], []>;
defm SubgroupAvcMotionEstimationINTEL : CapabilityOperand<5696, 0, 0, [], []>;
defm SubgroupAvcMotionEstimationIntraINTEL : CapabilityOperand<5697, 0, 0, [], []>;
defm SubgroupAvcMotionEstimationChromaINTEL : CapabilityOperand<5698, 0, 0, [], []>;
Expand Down
Loading
Loading