-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[SPIRV] Added support for extension SPV_INTEL_blocking_pipes #131075
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
Conversation
--Added test files for the extesnion SPV_INTEL_blocking_pipes
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-backend-spir-v Author: Aadesh PremKumar (aadeshps-mcw) Changes--Added test files for the extension SPV_INTEL_blocking_pipes Full diff: https://github.com/llvm/llvm-project/pull/131075.diff 7 Files Affected:
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 579e37f68d5d8..d5d2ed3bc92d0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2265,6 +2265,63 @@ static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
return buildBindlessImageINTELInst(Call, Opcode, MIRBuilder, GR);
}
+static bool generateIOPipesInst(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;
+
+ if (Call->Arguments.size() < 4) {
+ llvm::errs() << "Not enough operands for pipe instruction\n";
+ return false;
+ }
+
+ // Retrieve Packet Size and Packet Alignment.
+ // Here we assume that these operands are immediate constants.
+ MachineRegisterInfo *MRI = MIRBuilder.getMRI();
+ Register packet = Call->Arguments[2];
+ Register packetAlignment = Call->Arguments[3];
+
+ // Get definitions
+ MachineInstr *PacketDefMI = MRI->getUniqueVRegDef(packet);
+ MachineInstr *AlignDefMI = MRI->getUniqueVRegDef(packetAlignment);
+
+ // Get types
+ LLT PacketType = MRI->getType(PacketDefMI->getOperand(0).getReg());
+ LLT AlignType = MRI->getType(AlignDefMI->getOperand(0).getReg());
+
+ // Validate types
+ if (!PacketType.isScalar() || PacketType.getSizeInBits() != 32) {
+ llvm::report_fatal_error("Packet Size must be a 32-bit integer scalar!");
+ }
+
+ if (!AlignType.isScalar() || AlignType.getSizeInBits() != 32) {
+ llvm::report_fatal_error(
+ "Packet Alignment must be a 32-bit integer scalar!");
+ }
+
+ // Get constant values
+ const uint32_t PacketSize = getConstFromIntrinsic(packet, MRI);
+ const uint32_t PacketAlignment = getConstFromIntrinsic(packetAlignment, MRI);
+
+ // 1 <= PacketAlignment <= PacketSize
+ // PacketSize must be evenly divisible by PacketAlignment.
+ if (PacketAlignment < 1 || PacketAlignment > PacketSize ||
+ (PacketSize % PacketAlignment != 0)) {
+ llvm::errs() << "Invalid packet size and alignment: "
+ << "PacketSize = " << PacketSize
+ << ", PacketAlignment = " << PacketAlignment << "\n";
+ return false;
+ }
+
+ auto MIB = MIRBuilder.buildInstr(Opcode);
+
+ for (unsigned i = 0; i < Call->Arguments.size(); ++i)
+ MIB.addUse(Call->Arguments[i]);
+ return true;
+}
static bool buildNDRange(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
@@ -2847,6 +2904,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
case SPIRV::BindlessINTEL:
return generateBindlessImageINTELInst(Call.get(), MIRBuilder, GR);
+ case BlockingPipes:
+ return generateIOPipesInst(Call.get(), MIRBuilder, GR);
}
return false;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index c9a5c92ee3a66..fb95eaff90886 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -67,6 +67,7 @@ def CoopMatr : BuiltinGroup;
def ICarryBorrow : BuiltinGroup;
def ExtendedBitOps : BuiltinGroup;
def BindlessINTEL : BuiltinGroup;
+def BlockingPipes : BuiltinGroup;
//===----------------------------------------------------------------------===//
// Class defining a demangled builtin record. The information in the record
@@ -1128,6 +1129,10 @@ defm : DemangledNativeBuiltin<"clock_read_hilo_device", OpenCL_std, KernelClock,
defm : DemangledNativeBuiltin<"clock_read_hilo_work_group", OpenCL_std, KernelClock, 0, 0, OpReadClockKHR>;
defm : DemangledNativeBuiltin<"clock_read_hilo_sub_group", OpenCL_std, KernelClock, 0, 0, OpReadClockKHR>;
+//SPV_INTEL_blocking_pipes
+defm : DemangledNativeBuiltin<"__spirv_WritePipeBlockingINTEL", OpenCL_std, BlockingPipes, 0, 0, OpWritePipeBlockingINTEL>;
+defm : DemangledNativeBuiltin<"__spirv_ReadPipeBlockingINTEL", OpenCL_std, BlockingPipes, 0, 0, OpReadPipeBlockingINTEL>;
+
//===----------------------------------------------------------------------===//
// Class defining an atomic instruction on floating-point numbers.
//
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 8d1714932c3c6..3d9e7514766d2 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -90,7 +90,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
{"SPV_KHR_non_semantic_info",
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
{"SPV_INTEL_long_composites",
- SPIRV::Extension::Extension::SPV_INTEL_long_composites}};
+ SPIRV::Extension::Extension::SPV_INTEL_long_composites},
+ {"SPV_INTEL_blocking_pipes",
+ SPIRV::Extension::Extension::SPV_INTEL_blocking_pipes}};
bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
llvm::StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index a8f862271dbab..0998d28a95829 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -956,3 +956,9 @@ def OpAliasScopeDeclINTEL: Op<5912, (outs ID:$res), (ins ID:$AliasDomain, variab
"$res = OpAliasScopeDeclINTEL $AliasDomain">;
def OpAliasScopeListDeclINTEL: Op<5913, (outs ID:$res), (ins variable_ops),
"$res = OpAliasScopeListDeclINTEL">;
+
+//SPV_INTEL_blocking_pipes
+def OpReadPipeBlockingINTEL :Op<5946, (outs), (ins ID:$pipe, ID:$pointer, ID:$packetSize, ID:$packetAlignment),
+ "OpReadPipeBlockingINTEL $pipe $pointer $packetSize $packetAlignment">;
+def OpWritePipeBlockingINTEL :Op<5946, (outs), (ins ID:$pipe, ID:$pointer, ID:$packetSize, ID:$packetAlignment),
+ "OpWritePipeBlockingINTEL $pipe $pointer $packetSize $packetAlignment">;
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index e0b348f0bba10..b92c77d149e47 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1448,6 +1448,13 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
}
break;
+ case SPIRV::OpReadPipeBlockingINTEL:
+ case SPIRV::OpWritePipeBlockingINTEL:
+ if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_blocking_pipes)) {
+ Reqs.addExtension(SPIRV::Extension::SPV_INTEL_blocking_pipes);
+ Reqs.addCapability(SPIRV::Capability::BlockingPipesINTEL);
+ }
+ break;
case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index a871518e2094c..35d54e97ef675 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -511,6 +511,7 @@ defm FunctionFloatControlINTEL : CapabilityOperand<5821, 0, 0, [SPV_INTEL_float_
defm LongCompositesINTEL : CapabilityOperand<6089, 0, 0, [SPV_INTEL_long_composites], []>;
defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory_access_aliasing], []>;
+defm BlockingPipesINTEL : CapabilityOperand<5945, 0, 0, [SPV_INTEL_blocking_pipes], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_blocking_pipes/PipeBlocking.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_blocking_pipes/PipeBlocking.ll
new file mode 100644
index 0000000000000..adefd31b4d3b5
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_blocking_pipes/PipeBlocking.ll
@@ -0,0 +1,114 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_blocking_pipes %s -o - | FileCheck %s --check-prefixes=CHECK-SPIRV
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_blocking_pipes %s -o - -filetype=obj | spirv-val %}
+
+%opencl.pipe_ro_t = type opaque
+%opencl.pipe_wo_t = type opaque
+
+; CHECK-SPIRV: OpCapability BlockingPipesINTEL
+; CHECK-SPIRV: OpExtension "SPV_INTEL_blocking_pipes"
+; CHECK-SPIRV: %[[PipeRTy:[0-9]+]] = OpTypePipe ReadOnly
+; CHECK-SPIRV: %[[PipeWTy:[0-9]+]] = OpTypePipe WriteOnly
+; CHECK-SPIRV: %[[PipeR1:[0-9]+]] = OpLoad %[[PipeRTy]] %[[#]] Aligned 8
+; CHECK-SPIRV: OpReadPipeBlockingINTEL %[[PipeR1]] %[[#]] %[[#]] %[[#]]
+; CHECK-SPIRV: %[[PipeR2:[0-9]+]] = OpLoad %[[PipeRTy]] %[[#]] Aligned 8
+; CHECK-SPIRV: OpReadPipeBlockingINTEL %[[PipeR2]] %[[#]] %[[#]] %[[#]]
+; CHECK-SPIRV: %[[PipeW1:[0-9]+]] = OpLoad %[[PipeWTy]] %[[#]] Aligned 8
+; CHECK-SPIRV: OpWritePipeBlockingINTEL %[[PipeW1]] %[[#]] %[[#]] %[[#]]
+; CHECK-SPIRV: %[[PipeW2:[0-9]+]] = OpLoad %[[PipeWTy]] %[[#]] Aligned 8
+; CHECK-SPIRV: OpWritePipeBlockingINTEL %[[PipeW2]] %[[#]] %[[#]] %[[#]]
+
+
+; Function Attrs: convergent noinline nounwind optnone
+define spir_func void @foo(target("spirv.Pipe", 0) %p, ptr addrspace(1) %ptr) #0 {
+entry:
+ %p.addr = alloca target("spirv.Pipe", 0), align 8
+ %ptr.addr = alloca ptr addrspace(1), align 8
+ store target("spirv.Pipe", 0) %p, target("spirv.Pipe", 0)* %p.addr, align 8
+ store ptr addrspace(1) %ptr, ptr %ptr.addr, align 8
+ %0 = load target("spirv.Pipe", 0), target("spirv.Pipe", 0)* %p.addr, align 8
+ %1 = load ptr addrspace(1), ptr %ptr.addr, align 8
+ %2 = addrspacecast ptr addrspace(1) %1 to ptr addrspace(4)
+ call spir_func void @_Z29__spirv_ReadPipeBlockingINTELIiEv8ocl_pipePiii(target("spirv.Pipe", 0) %0, ptr addrspace(4) %2, i32 4, i32 4)
+ ret void
+}
+
+declare dso_local spir_func void @_Z29__spirv_ReadPipeBlockingINTELIiEv8ocl_pipePiii(target("spirv.Pipe", 0), ptr addrspace(4), i32, i32)
+
+; Function Attrs: convergent noinline nounwind optnone
+define spir_func void @bar(target("spirv.Pipe", 0) %p, ptr addrspace(1) %ptr) #0 {
+entry:
+ %p.addr = alloca target("spirv.Pipe", 0), align 8
+ %ptr.addr = alloca ptr addrspace(1), align 8
+ store target("spirv.Pipe", 0) %p, target("spirv.Pipe", 0)* %p.addr, align 8
+ store ptr addrspace(1) %ptr, ptr %ptr.addr, align 8
+ %0 = load target("spirv.Pipe", 0), target("spirv.Pipe", 0)* %p.addr, align 8
+ %1 = load ptr addrspace(1), ptr %ptr.addr, align 8
+ %2 = addrspacecast ptr addrspace(1) %1 to ptr addrspace(4)
+ call spir_func void @_Z29__spirv_ReadPipeBlockingINTELIiEv8ocl_pipePvii(target("spirv.Pipe", 0) %0, ptr addrspace(4) %2, i32 4, i32 4)
+ ret void
+}
+
+declare dso_local spir_func void @_Z29__spirv_ReadPipeBlockingINTELIiEv8ocl_pipePvii(target("spirv.Pipe", 0), ptr addrspace(4), i32, i32)
+
+; Function Attrs: convergent noinline nounwind optnone
+define spir_func void @boo(target("spirv.Pipe", 1) %p, ptr addrspace(1) %ptr) #0 {
+entry:
+ %p.addr = alloca target("spirv.Pipe", 1), align 8
+ %ptr.addr = alloca ptr addrspace(1), align 8
+ store target("spirv.Pipe", 1) %p, target("spirv.Pipe", 1)* %p.addr, align 8
+ store ptr addrspace(1) %ptr, ptr %ptr.addr, align 8
+ %0 = load target("spirv.Pipe", 1), target("spirv.Pipe", 1)* %p.addr, align 8
+ %1 = load ptr addrspace(1), ptr %ptr.addr, align 8
+ %2 = addrspacecast ptr addrspace(1) %1 to ptr addrspace(4)
+ call spir_func void @_Z30__spirv_WritePipeBlockingINTELIKiEv8ocl_pipePiii(target("spirv.Pipe", 1) %0, ptr addrspace(4) %2, i32 4, i32 4)
+ ret void
+}
+
+declare dso_local spir_func void @_Z30__spirv_WritePipeBlockingINTELIKiEv8ocl_pipePiii(target("spirv.Pipe", 1), ptr addrspace(4), i32, i32)
+
+; Function Attrs: convergent noinline nounwind optnone
+define spir_func void @baz(target("spirv.Pipe", 1) %p, ptr addrspace(1) %ptr) #0 {
+entry:
+ %p.addr = alloca target("spirv.Pipe", 1), align 8
+ %ptr.addr = alloca ptr addrspace(1), align 8
+ store target("spirv.Pipe", 1) %p, target("spirv.Pipe", 1)* %p.addr, align 8
+ store ptr addrspace(1) %ptr, ptr %ptr.addr, align 8
+ %0 = load target("spirv.Pipe", 1), target("spirv.Pipe", 1)* %p.addr, align 8
+ %1 = load ptr addrspace(1), ptr %ptr.addr, align 8
+ %2 = addrspacecast ptr addrspace(1) %1 to ptr addrspace(4)
+ call spir_func void @_Z30__spirv_WritePipeBlockingINTELIKiEv8ocl_pipePvii(target("spirv.Pipe", 1) %0, ptr addrspace(4) %2, i32 4, i32 4)
+ ret void
+}
+
+declare dso_local spir_func void @_Z30__spirv_WritePipeBlockingINTELIKiEv8ocl_pipePvii(target("spirv.Pipe", 1), ptr addrspace(4), i32, i32)
+
+; CHECK-LLVM: declare spir_func void @__read_pipe_2_bl(ptr addrspace(1), ptr addrspace(4), i32, i32)
+; CHECK-LLVM: declare spir_func void @__write_pipe_2_bl(ptr addrspace(1), ptr addrspace(4), i32, i32)
+
+; Function Attrs: convergent mustprogress norecurse nounwind
+define linkonce_odr dso_local spir_func void @WritePipeBLockingi9Pointer(ptr addrspace(4) align 2 dereferenceable(2) %_Data) {
+entry:
+ %_Data.addr = alloca ptr addrspace(4), align 8
+ %_WPipe = alloca target("spirv.Pipe", 1), align 8
+ %_Data.addr.ascast = addrspacecast ptr %_Data.addr to ptr addrspace(4)
+ %_WPipe.ascast = addrspacecast target("spirv.Pipe", 1)* %_WPipe to target("spirv.Pipe", 1) addrspace(4)*
+ store ptr addrspace(4) %_Data, ptr addrspace(4) %_Data.addr.ascast, align 8
+ %0 = bitcast target("spirv.Pipe", 1)* %_WPipe to ptr
+ %1 = load target("spirv.Pipe", 1), target("spirv.Pipe", 1) addrspace(4)* %_WPipe.ascast, align 8
+ %2 = load ptr addrspace(4), ptr addrspace(4) %_Data.addr.ascast, align 8
+ call spir_func void @_Z30__spirv_WritePipeBlockingINTELIDU9_Ev8ocl_pipePKT_ii(target("spirv.Pipe", 1) %1, ptr addrspace(4) %2, i32 2, i32 2)
+ ret void
+}
+
+declare dso_local spir_func void @_Z30__spirv_WritePipeBlockingINTELIDU9_Ev8ocl_pipePKT_ii(target("spirv.Pipe", 1), ptr addrspace(4), i32, i32)
+
+attributes #0 = { convergent noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0}
+!opencl.ocl.version = !{!1}
+!opencl.spir.version = !{!1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 2, i32 0}
+!2 = !{!"clang version 9.0.0 (https://github.com/MrSidims/llvm.git c627b787284c5bcc917ea9742908baa1b856e176)"}
|
--Added test files for the extension SPV_INTEL_blocking_pipes