Skip to content

Commit 56988bb

Browse files
authored
Fix SPIR-V friendly IR for OpGroupAsyncCopy and OpGroupWaitEvents (#963)
These instructions were translated directly to OCL even if SPIR-V friendly LLVM IR was requested.
1 parent 6b29cc6 commit 56988bb

File tree

5 files changed

+61
-16
lines changed

5 files changed

+61
-16
lines changed

lib/SPIRV/SPIRVReader.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,8 @@ bool SPIRVToLLVM::isSPIRVCmpInstTransToLLVMInst(SPIRVInstruction *BI) const {
684684
return isCmpOpCode(OC) && !(OC >= OpLessOrGreater && OC <= OpUnordered);
685685
}
686686

687+
// TODO: Instead of direct translation to OCL we should always produce SPIR-V
688+
// friendly IR and apply lowering later if needed
687689
bool SPIRVToLLVM::isDirectlyTranslatedToOCL(Op OpCode) const {
688690
if (isSubgroupAvcINTELInstructionOpCode(OpCode) ||
689691
isIntelSubgroupOpCode(OpCode))
@@ -696,7 +698,8 @@ bool SPIRVToLLVM::isDirectlyTranslatedToOCL(Op OpCode) const {
696698
// clang-consistent format in SPIRVToOCL pass.
697699
return !(isAtomicOpCode(OpCode) || isGroupOpCode(OpCode) ||
698700
isGroupNonUniformOpcode(OpCode) || isPipeOpCode(OpCode) ||
699-
isMediaBlockINTELOpcode(OpCode));
701+
isMediaBlockINTELOpcode(OpCode) || OpCode == OpGroupAsyncCopy ||
702+
OpCode == OpGroupWaitEvents);
700703
}
701704
return false;
702705
}

lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ void SPIRVToOCL::visitCallInst(CallInst &CI) {
9393
visitCallSPIRVCvtBuiltin(&CI, OC, DemangledName);
9494
return;
9595
}
96+
if (OC == OpGroupAsyncCopy) {
97+
visitCallAsyncWorkGroupCopy(&CI, OC);
98+
return;
99+
}
100+
if (OC == OpGroupWaitEvents) {
101+
visitCallGroupWaitEvents(&CI, OC);
102+
return;
103+
}
96104
if (OCLSPIRVBuiltinMap::rfind(OC))
97105
visitCallSPIRVBuiltin(&CI, OC);
98106
}
@@ -529,6 +537,32 @@ void SPIRVToOCL::visitCallSPIRVCvtBuiltin(CallInst *CI, Op OC,
529537
&Attrs);
530538
}
531539

