Skip to content

Commit f0cec1f

Browse files
vmaksimosys-ce-bb
authored andcommitted
Fix translation of __spirv_TaskSequenceGetINTEL (#2418)
This change adds support for void return-type of Get instruction and handles the case when Get instruction has 'sret' parameter. Original commit: KhronosGroup/SPIRV-LLVM-Translator@ee0b5605456a57b
1 parent 4c15e0b commit f0cec1f

File tree

6 files changed

+206
-3
lines changed

6 files changed

+206
-3
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6146,7 +6146,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
61466146
OC = OpAtomicCompareExchange;
61476147
if (isGroupOpCode(OC))
61486148
BM->addCapability(CapabilityGroups);
6149-
switch (OC) {
6149+
switch (static_cast<size_t>(OC)) {
61506150
case OpControlBarrier: {
61516151
auto BArgs = transValue(getArguments(CI), BB);
61526152
return BM->addControlBarrierInst(BArgs[0], BArgs[1], BArgs[2], BB);
@@ -6451,6 +6451,25 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
64516451
return BM->addStoreInst(transValue(CI->getArgOperand(0), BB), APIntInst, {},
64526452
BB);
64536453
}
6454+
case internal::OpTaskSequenceGetINTEL: {
6455+
Type *ResTy = nullptr;
6456+
auto OpItr = CI->value_op_begin();
6457+
6458+
if (CI->hasStructRetAttr()) {
6459+
assert(CI->getType()->isVoidTy() && "Return type is not void");
6460+
ResTy = CI->getParamStructRetType(0);
6461+
OpItr++;
6462+
}
6463+
6464+
SPIRVType *RetTy = ResTy ? transType(ResTy) : transScavengedType(CI);
6465+
auto *TaskSeqGet =
6466+
BM->addTaskSequenceGetINTELInst(RetTy, transValue(*OpItr++, BB), BB);
6467+
6468+
if (!CI->hasStructRetAttr())
6469+
return TaskSeqGet;
6470+
return BM->addStoreInst(transValue(CI->getArgOperand(0), BB), TaskSeqGet,
6471+
{}, BB);
6472+
}
64546473
case OpLoad: {
64556474
std::vector<SPIRVWord> MemoryAccess;
64566475
assert(CI->arg_size() > 0 && "Expected at least 1 operand for OpLoad call");

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ class SPIRVModuleImpl : public SPIRVModule {
269269
SPIRVTypeCooperativeMatrixKHR *
270270
addCooperativeMatrixKHRType(SPIRVType *, std::vector<SPIRVValue *>) override;
271271
SPIRVTypeTaskSequenceINTEL *addTaskSequenceINTELType() override;
272+
SPIRVInstruction *addTaskSequenceGetINTELInst(SPIRVType *, SPIRVValue *,
273+
SPIRVBasicBlock *) override;
272274
SPIRVType *addOpaqueGenericType(Op) override;
273275
SPIRVTypeDeviceEvent *addDeviceEventType() override;
274276
SPIRVTypeQueue *addQueueType() override;
@@ -1053,6 +1055,14 @@ SPIRVTypeTaskSequenceINTEL *SPIRVModuleImpl::addTaskSequenceINTELType() {
10531055
return addType(new SPIRVTypeTaskSequenceINTEL(this, getId()));
10541056
}
10551057

1058+
SPIRVInstruction *SPIRVModuleImpl::addTaskSequenceGetINTELInst(
1059+
SPIRVType *RetTy, SPIRVValue *ObjPtr, SPIRVBasicBlock *BB) {
1060+
return addInstruction(
1061+
SPIRVInstTemplateBase::create(internal::OpTaskSequenceGetINTEL, RetTy,
1062+
getId(), getVec(ObjPtr->getId()), BB, this),
1063+
BB);
1064+
}
1065+
10561066
SPIRVType *SPIRVModuleImpl::addOpaqueGenericType(Op TheOpCode) {
10571067
return addType(new SPIRVTypeOpaqueGeneric(TheOpCode, this, getId()));
10581068
}

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ class SPIRVModule {
266266
virtual SPIRVTypeCooperativeMatrixKHR *
267267
addCooperativeMatrixKHRType(SPIRVType *, std::vector<SPIRVValue *>) = 0;
268268
virtual SPIRVTypeTaskSequenceINTEL *addTaskSequenceINTELType() = 0;
269+
virtual SPIRVInstruction *
270+
addTaskSequenceGetINTELInst(SPIRVType *, SPIRVValue *, SPIRVBasicBlock *) = 0;
269271
virtual SPIRVTypeVoid *addVoidType() = 0;
270272
virtual SPIRVType *addOpaqueGenericType(Op) = 0;
271273
virtual SPIRVTypeDeviceEvent *addDeviceEventType() = 0;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVValue.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ class SPIRVValue : public SPIRVEntry {
111111

112112
void setType(SPIRVType *Ty) {
113113
Type = Ty;
114-
assert(!Ty || !Ty->isTypeVoid() || OpCode == OpFunction);
115-
if (Ty && (!Ty->isTypeVoid() || OpCode == OpFunction))
114+
assert(!Ty || !Ty->isTypeVoid() || OpCode == OpFunction ||
115+
OpCode == internal::OpTaskSequenceGetINTEL);
116+
if (Ty && (!Ty->isTypeVoid() || OpCode == OpFunction ||
117+
OpCode == internal::OpTaskSequenceGetINTEL))
116118
setHasType();
117119
else
118120
setHasNoType();
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; Test translation of __spirv_TaskSequenceGetINTEL with a sret (structure return) parameter.
2+
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_task_sequence -o %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
6+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
7+
8+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
9+
; RUN: llvm-dis %t.rev.bc
10+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
11+
12+
; CHECK-SPIRV: TypeTaskSequenceINTEL [[#TypeTS:]]
13+
; CHECK-SPIRV: TypeStruct [[#TypeStruct:]]
14+
15+
; CHECK-SPIRV: TaskSequenceCreateINTEL [[#TypeTS]] [[#TSCreateId:]]
16+
; CHECK-SPIRV: TaskSequenceGetINTEL [[#TypeStruct]] [[#Get:]] [[#TSCreateId]]
17+
; CHECK-SPIRV: Store [[#]] [[#Get]]
18+
19+
; CHECK-LLVM: %struct.FunctionPacket = type <{ float, i8, [3 x i8] }>
20+
21+
; CHECK-LLVM: %[[TSCreate:[a-z0-9.]+]] = call spir_func target("spirv.TaskSequenceINTEL") @_Z66__spirv_TaskSequenceCreateINTEL_RPU3AS125__spirv_TaskSequenceINTELPiiiii(ptr @_Z4multii, i32 -1, i32 -1, i32 1, i32 32)
22+
; CHECK-LLVM: %[[Var:[a-z0-9.]+]] = alloca %struct.FunctionPacket
23+
; CHECK-LLVM: %[[Ptr:[a-z0-9.]+]] = addrspacecast ptr %[[Var]] to ptr addrspace(4)
24+
; CHECK-LLVM: call spir_func void @_Z28__spirv_TaskSequenceGetINTEL{{.*}}(ptr addrspace(4) sret(%struct.FunctionPacket) %[[Ptr]], target("spirv.TaskSequenceINTEL") %[[TSCreate]])
25+
26+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
27+
target triple = "spir64-unknown-unknown"
28+
29+
$_ZTS8MyKernel = comdat any
30+
31+
%struct.FunctionPacket = type <{ float, i8, [3 x i8] }>
32+
33+
; Function Attrs: convergent mustprogress norecurse nounwind
34+
define weak_odr dso_local spir_kernel void @_ZTS8MyKernel(ptr addrspace(1) noundef align 4 %_arg_in, ptr addrspace(1) noundef align 4 %_arg_res) local_unnamed_addr #0 comdat !srcloc !5 !kernel_arg_buffer_location !6 !sycl_fixed_targets !7 !sycl_kernel_omit_args !8 !stall_enable !9 {
35+
entry:
36+
%call.i1 = call spir_func noundef target("spirv.TaskSequenceINTEL") @_Z31__spirv_TaskSequenceCreateINTELIN4sycl3_V13ext5intel12experimental13task_sequenceIL_Z4multiiENS2_6oneapi12experimental10propertiesISt5tupleIJNS7_14property_valueINS4_13pipelined_keyEJSt17integral_constantIiLin1EEEEENSA_INS4_16fpga_cluster_keyEJSC_INS4_25fpga_cluster_options_enumELSG_1EEEEENSA_INS4_12balanced_keyEJEEENSA_INS4_23invocation_capacity_keyEJSC_IjLj10EEEEENSA_INS4_21response_capacity_keyEJSC_IjLj17EEEEEEEEEEEiJiiEEmPT_PFT0_DpT1_Ejjit(ptr noundef nonnull @_Z4multii, i32 noundef -1, i32 noundef -1, i32 noundef 1, i32 noundef 32) #3
37+
br label %for.body10.i
38+
39+
for.body10.i: ; preds = %entry, %for.body10.i
40+
%i5.0.i9 = phi i32 [ 0, %entry ], [ %inc14.i, %for.body10.i ]
41+
%ref.tmp.i = alloca %struct.FunctionPacket, align 4
42+
%ref.tmp.ascast.i = addrspacecast ptr %ref.tmp.i to ptr addrspace(4)
43+
call spir_func void @_Z28__spirv_TaskSequenceGetINTELI14FunctionPacketET_PN5__spv25__spirv_TaskSequenceINTELE(ptr addrspace(4) dead_on_unwind writable sret(%struct.FunctionPacket) align 4 %ref.tmp.ascast.i, target("spirv.TaskSequenceINTEL") noundef %call.i1) #8
44+
%inc14.i = add nuw nsw i32 %i5.0.i9, 1
45+
%exitcond.not = icmp eq i32 %inc14.i, 16384
46+
br i1 %exitcond.not, label %_ZZ4mainENKUlvE_clEv.exit, label %for.body10.i, !llvm.loop !10
47+
48+
_ZZ4mainENKUlvE_clEv.exit: ; preds = %for.body10.i
49+
ret void
50+
}
51+
52+
; Function Attrs: mustprogress norecurse nounwind
53+
define linkonce_odr dso_local spir_func noundef i32 @_Z4multii(i32 noundef %a, i32 noundef %b) #1 !srcloc !12 {
54+
entry:
55+
%mul = mul nsw i32 %b, %a
56+
ret i32 %mul
57+
}
58+
59+
; Function Attrs: convergent nounwind
60+
declare dso_local spir_func noundef target("spirv.TaskSequenceINTEL") @_Z31__spirv_TaskSequenceCreateINTELIN4sycl3_V13ext5intel12experimental13task_sequenceIL_Z4multiiENS2_6oneapi12experimental10propertiesISt5tupleIJNS7_14property_valueINS4_13pipelined_keyEJSt17integral_constantIiLin1EEEEENSA_INS4_16fpga_cluster_keyEJSC_INS4_25fpga_cluster_options_enumELSG_1EEEEENSA_INS4_12balanced_keyEJEEENSA_INS4_23invocation_capacity_keyEJSC_IjLj10EEEEENSA_INS4_21response_capacity_keyEJSC_IjLj17EEEEEEEEEEEiJiiEEmPT_PFT0_DpT1_Ejjit(ptr noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef zeroext) local_unnamed_addr #2
61+
62+
; Function Attrs: convergent nounwind
63+
declare dso_local spir_func void @_Z28__spirv_TaskSequenceGetINTELI14FunctionPacketET_PN5__spv25__spirv_TaskSequenceINTELE(ptr addrspace(4) dead_on_unwind writable sret(%struct.FunctionPacket) align 4, target("spirv.TaskSequenceINTEL") noundef) local_unnamed_addr #2
64+
65+
attributes #0 = { convergent mustprogress norecurse nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-fpga-cluster"="1" "sycl-module-id"="test.cpp" "sycl-optlevel"="2" "sycl-single-task" "uniform-work-group-size"="true" }
66+
attributes #1 = { mustprogress norecurse nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-optlevel"="2" }
67+
attributes #2 = { convergent nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
68+
attributes #3 = { convergent nounwind }
69+
70+
71+
!opencl.spir.version = !{!0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0}
72+
!spirv.Source = !{!1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1}
73+
!llvm.ident = !{!2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2}
74+
!llvm.module.flags = !{!3, !4}
75+
!sycl.specialization-constants = !{}
76+
!sycl.specialization-constants-default-values = !{}
77+
78+
!0 = !{i32 1, i32 2}
79+
!1 = !{i32 4, i32 100000}
80+
!2 = !{!"clang version 18.0.0git (https://github.com/bowenxue-intel/llvm.git bb1121cb47589e94ab65b81971a298b9d2c21ff6)"}
81+
!3 = !{i32 1, !"wchar_size", i32 4}
82+
!4 = !{i32 7, !"frame-pointer", i32 2}
83+
!5 = !{i32 5445863}
84+
!6 = !{i32 -1, i32 -1}
85+
!7 = !{}
86+
!8 = !{i1 false, i1 false}
87+
!9 = !{i1 true}
88+
!10 = distinct !{!10, !11}
89+
!11 = !{!"llvm.loop.mustprogress"}
90+
!12 = !{i32 5445350}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
; Test translation of __spirv_TaskSequenceGetINTEL with void return type.
2+
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_task_sequence -o %t.spv
5+
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
6+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
7+
8+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
9+
; RUN: llvm-dis %t.rev.bc
10+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
11+
12+
; CHECK-SPIRV: TypeVoid [[#VoidTy:]]
13+
; CHECK-SPIRV: TypeTaskSequenceINTEL [[#TypeTS:]]
14+
15+
; CHECK-SPIRV: TaskSequenceCreateINTEL [[#TypeTS]] [[#TSCreateId:]]
16+
; CHECK-SPIRV: TaskSequenceGetINTEL [[#VoidTy]] [[#]] [[#TSCreateId]]
17+
18+
; CHECK-LLVM: %[[TSCreate:[a-z0-9.]+]] = call spir_func target("spirv.TaskSequenceINTEL") @_Z66__spirv_TaskSequenceCreateINTEL_RPU3AS125__spirv_TaskSequenceINTELPiiiii(ptr @_Z4multii, i32 -1, i32 -1, i32 1, i32 32)
19+
; CHECK-LLVM: call spir_func void @_Z28__spirv_TaskSequenceGetINTELPU3AS125__spirv_TaskSequenceINTEL(target("spirv.TaskSequenceINTEL") %[[TSCreate]])
20+
21+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
22+
target triple = "spir64-unknown-unknown"
23+
24+
$_ZTS8MyKernel = comdat any
25+
26+
; Function Attrs: convergent mustprogress norecurse nounwind
27+
define weak_odr dso_local spir_kernel void @_ZTS8MyKernel(ptr addrspace(1) noundef align 4 %_arg_in, ptr addrspace(1) noundef align 4 %_arg_res) local_unnamed_addr #0 comdat !srcloc !5 !kernel_arg_buffer_location !6 !sycl_fixed_targets !7 !sycl_kernel_omit_args !8 !stall_enable !9 {
28+
entry:
29+
%call.i1 = call spir_func noundef target("spirv.TaskSequenceINTEL") @_Z31__spirv_TaskSequenceCreateINTELIN4sycl3_V13ext5intel12experimental13task_sequenceIL_Z4multiiENS2_6oneapi12experimental10propertiesISt5tupleIJNS7_14property_valueINS4_13pipelined_keyEJSt17integral_constantIiLin1EEEEENSA_INS4_16fpga_cluster_keyEJSC_INS4_25fpga_cluster_options_enumELSG_1EEEEENSA_INS4_12balanced_keyEJEEENSA_INS4_23invocation_capacity_keyEJSC_IjLj10EEEEENSA_INS4_21response_capacity_keyEJSC_IjLj17EEEEEEEEEEEiJiiEEmPT_PFT0_DpT1_Ejjit(ptr noundef nonnull @_Z4multii, i32 noundef -1, i32 noundef -1, i32 noundef 1, i32 noundef 32) #3
30+
br label %for.body10.i
31+
32+
for.body10.i: ; preds = %entry, %for.body10.i
33+
%i5.0.i9 = phi i32 [ 0, %entry ], [ %inc14.i, %for.body10.i ]
34+
tail call spir_func void @_Z28__spirv_TaskSequenceGetINTELIiET_m(target("spirv.TaskSequenceINTEL") noundef %call.i1) #3
35+
%inc14.i = add nuw nsw i32 %i5.0.i9, 1
36+
%exitcond.not = icmp eq i32 %inc14.i, 16384
37+
br i1 %exitcond.not, label %_ZZ4mainENKUlvE_clEv.exit, label %for.body10.i, !llvm.loop !10
38+
39+
_ZZ4mainENKUlvE_clEv.exit: ; preds = %for.body10.i
40+
ret void
41+
}
42+
43+
; Function Attrs: mustprogress norecurse nounwind
44+
define linkonce_odr dso_local spir_func noundef i32 @_Z4multii(i32 noundef %a, i32 noundef %b) #1 !srcloc !12 {
45+
entry:
46+
%mul = mul nsw i32 %b, %a
47+
ret i32 %mul
48+
}
49+
50+
; Function Attrs: convergent nounwind
51+
declare dso_local spir_func noundef target("spirv.TaskSequenceINTEL") @_Z31__spirv_TaskSequenceCreateINTELIN4sycl3_V13ext5intel12experimental13task_sequenceIL_Z4multiiENS2_6oneapi12experimental10propertiesISt5tupleIJNS7_14property_valueINS4_13pipelined_keyEJSt17integral_constantIiLin1EEEEENSA_INS4_16fpga_cluster_keyEJSC_INS4_25fpga_cluster_options_enumELSG_1EEEEENSA_INS4_12balanced_keyEJEEENSA_INS4_23invocation_capacity_keyEJSC_IjLj10EEEEENSA_INS4_21response_capacity_keyEJSC_IjLj17EEEEEEEEEEEiJiiEEmPT_PFT0_DpT1_Ejjit(ptr noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef zeroext) local_unnamed_addr #2
52+
53+
; Function Attrs: convergent nounwind
54+
declare dso_local spir_func void @_Z28__spirv_TaskSequenceGetINTELIiET_m(target("spirv.TaskSequenceINTEL") noundef) local_unnamed_addr #2
55+
56+
attributes #0 = { convergent mustprogress norecurse nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-fpga-cluster"="1" "sycl-module-id"="test.cpp" "sycl-optlevel"="2" "sycl-single-task" "uniform-work-group-size"="true" }
57+
attributes #1 = { mustprogress norecurse nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-optlevel"="2" }
58+
attributes #2 = { convergent nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
59+
attributes #3 = { convergent nounwind }
60+
61+
!opencl.spir.version = !{!0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0}
62+
!spirv.Source = !{!1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1}
63+
!llvm.ident = !{!2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2}
64+
!llvm.module.flags = !{!3, !4}
65+
!sycl.specialization-constants = !{}
66+
!sycl.specialization-constants-default-values = !{}
67+
68+
!0 = !{i32 1, i32 2}
69+
!1 = !{i32 4, i32 100000}
70+
!2 = !{!"clang version 18.0.0git (https://github.com/bowenxue-intel/llvm.git bb1121cb47589e94ab65b81971a298b9d2c21ff6)"}
71+
!3 = !{i32 1, !"wchar_size", i32 4}
72+
!4 = !{i32 7, !"frame-pointer", i32 2}
73+
!5 = !{i32 5445863}
74+
!6 = !{i32 -1, i32 -1}
75+
!7 = !{}
76+
!8 = !{i1 false, i1 false}
77+
!9 = !{i1 true}
78+
!10 = distinct !{!10, !11}
79+
!11 = !{!"llvm.loop.mustprogress"}
80+
!12 = !{i32 5445350}

0 commit comments

Comments
 (0)