Skip to content

Commit 33012ca

Browse files
jcranmer-intelsvenvh
authored andcommitted
Remove more uses of getPointerElementType (part of issue #1444).
This is the easiest tranche of changes: where the pointer element type is usually retrieved by looking a little further afield for the element type, or via scavenging from sret/byval parameters.
1 parent 28fdb7a commit 33012ca

File tree

8 files changed

+58
-58
lines changed

8 files changed

+58
-58
lines changed

lib/SPIRV/OCLToSPIRV.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,23 @@ static size_t getOCLCpp11AtomicMaxNumOps(StringRef Name) {
7070
.Default(0);
7171
}
7272

73+
static Type *getBlockStructType(Value *Parameter) {
74+
// In principle, this information should be passed to us from Clang via
75+
// an elementtype attribute. However, said attribute requires that the
76+
// function call be an intrinsic, which it is not. Instead, we rely on being
77+
// able to trace this to the declaration of a variable: OpenCL C specification
78+
// section 6.12.5 should guarantee that we can do this.
79+
Value *UnderlyingObject = Parameter->stripPointerCasts();
80+
Type *ParamType = nullptr;
81+
if (auto *GV = dyn_cast<GlobalValue>(UnderlyingObject))
82+
ParamType = GV->getValueType();
83+
else if (auto *Alloca = dyn_cast<AllocaInst>(UnderlyingObject))
84+
ParamType = Alloca->getAllocatedType();
85+
else
86+
llvm_unreachable("Blocks in OpenCL C must be traceable to allocation site");
87+
return ParamType;
88+
}
89+
7390
class OCLToSPIRVBase : public InstVisitor<OCLToSPIRVBase> {
7491
public:
7592
OCLToSPIRVBase() : M(nullptr), Ctx(nullptr), CLVer(0) {}
@@ -674,11 +691,9 @@ CallInst *OCLToSPIRVBase::visitCallAtomicCmpXchg(CallInst *CI) {
674691
M, CI,
675692
[&](CallInst *CI, std::vector<Value *> &Args, Type *&RetTy) {
676693
Expected = Args[1]; // temporary save second argument.
677-
Args[1] = new LoadInst(Args[1]->getType()->getPointerElementType(),
678-
Args[1], "exp", false, CI);
679694
RetTy = Args[2]->getType();
680-
assert(Args[0]->getType()->getPointerElementType()->isIntegerTy() &&
681-
Args[1]->getType()->isIntegerTy() &&
695+
Args[1] = new LoadInst(RetTy, Args[1], "exp", false, CI);
696+
assert(Args[1]->getType()->isIntegerTy() &&
682697
Args[2]->getType()->isIntegerTy() &&
683698
"In SPIR-V 1.0 arguments of OpAtomicCompareExchange must be "
684699
"an integer type scalars");
@@ -1584,9 +1599,7 @@ void OCLToSPIRVBase::visitCallEnqueueKernel(CallInst *CI,
15841599
// Param Size: Size of block literal structure
15851600
// Param Aligment: Aligment of block literal structure
15861601
// TODO: these numbers should be obtained from block literal structure
1587-
Type *ParamType = getUnderlyingObject(BlockLiteral)->getType();
1588-
if (PointerType *PT = dyn_cast<PointerType>(ParamType))
1589-
ParamType = PT->getPointerElementType();
1602+
Type *ParamType = getBlockStructType(BlockLiteral);
15901603
Args.push_back(getInt32(M, DL.getTypeStoreSize(ParamType)));
15911604
Args.push_back(getInt32(M, DL.getPrefTypeAlignment(ParamType)));
15921605

@@ -1636,10 +1649,7 @@ void OCLToSPIRVBase::visitCallKernelQuery(CallInst *CI,
16361649
M, CI,
16371650
[=](CallInst *CI, std::vector<Value *> &Args) {
16381651
Value *Param = *Args.rbegin();
1639-
Type *ParamType = getUnderlyingObject(Param)->getType();
1640-
if (PointerType *PT = dyn_cast<PointerType>(ParamType)) {
1641-
ParamType = PT->getPointerElementType();
1642-
}
1652+
Type *ParamType = getBlockStructType(Param);
16431653
// Last arg corresponds to SPIRV Param operand.
16441654
// Insert Invoke in front of Param.
16451655
// Add Param Size and Param Align at the end.

lib/SPIRV/OCLUtil.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,22 +1260,18 @@ class OCLBuiltinFuncMangleInfo : public SPIRV::BuiltinFuncMangleInfo {
12601260
else
12611261
addUnsignedArg(1);
12621262
} else if (NameRef.startswith("intel_sub_group_block_write")) {
1263-
// distinguish write to image and other data types as position
1264-
// of uint argument is different though name is the same.
1265-
auto *Arg0Ty = getArgTy(0);
1266-
if (Arg0Ty->isPointerTy() &&
1267-
Arg0Ty->getPointerElementType()->isIntegerTy()) {
1263+
// distinguish write to image and other data types based on number of
1264+
// arguments--images have one more argument.
1265+
if (F->getFunctionType()->getNumParams() == 2) {
12681266
addUnsignedArg(0);
12691267
addUnsignedArg(1);
12701268
} else {
12711269
addUnsignedArg(2);
12721270
}
12731271
} else if (NameRef.startswith("intel_sub_group_block_read")) {
1274-
// distinguish read from image and other data types as position
1275-
// of uint argument is different though name is the same.
1276-
auto *Arg0Ty = getArgTy(0);
1277-
if (Arg0Ty->isPointerTy() &&
1278-
Arg0Ty->getPointerElementType()->isIntegerTy()) {
1272+
// distinguish read from image and other data types based on number of
1273+
// arguments--images have one more argument.
1274+
if (F->getFunctionType()->getNumParams() == 1) {
12791275
setArgAttr(0, SPIR::ATTR_CONST);
12801276
addUnsignedArg(0);
12811277
}

lib/SPIRV/SPIRVReader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3411,9 +3411,10 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) {
34113411
if (!AnnotStr.empty()) {
34123412
auto *GS = Builder.CreateGlobalStringPtr(AnnotStr);
34133413

3414-
auto GEP = Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I);
3414+
auto *GEP = cast<GetElementPtrInst>(
3415+
Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I));
34153416

3416-
Type *IntTy = GEP->getType()->getPointerElementType()->isIntegerTy()
3417+
Type *IntTy = GEP->getResultElementType()->isIntegerTy()
34173418
? GEP->getType()
34183419
: Int8PtrTyPrivate;
34193420

lib/SPIRV/SPIRVRegularizeLLVM.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -350,41 +350,38 @@ void SPIRVRegularizeLLVMBase::lowerUMulWithOverflow(
350350

351351
void SPIRVRegularizeLLVMBase::expandVEDWithSYCLTypeSRetArg(Function *F) {
352352
auto Attrs = F->getAttributes();
353+
StructType *SRetTy = cast<StructType>(Attrs.getParamStructRetType(0));
353354
Attrs = Attrs.removeParamAttribute(F->getContext(), 0, Attribute::StructRet);
354355
std::string Name = F->getName().str();
355356
CallInst *OldCall = nullptr;
356357
mutateFunction(
357358
F,
358359
[=, &OldCall](CallInst *CI, std::vector<Value *> &Args, Type *&RetTy) {
359360
Args.erase(Args.begin());
360-
auto *SRetPtrTy = cast<PointerType>(CI->getOperand(0)->getType());
361-
auto *ET = SRetPtrTy->getPointerElementType();
362-
RetTy = cast<StructType>(ET)->getElementType(0);
361+
RetTy = SRetTy->getElementType(0);
363362
OldCall = CI;
364363
return Name;
365364
},
366365
[=, &OldCall](CallInst *NewCI) {
367366
IRBuilder<> Builder(OldCall);
368-
auto *SRetPtrTy = cast<PointerType>(OldCall->getOperand(0)->getType());
369-
auto *ET = SRetPtrTy->getPointerElementType();
370-
Value *Target = Builder.CreateStructGEP(ET, OldCall->getOperand(0), 0);
367+
Value *Target =
368+
Builder.CreateStructGEP(SRetTy, OldCall->getOperand(0), 0);
371369
return Builder.CreateStore(NewCI, Target);
372370
},
373371
nullptr, &Attrs, true);
374372
}
375373

376374
void SPIRVRegularizeLLVMBase::expandVIDWithSYCLTypeByValComp(Function *F) {
377375
auto Attrs = F->getAttributes();
376+
auto *CompPtrTy = cast<StructType>(Attrs.getParamByValType(1));
378377
Attrs = Attrs.removeParamAttribute(F->getContext(), 1, Attribute::ByVal);
379378
std::string Name = F->getName().str();
380379
mutateFunction(
381380
F,
382381
[=](CallInst *CI, std::vector<Value *> &Args) {
383-
auto *CompPtrTy = cast<PointerType>(CI->getOperand(1)->getType());
384-
auto *ET = CompPtrTy->getPointerElementType();
385-
Type *HalfTy = cast<StructType>(ET)->getElementType(0);
382+
Type *HalfTy = CompPtrTy->getElementType(0);
386383
IRBuilder<> Builder(CI);
387-
auto *Target = Builder.CreateStructGEP(ET, CI->getOperand(1), 0);
384+
auto *Target = Builder.CreateStructGEP(CompPtrTy, CI->getOperand(1), 0);
388385
Args[1] = Builder.CreateLoad(HalfTy, Target);
389386
return Name;
390387
},
@@ -398,9 +395,8 @@ void SPIRVRegularizeLLVMBase::expandSYCLTypeUsing(Module *M) {
398395
for (auto &F : *M) {
399396
if (F.getName().startswith("_Z28__spirv_VectorExtractDynamic") &&
400397
F.hasStructRetAttr()) {
401-
auto *SRetPtrTy = cast<PointerType>(F.getArg(0)->getType());
402-
if (isSYCLHalfType(SRetPtrTy->getPointerElementType()) ||
403-
isSYCLBfloat16Type(SRetPtrTy->getPointerElementType()))
398+
auto *SRetTy = F.getParamStructRetType(0);
399+
if (isSYCLHalfType(SRetTy) || isSYCLBfloat16Type(SRetTy))
404400
ToExpandVEDWithSYCLTypeSRetArg.push_back(&F);
405401
else
406402
llvm_unreachable("The return type of the VectorExtractDynamic "
@@ -409,8 +405,7 @@ void SPIRVRegularizeLLVMBase::expandSYCLTypeUsing(Module *M) {
409405
}
410406
if (F.getName().startswith("_Z27__spirv_VectorInsertDynamic") &&
411407
F.getArg(1)->getType()->isPointerTy()) {
412-
auto *CompPtrTy = cast<PointerType>(F.getArg(1)->getType());
413-
auto *ET = CompPtrTy->getPointerElementType();
408+
auto *ET = F.getParamByValType(1);
414409
if (isSYCLHalfType(ET) || isSYCLBfloat16Type(ET))
415410
ToExpandVIDWithSYCLTypeByValComp.push_back(&F);
416411
else

lib/SPIRV/SPIRVToOCL12.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ Instruction *SPIRVToOCL12Base::visitCallSPIRVAtomicLoad(CallInst *CI) {
151151
Args.resize(1);
152152
// There is no atomic_load in OpenCL 1.2 spec.
153153
// Emit this builtin via call of atomic_add(*p, 0).
154-
Type *ptrElemTy = Args[0]->getType()->getPointerElementType();
155-
Args.push_back(Constant::getNullValue(ptrElemTy));
156-
return mapAtomicName(OpAtomicIAdd, ptrElemTy);
154+
Type *PtrElemTy = CI->getType();
155+
Args.push_back(Constant::getNullValue(PtrElemTy));
156+
return mapAtomicName(OpAtomicIAdd, PtrElemTy);
157157
},
158158
&Attrs);
159159
}
@@ -165,9 +165,9 @@ Instruction *SPIRVToOCL12Base::visitCallSPIRVAtomicStore(CallInst *CI) {
165165
[=](CallInst *, std::vector<Value *> &Args, Type *&RetTy) {
166166
std::swap(Args[1], Args[3]);
167167
Args.resize(2);
168-
// The type of the value pointed to by Pointer (1st argument)
169-
// must be the same as Result Type.
170-
RetTy = Args[0]->getType()->getPointerElementType();
168+
// The type of the value pointed to by Pointer (1st argument), or the
169+
// value being exchanged (2nd argument) must be the same as Result Type.
170+
RetTy = Args[1]->getType();
171171
return mapAtomicName(OpAtomicExchange, RetTy);
172172
},
173173
[=](CallInst *CI) -> Instruction * { return CI; }, &Attrs);

lib/SPIRV/SPIRVToOCL20.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,7 @@ Instruction *SPIRVToOCL20Base::visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) {
183183
// = 1.
184184
auto Name = OCLSPIRVBuiltinMap::rmap(
185185
OC == OpAtomicIIncrement ? OpAtomicIAdd : OpAtomicISub);
186-
auto Ptr = findFirstPtr(Args);
187-
Type *ValueTy =
188-
cast<PointerType>(Args[Ptr]->getType())->getPointerElementType();
186+
Type *ValueTy = CI->getType();
189187
assert(ValueTy->isIntegerTy());
190188
Args.insert(Args.begin() + 1, llvm::ConstantInt::get(ValueTy, 1));
191189
return Name;
@@ -241,6 +239,8 @@ Instruction *SPIRVToOCL20Base::visitCallSPIRVAtomicCmpExchg(CallInst *CI) {
241239
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
242240
Instruction *PInsertBefore = CI;
243241

242+
Type *MemTy = CI->getType();
243+
244244
return mutateCallInstOCL(
245245
M, CI,
246246
[=](CallInst *, std::vector<Value *> &Args, Type *&RetTy) {
@@ -250,13 +250,12 @@ Instruction *SPIRVToOCL20Base::visitCallSPIRVAtomicCmpExchg(CallInst *CI) {
250250
// OCL built-ins returns boolean value and stores a new/original
251251
// value by pointer passed as 2nd argument (aka expected) while SPIR-V
252252
// instructions returns this new/original value as a resulting value.
253-
AllocaInst *PExpected = new AllocaInst(CI->getType(), 0, "expected",
253+
AllocaInst *PExpected = new AllocaInst(MemTy, 0, "expected",
254254
&(*PInsertBefore->getParent()
255255
->getParent()
256256
->getEntryBlock()
257257
.getFirstInsertionPt()));
258-
PExpected->setAlignment(
259-
Align(CI->getType()->getScalarSizeInBits() / 8));
258+
PExpected->setAlignment(Align(MemTy->getScalarSizeInBits() / 8));
260259
new StoreInst(Args[1], PExpected, PInsertBefore);
261260
unsigned AddrSpc = SPIRAS_Generic;
262261
Type *PtrTyAS = PointerType::getWithSamePointeeType(
@@ -276,9 +275,8 @@ Instruction *SPIRVToOCL20Base::visitCallSPIRVAtomicCmpExchg(CallInst *CI) {
276275
// returning it has to be loaded from the memory where 'expected'
277276
// value is stored. This memory must contain the needed value after a
278277
// call to OCL built-in is completed.
279-
return new LoadInst(
280-
CI->getArgOperand(1)->getType()->getPointerElementType(),
281-
CI->getArgOperand(1), "original", PInsertBefore);
278+
return new LoadInst(MemTy, CI->getArgOperand(1), "original",
279+
PInsertBefore);
282280
},
283281
&Attrs);
284282
}

lib/SPIRV/SPIRVUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,7 @@ bool lowerBuiltinVariableToCall(GlobalVariable *GV,
18591859

18601860
Value *Ptr = LD->getPointerOperand();
18611861

1862-
if (isa<FixedVectorType>(Ptr->getType()->getPointerElementType())) {
1862+
if (isa<FixedVectorType>(LD->getType())) {
18631863
LD->replaceAllUsesWith(Vectors.back());
18641864
} else {
18651865
auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4677,7 +4677,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
46774677
// the original return type.
46784678
if (CI->hasStructRetAttr()) {
46794679
assert(ResTy->isVoidTy() && "Return type is not void");
4680-
ResTy = cast<PointerType>(OpItr->getType())->getPointerElementType();
4680+
ResTy = CI->getParamStructRetType(0);
46814681
OpItr++;
46824682
}
46834683

@@ -4768,7 +4768,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
47684768
// the original return type.
47694769
if (CI->hasStructRetAttr()) {
47704770
assert(ResTy->isVoidTy() && "Return type is not void");
4771-
ResTy = cast<PointerType>(OpItr->getType())->getPointerElementType();
4771+
ResTy = CI->getParamStructRetType(0);
47724772
OpItr++;
47734773
}
47744774

@@ -4845,7 +4845,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
48454845
// the original return type.
48464846
if (CI->hasStructRetAttr()) {
48474847
assert(ResTy->isVoidTy() && "Return type is not void");
4848-
ResTy = cast<PointerType>(OpItr->getType())->getPointerElementType();
4848+
ResTy = CI->getParamStructRetType(0);
48494849
OpItr++;
48504850
}
48514851

@@ -4950,7 +4950,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
49504950
if (!RetTy->isVoidTy()) {
49514951
SPRetTy = transType(RetTy);
49524952
} else if (Args.size() > 0 && F->arg_begin()->hasStructRetAttr()) {
4953-
SPRetTy = transType(F->arg_begin()->getType()->getPointerElementType());
4953+
SPRetTy = transType(F->getParamStructRetType(0));
49544954
Args.erase(Args.begin());
49554955
}
49564956
auto *SPI = SPIRVInstTemplateBase::create(OC);

0 commit comments

Comments
 (0)