540+
void SPIRVToOCL::visitCallAsyncWorkGroupCopy(CallInst *CI, Op OC) {
541+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
542+
mutateCallInstOCL(
543+
M, CI,
544+
[=](CallInst *, std::vector<Value *> &Args) {
545+
// First argument of AsyncWorkGroupCopy instruction is Scope, OCL
546+
// built-in async_work_group_strided_copy doesn't have this argument
547+
Args.erase(Args.begin());
548+
return OCLSPIRVBuiltinMap::rmap(OC);
549+
},
550+
&Attrs);
551+
}
552+
553+
void SPIRVToOCL::visitCallGroupWaitEvents(CallInst *CI, Op OC) {
554+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
555+
mutateCallInstOCL(
556+
M, CI,
557+
[=](CallInst *, std::vector<Value *> &Args) {
558+
// First argument of GroupWaitEvents instruction is Scope, OCL
559+
// built-in wait_group_events doesn't have this argument
560+
Args.erase(Args.begin());
561+
return OCLSPIRVBuiltinMap::rmap(OC);
562+
},
563+
&Attrs);
564+
}
565+
532566
void SPIRVToOCL::visitCallSPIRVBuiltin(CallInst *CI, Op OC) {
533567
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
534568
mutateCallInstOCL(

lib/SPIRV/SPIRVToOCL.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ class SPIRVToOCL : public ModulePass, public InstVisitor<SPIRVToOCL> {
104104
/// convert_uchar2_sat(int2)
105105
void visitCallSPIRVCvtBuiltin(CallInst *CI, Op OC, StringRef DemangledName);
106106

107+
/// Transform
108+
/// __spirv_AsyncGroupCopy(ScopeWorkGroup, dst, src, n, stride, event)
109+
/// => async_work_group_strided_copy(dst, src, n, stride, event)
110+
void visitCallAsyncWorkGroupCopy(CallInst *CI, Op OC);
111+
112+
/// Transform __spirv_GroupWaitEvents(Scope, NumEvents, EventsList)
113+
/// => wait_group_events(NumEvents, EventsList)
114+
void visitCallGroupWaitEvents(CallInst *CI, Op OC);
115+
107116
/// Transform __spirv_* builtins to OCL 2.0 builtins.
108117
/// No change with arguments.
109118
void visitCallSPIRVBuiltin(CallInst *CI, Op OC);

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -298,35 +298,23 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
298298
: getValue(Ops[I]);
299299
}
300300

301-
// Get the offset of operands.
302-
// Some instructions skip literals when returning operands.
303-
size_t getOperandOffset() const {
304-
if (hasExecScope() && !isGroupOpCode(OpCode) && !isPipeOpCode(OpCode))
305-
return 1;
306-
return 0;
307-
}
308-
309-
// Get operands which are values.
310-
// Drop execution scope and group operation literals.
311-
// Return other literals as uint32 constants.
312301
std::vector<SPIRVValue *> getOperands() override {
313302
std::vector<SPIRVValue *> VOps;
314-
auto Offset = getOperandOffset();
315-
for (size_t I = 0, E = Ops.size() - Offset; I != E; ++I)
303+
for (size_t I = 0, E = Ops.size(); I != E; ++I)
316304
VOps.push_back(getOperand(I));
317305
return VOps;
318306
}
319307

320308
std::vector<SPIRVEntry *> getNonLiteralOperands() const override {
321309
std::vector<SPIRVEntry *> Operands;
322-
for (size_t I = getOperandOffset(), E = Ops.size(); I < E; ++I)
310+
for (size_t I = 0, E = Ops.size(); I < E; ++I)
323311
if (!isOperandLiteral(I))
324312
Operands.push_back(getEntry(Ops[I]));
325313
return Operands;
326314
}
327315

328316
virtual SPIRVValue *getOperand(unsigned I) {
329-
return getOpValue(I + getOperandOffset());
317+
return getOpValue(I);
330318
}
331319

332320
bool hasExecScope() const { return SPIRV::hasExecScope(OpCode); }
@@ -2379,6 +2367,7 @@ class SPIRVGroupAsyncCopy : public SPIRVInstruction {
23792367
SPIRVValue *getEvent() const { return getValue(Event); }
23802368
std::vector<SPIRVValue *> getOperands() override {
23812369
std::vector<SPIRVId> Operands;
2370+
Operands.push_back(ExecScope);
23822371
Operands.push_back(Destination);
23832372
Operands.push_back(Source);
23842373
Operands.push_back(NumElements);

test/transcoding/OpGroupAsyncCopy.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,18 @@
44
; RUN: llvm-spirv %t.bc -o %t.spv
55
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
66
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
7+
; RUN: llvm-spirv -r --spirv-target-env=SPV-IR %t.spv -o %t.rev.bc
8+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-SPV-IR
79

810
; CHECK-LLVM: call spir_func %opencl.event_t{{.*}}* @_Z29async_work_group_strided_copyPU3AS1Dv2_hPU3AS3KS_jj9ocl_event(
11+
; CHECK-LLVM: call spir_func void @_Z17wait_group_eventsiPU3AS49ocl_event(
12+
; CHECK-LLVM: declare spir_func %opencl.event_t* @_Z29async_work_group_strided_copyPU3AS1Dv2_hPU3AS3KS_jj9ocl_event(<2 x i8> addrspace(1)*, <2 x i8> addrspace(3)*, i32, i32, %opencl.event_t*)
13+
; CHECK-LLVM: declare spir_func void @_Z17wait_group_eventsiPU3AS49ocl_event(i32, %opencl.event_t* addrspace(4)*)
14+
15+
; CHECK-SPV-IR: call spir_func %opencl.event_t{{.*}}* @_Z22__spirv_GroupAsyncCopyiPU3AS1Dv2_cPU3AS3S_ii9ocl_event(i32 2
16+
; CHECK-SPV-IR: call spir_func void @_Z23__spirv_GroupWaitEventsiiPU3AS49ocl_event(i32 2
17+
; CHECK-SPV-IR: declare spir_func %opencl.event_t* @_Z22__spirv_GroupAsyncCopyiPU3AS1Dv2_cPU3AS3S_ii9ocl_event(i32, <2 x i8> addrspace(1)*, <2 x i8> addrspace(3)*, i32, i32, %opencl.event_t*)
18+
; CHECK-SPV-IR: declare spir_func void @_Z23__spirv_GroupWaitEventsiiPU3AS49ocl_event(i32, i32, %opencl.event_t* addrspace(4)*)
919

1020
; CHECK-SPIRV-DAG: GroupAsyncCopy {{[0-9]+}} {{[0-9]+}} [[Scope:[0-9]+]]
1121
; CHECK-SPIRV-DAG: Constant {{[0-9]+}} [[Scope]]

0 commit comments

Comments
 (0)