Skip to content

Commit 9070904

Browse files
fixes and test cases
1 parent 12a354e commit 9070904

File tree

5 files changed

+97
-70
lines changed

5 files changed

+97
-70
lines changed

llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
316316

317317
if (Arg.hasName())
318318
buildOpName(VRegs[i][0], Arg.getName(), MIRBuilder);
319-
if (isPointerTy(Arg.getType())) {
319+
if (isPointerTyOrWrapper(Arg.getType())) {
320320
auto DerefBytes = static_cast<unsigned>(Arg.getDereferenceableBytes());
321321
if (DerefBytes != 0)
322322
buildOpDecorate(VRegs[i][0], MIRBuilder,

llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class SPIRVEmitIntrinsics
209209
void replaceAllUsesWithAndErase(IRBuilder<> &B, Instruction *Src,
210210
Instruction *Dest, bool DeleteOld = true);
211211

212+
void applyDemangledPtrArgTypes(IRBuilder<> &B);
213+
212214
bool runOnFunction(Function &F);
213215
bool postprocessTypes(Module &M);
214216
bool processFunctionPointers(Module &M);
@@ -2156,6 +2158,53 @@ bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) {
21562158
return true;
21572159
}
21582160

2161+
// Apply types parsed from demangled function declarations.
2162+
void SPIRVEmitIntrinsics::applyDemangledPtrArgTypes(IRBuilder<> &B) {
2163+
for (auto It : FDeclPtrTys) {
2164+
Function *F = It.first;
2165+
for (auto *U : F->users()) {
2166+
CallInst *CI = dyn_cast<CallInst>(U);
2167+
if (!CI || CI->getCalledFunction() != F)
2168+
continue;
2169+
unsigned Sz = CI->arg_size();
2170+
for (auto [Idx, ElemTy] : It.second) {
2171+
if (Idx >= Sz)
2172+
continue;
2173+
Value *Param = CI->getArgOperand(Idx);
2174+
if (GR->findDeducedElementType(Param) || isa<GlobalValue>(Param))
2175+
continue;
2176+
if (Argument *Arg = dyn_cast<Argument>(Param)) {
2177+
if (!hasPointeeTypeAttr(Arg)) {
2178+
B.SetInsertPointPastAllocas(Arg->getParent());
2179+
B.SetCurrentDebugLocation(DebugLoc());
2180+
buildAssignPtr(B, ElemTy, Arg);
2181+
}
2182+
} else if (isa<Instruction>(Param)) {
2183+
GR->addDeducedElementType(Param, ElemTy);
2184+
// insertAssignTypeIntrs() will complete buildAssignPtr()
2185+
} else {
2186+
B.SetInsertPoint(CI->getParent()
2187+
->getParent()
2188+
->getEntryBlock()
2189+
.getFirstNonPHIOrDbgOrAlloca());
2190+
buildAssignPtr(B, ElemTy, Param);
2191+
}
2192+
CallInst *Ref = dyn_cast<CallInst>(Param);
2193+
if (!Ref)
2194+
continue;
2195+
Function *RefF = Ref->getCalledFunction();
2196+
if (!RefF || !isPointerTy(RefF->getReturnType()) ||
2197+
GR->findDeducedElementType(RefF))
2198+
continue;
2199+
GR->addDeducedElementType(RefF, ElemTy);
2200+
GR->addReturnType(
2201+
RefF, TypedPointerType::get(
2202+
ElemTy, getPointerAddressSpace(RefF->getReturnType())));
2203+
}
2204+
}
2205+
}
2206+
}
2207+
21592208
bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
21602209
if (Func.isDeclaration())
21612210
return false;
@@ -2198,33 +2247,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
21982247
for (auto &I : instructions(Func))
21992248
Worklist.push_back(&I);
22002249

2201-
// Apply types parsed from demangled function declarations.
2202-
for (auto It : FDeclPtrTys) {
2203-
Function *F = It.first;
2204-
for (auto *U : F->users()) {
2205-
CallInst *CI = dyn_cast<CallInst>(U);
2206-
if (!CI || CI->getCalledFunction() != F)
2207-
continue;
2208-
unsigned Sz = CI->arg_size();
2209-
for (auto [Idx, ElemTy] : It.second) {
2210-
if (Idx >= Sz)
2211-
continue;
2212-
Value *Arg = CI->getArgOperand(Idx);
2213-
GR->addDeducedElementType(Arg, ElemTy);
2214-
CallInst *Ref = dyn_cast<CallInst>(Arg);
2215-
if (!Ref)
2216-
continue;
2217-
Function *RefF = Ref->getCalledFunction();
2218-
if (!RefF || !isPointerTy(RefF->getReturnType()) ||
2219-
GR->findDeducedElementType(RefF))
2220-
continue;
2221-
GR->addDeducedElementType(RefF, ElemTy);
2222-
GR->addReturnType(
2223-
RefF, TypedPointerType::get(
2224-
ElemTy, getPointerAddressSpace(RefF->getReturnType())));
2225-
}
2226-
}
2227-
}
2250+
applyDemangledPtrArgTypes(B);
22282251

22292252
// Pass forward: use operand to deduce instructions result.
22302253
for (auto &I : Worklist) {
@@ -2344,9 +2367,11 @@ void SPIRVEmitIntrinsics::parseFunDeclarations(Module &M) {
23442367
continue;
23452368
// find pointer arguments
23462369
SmallVector<unsigned> Idxs;
2347-
for (unsigned OpIdx = 0; OpIdx < F.arg_size(); ++OpIdx)
2348-
if (isPointerTy(F.getArg(OpIdx)->getType()))
2370+
for (unsigned OpIdx = 0; OpIdx < F.arg_size(); ++OpIdx) {
2371+
Argument *Arg = F.getArg(OpIdx);
2372+
if (isPointerTy(Arg->getType()) && !hasPointeeTypeAttr(Arg))
23492373
Idxs.push_back(OpIdx);
2374+
}
23502375
if (!Idxs.size())
23512376
continue;
23522377
// parse function arguments
@@ -2361,7 +2386,9 @@ void SPIRVEmitIntrinsics::parseFunDeclarations(Module &M) {
23612386
continue;
23622387
if (Type *ElemTy =
23632388
SPIRV::parseBuiltinCallArgumentType(TypeStrs[Idx].trim(), Ctx))
2364-
FDeclPtrTys[&F].push_back(std::make_pair(Idx, ElemTy));
2389+
if (TypedPointerType::isValidElementType(ElemTy) &&
2390+
!ElemTy->isTargetExtTy())
2391+
FDeclPtrTys[&F].push_back(std::make_pair(Idx, ElemTy));
23652392
}
23662393
}
23672394
}

llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
10221022
SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
10231023
const Type *Ty, MachineIRBuilder &MIRBuilder,
10241024
SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
1025-
if (TypesInProcessing.count(Ty) && !isPointerTy(Ty))
1025+
if (TypesInProcessing.count(Ty) && !isPointerTyOrWrapper(Ty))
10261026
return nullptr;
10271027
TypesInProcessing.insert(Ty);
10281028
SPIRVType *SpirvType = createSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);

llvm/test/CodeGen/SPIRV/opencl/vload2.ll

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
2-
; This test only intends to check the vloadn builtin name resolution.
3-
; The calls to the OpenCL builtins are not valid and will not pass SPIR-V validation.
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
43

54
; CHECK-DAG: %[[#IMPORT:]] = OpExtInstImport "OpenCL.std"
65

6+
; CHECK-DAG: OpName %[[#CALL1:]] "call1"
7+
; CHECK-DAG: OpName %[[#CALL2:]] "call2"
8+
; CHECK-DAG: OpName %[[#CALL3:]] "call3"
9+
; CHECK-DAG: OpName %[[#CALL4:]] "call4"
10+
; CHECK-DAG: OpName %[[#CALL5:]] "call5"
11+
712
; CHECK-DAG: %[[#INT8:]] = OpTypeInt 8 0
813
; CHECK-DAG: %[[#INT16:]] = OpTypeInt 16 0
914
; CHECK-DAG: %[[#INT32:]] = OpTypeInt 32 0
@@ -23,20 +28,20 @@
2328
; CHECK: %[[#OFFSET:]] = OpFunctionParameter %[[#INT64]]
2429

2530
define spir_kernel void @test_fn(i64 %offset, ptr addrspace(1) %address) {
26-
; CHECK: %[[#CASTorPARAMofPTRI8:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT8]]{{.*}}
27-
; CHECK: %[[#]] = OpExtInst %[[#VINT8]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI8]] 2
31+
; CHECK-DAG: %[[#CASTorPARAMofPTRI8:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT8]]{{.*}}
32+
; CHECK-DAG: %[[#CALL1]] = OpExtInst %[[#VINT8]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI8]] 2
2833
%call1 = call spir_func <2 x i8> @_Z6vload2mPU3AS1Kc(i64 %offset, ptr addrspace(1) %address)
29-
; CHECK: %[[#CASTorPARAMofPTRI16:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT16]]{{.*}}
30-
; CHECK: %[[#]] = OpExtInst %[[#VINT16]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI16]] 2
34+
; CHECK-DAG: %[[#CASTorPARAMofPTRI16:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT16]]{{.*}}
35+
; CHECK-DAG: %[[#CALL2]] = OpExtInst %[[#VINT16]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI16]] 2
3136
%call2 = call spir_func <2 x i16> @_Z6vload2mPU3AS1Ks(i64 %offset, ptr addrspace(1) %address)
32-
; CHECK: %[[#CASTorPARAMofPTRI32:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT32]]{{.*}}
33-
; CHECK: %[[#]] = OpExtInst %[[#VINT32]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI32]] 2
37+
; CHECK-DAG: %[[#CASTorPARAMofPTRI32:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT32]]{{.*}}
38+
; CHECK-DAG: %[[#CALL3]] = OpExtInst %[[#VINT32]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI32]] 2
3439
%call3 = call spir_func <2 x i32> @_Z6vload2mPU3AS1Ki(i64 %offset, ptr addrspace(1) %address)
35-
; CHECK: %[[#CASTorPARAMofPTRI64:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT64]]{{.*}}
36-
; CHECK: %[[#]] = OpExtInst %[[#VINT64]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI64]] 2
40+
; CHECK-DAG: %[[#CASTorPARAMofPTRI64:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRINT64]]{{.*}}
41+
; CHECK-DAG: %[[#CALL4]] = OpExtInst %[[#VINT64]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRI64]] 2
3742
%call4 = call spir_func <2 x i64> @_Z6vload2mPU3AS1Kl(i64 %offset, ptr addrspace(1) %address)
38-
; CHECK: %[[#CASTorPARAMofPTRFLOAT:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRFLOAT]]{{.*}}
39-
; CHECK: %[[#]] = OpExtInst %[[#VFLOAT]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRFLOAT]] 2
43+
; CHECK-DAG: %[[#CASTorPARAMofPTRFLOAT:]] = {{OpBitcast|OpFunctionParameter}}{{.*}}%[[#PTRFLOAT]]{{.*}}
44+
; CHECK-DAG: %[[#CALL5]] = OpExtInst %[[#VFLOAT]] %[[#IMPORT]] vloadn %[[#OFFSET]] %[[#CASTorPARAMofPTRFLOAT]] 2
4045
%call5 = call spir_func <2 x float> @_Z6vload2mPU3AS1Kf(i64 %offset, ptr addrspace(1) %address)
4146
ret void
4247
}

llvm/test/CodeGen/SPIRV/transcoding/spirv-event-null.ll

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,20 @@
1313
; CHECK-DAG: %[[#TyChar:]] = OpTypeInt 8 0
1414
; CHECK-DAG: %[[#TyV4:]] = OpTypeVector %[[#TyChar]] 4
1515
; CHECK-DAG: %[[#TyStructV4:]] = OpTypeStruct %[[#TyV4]]
16-
; CHECK-DAG: %[[#TyPtrSV4_W:]] = OpTypePointer Workgroup %[[#TyStructV4]]
1716
; CHECK-DAG: %[[#TyPtrSV4_CW:]] = OpTypePointer CrossWorkgroup %[[#TyStructV4]]
1817
; CHECK-DAG: %[[#TyPtrV4_W:]] = OpTypePointer Workgroup %[[#TyV4]]
1918
; CHECK-DAG: %[[#TyPtrV4_CW:]] = OpTypePointer CrossWorkgroup %[[#TyV4]]
19+
; CHECK-DAG: %[[#TyHalf:]] = OpTypeFloat 16
20+
; CHECK-DAG: %[[#TyHalfV2:]] = OpTypeVector %[[#TyHalf]] 2
21+
; CHECK-DAG: %[[#TyHalfV2_W:]] = OpTypePointer Workgroup %[[#TyHalfV2]]
22+
; CHECK-DAG: %[[#TyHalfV2_CW:]] = OpTypePointer CrossWorkgroup %[[#TyHalfV2]]
2023

2124
; Check correct translation of __spirv_GroupAsyncCopy and target("spirv.Event") zeroinitializer
2225

2326
; CHECK: OpFunction
24-
; CHECK: OpFunctionParameter
25-
; CHECK: %[[#Src:]] = OpFunctionParameter
26-
; CHECK: OpVariable %[[#TyStructPtr]] Function
27-
; CHECK: %[[#EventVar:]] = OpVariable %[[#TyEventPtr]] Function
28-
; CHECK: %[[#Dest:]] = OpInBoundsPtrAccessChain
29-
; CHECK: %[[#CopyRes:]] = OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#Dest]] %[[#Src]] %[[#]] %[[#]] %[[#ConstEvent]]
30-
; CHECK: OpStore %[[#EventVar]] %[[#CopyRes]]
27+
; CHECK: %[[#HalfA1:]] = OpFunctionParameter %[[#TyHalfV2_W:]]
28+
; CHECK: %[[#HalfA2:]] = OpFunctionParameter %[[#TyHalfV2_CW:]]
29+
; CHECK: OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#HalfA1]] %[[#HalfA2]] %[[#]] %[[#]] %[[#ConstEvent]]
3130
; CHECK: OpFunctionEnd
3231

3332
%StructEvent = type { target("spirv.Event") }
@@ -40,6 +39,16 @@ entry:
4039

4140
declare dso_local spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU3AS3Dv2_DF16_PU3AS1KS_mm9ocl_event(i32 noundef, ptr addrspace(3) noundef, ptr addrspace(1) noundef, i64 noundef, i64 noundef, target("spirv.Event"))
4241

42+
; CHECK: OpFunction
43+
; CHECK: OpFunctionParameter
44+
; CHECK: %[[#Src:]] = OpFunctionParameter
45+
; CHECK: OpVariable %[[#TyStructPtr]] Function
46+
; CHECK: %[[#EventVar:]] = OpVariable %[[#TyEventPtr]] Function
47+
; CHECK: %[[#Dest:]] = OpInBoundsPtrAccessChain
48+
; CHECK: %[[#CopyRes:]] = OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#Dest]] %[[#Src]] %[[#]] %[[#]] %[[#ConstEvent]]
49+
; CHECK: OpStore %[[#EventVar]] %[[#CopyRes]]
50+
; CHECK: OpFunctionEnd
51+
4352
define spir_kernel void @foo(ptr addrspace(1) %_arg_out_ptr, ptr addrspace(3) %_arg_local_acc) {
4453
entry:
4554
%var = alloca %StructEvent
@@ -58,33 +67,19 @@ declare dso_local spir_func target("spirv.Event") @_Z22__spirv_GroupAsyncCopyjPU
5867
; and %_arg_Local and %_arg are source/destination arguments in OpGroupAsyncCopy
5968

6069
; CHECK: OpFunction
61-
; CHECK: %[[#BarArg1:]] = OpFunctionParameter %[[#TyPtrSV4_W]]
70+
; CHECK: %[[#BarArg1:]] = OpFunctionParameter %[[#TyPtrV4_W]]
6271
; CHECK: %[[#BarArg2:]] = OpFunctionParameter %[[#TyPtrSV4_CW]]
6372
; CHECK: %[[#EventVarBar:]] = OpVariable %[[#TyStructPtr]] Function
6473
; CHECK: %[[#EventVarBarCasted2:]] = OpBitcast %[[#TyEventPtr]] %[[#EventVarBar]]
65-
; CHECK: %[[#SrcBar:]] = OpInBoundsPtrAccessChain %[[#TyPtrSV4_CW]] %[[#BarArg2]] %[[#]]
66-
; CHECK-DAG: %[[#BarArg1Casted:]] = OpBitcast %[[#TyPtrV4_W]] %[[#BarArg1]]
67-
; CHECK-DAG: %[[#SrcBarCasted:]] = OpBitcast %[[#TyPtrV4_CW]] %[[#SrcBar]]
68-
; CHECK: %[[#ResBar:]] = OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#BarArg1Casted]] %[[#SrcBarCasted]] %[[#]] %[[#]] %[[#ConstEvent]]
74+
; CHECK: %[[#BarArg2Casted:]] = OpBitcast %[[#TyPtrV4_CW]] %[[#BarArg2]]
75+
; CHECK: %[[#SrcBar:]] = OpInBoundsPtrAccessChain %[[#TyPtrV4_CW]] %[[#BarArg2Casted]] %[[#]]
76+
; CHECK: %[[#ResBar:]] = OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#BarArg1]] %[[#SrcBar]] %[[#]] %[[#]] %[[#ConstEvent]]
6977
; CHECK: %[[#EventVarBarCasted:]] = OpBitcast %[[#TyEventPtr]] %[[#EventVarBar]]
7078
; CHECK: OpStore %[[#EventVarBarCasted]] %[[#ResBar]]
7179
; CHECK: %[[#EventVarBarGen:]] = OpPtrCastToGeneric %[[#TyEventPtrGen]] %[[#EventVarBarCasted2]]
7280
; CHECK: OpGroupWaitEvents %[[#]] %[[#]] %[[#EventVarBarGen]]
7381
; CHECK: OpFunctionEnd
7482

75-
; CHECK2: OpFunction
76-
; CHECK2: %[[#BarArg1:]] = OpFunctionParameter %[[#TyPtrSV4_W]]
77-
; CHECK2: %[[#BarArg2:]] = OpFunctionParameter %[[#TyPtrSV4_CW]]
78-
; CHECK2: %[[#EventVarBar:]] = OpVariable %[[#TyEventPtr]] Function
79-
; CHECK2: %[[#SrcBar:]] = OpInBoundsPtrAccessChain %[[#TyPtrSV4_CW]] %[[#BarArg2]] %[[#]]
80-
; CHECK2-DAG: %[[#BarArg1Casted:]] = OpBitcast %[[#TyPtrV4_W]] %[[#BarArg1]]
81-
; CHECK2-DAG: %[[#SrcBarCasted:]] = OpBitcast %[[#TyPtrV4_CW]] %[[#SrcBar]]
82-
; CHECK2: %[[#ResBar:]] = OpGroupAsyncCopy %[[#TyEvent]] %[[#]] %[[#BarArg1Casted]] %[[#SrcBarCasted]] %[[#]] %[[#]] %[[#ConstEvent]]
83-
; CHECK2: OpStore %[[#EventVarBar]] %[[#ResBar]]
84-
; CHECK2: %[[#EventVarBarGen:]] = OpPtrCastToGeneric %[[#TyEventPtrGen]] %[[#EventVarBar]]
85-
; CHECK2: OpGroupWaitEvents %[[#]] %[[#]] %[[#EventVarBarGen]]
86-
; CHECK2: OpFunctionEnd
87-
8883
%Vec4 = type { <4 x i8> }
8984

9085
define spir_kernel void @bar(ptr addrspace(3) %_arg_Local, ptr addrspace(1) readonly %_arg) {

0 commit comments

Comments
 (0)