Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Type *SPIRVEmitIntrinsics::reconstructType(Value *Op, bool UnknownElemTypeI8,

void SPIRVEmitIntrinsics::buildAssignType(IRBuilder<> &B, Type *Ty,
Value *Arg) {
Value *OfType = PoisonValue::get(Ty);
Value *OfType = getNormalizedPoisonValue(Ty);
CallInst *AssignCI = nullptr;
if (Arg->getType()->isAggregateType() && Ty->isAggregateType() &&
allowEmitFakeUse(Arg)) {
Expand All @@ -447,6 +447,7 @@ void SPIRVEmitIntrinsics::buildAssignType(IRBuilder<> &B, Type *Ty,

void SPIRVEmitIntrinsics::buildAssignPtr(IRBuilder<> &B, Type *ElemTy,
Value *Arg) {
ElemTy = normalizeType(ElemTy);
Value *OfType = PoisonValue::get(ElemTy);
CallInst *AssignPtrTyCI = GR->findAssignPtrTypeInstr(Arg);
if (AssignPtrTyCI == nullptr ||
Expand All @@ -470,7 +471,7 @@ void SPIRVEmitIntrinsics::updateAssignType(CallInst *AssignCI, Value *Arg,
return;

// update association with the pointee type
Type *ElemTy = OfType->getType();
Type *ElemTy = normalizeType(OfType->getType());
GR->addDeducedElementType(AssignCI, ElemTy);
GR->addDeducedElementType(Arg, ElemTy);
}
Expand All @@ -490,7 +491,7 @@ CallInst *SPIRVEmitIntrinsics::buildSpvPtrcast(Function *F, Value *Op,
}
Type *OpTy = Op->getType();
SmallVector<Type *, 2> Types = {OpTy, OpTy};
SmallVector<Value *, 2> Args = {Op, buildMD(PoisonValue::get(ElemTy)),
SmallVector<Value *, 2> Args = {Op, buildMD(getNormalizedPoisonValue(ElemTy)),
B.getInt32(getPointerAddressSpace(OpTy))};
CallInst *PtrCasted =
B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
Expand Down Expand Up @@ -766,7 +767,7 @@ Type *SPIRVEmitIntrinsics::deduceElementTypeHelper(
// remember the found relationship
if (Ty && !IgnoreKnownType) {
// specify nested types if needed, otherwise return unchanged
GR->addDeducedElementType(I, Ty);
GR->addDeducedElementType(I, normalizeType(Ty));
}

return Ty;
Expand Down Expand Up @@ -852,7 +853,7 @@ Type *SPIRVEmitIntrinsics::deduceNestedTypeHelper(
}
if (Ty != OpTy) {
Type *NewTy = VectorType::get(Ty, VecTy->getElementCount());
GR->addDeducedCompositeType(U, NewTy);
GR->addDeducedCompositeType(U, normalizeType(NewTy));
return NewTy;
}
}
Expand Down Expand Up @@ -990,6 +991,7 @@ bool SPIRVEmitIntrinsics::deduceOperandElementTypeFunctionRet(
if (KnownElemTy)
return false;
if (Type *OpElemTy = GR->findDeducedElementType(Op)) {
OpElemTy = normalizeType(OpElemTy);
GR->addDeducedElementType(F, OpElemTy);
GR->addReturnType(
F, TypedPointerType::get(OpElemTy,
Expand All @@ -1002,7 +1004,7 @@ bool SPIRVEmitIntrinsics::deduceOperandElementTypeFunctionRet(
continue;
if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(CI)) {
if (Type *PrevElemTy = GR->findDeducedElementType(CI)) {
updateAssignType(AssignCI, CI, PoisonValue::get(OpElemTy));
updateAssignType(AssignCI, CI, getNormalizedPoisonValue(OpElemTy));
propagateElemType(CI, PrevElemTy, VisitedSubst);
}
}
Expand Down Expand Up @@ -1162,11 +1164,11 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
Type *Ty = AskTy ? AskTy : GR->findDeducedElementType(Op);
if (Ty == KnownElemTy)
continue;
Value *OpTyVal = PoisonValue::get(KnownElemTy);
Value *OpTyVal = getNormalizedPoisonValue(KnownElemTy);
Type *OpTy = Op->getType();
if (!Ty || AskTy || isUntypedPointerTy(Ty) || isTodoType(Op)) {
Type *PrevElemTy = GR->findDeducedElementType(Op);
GR->addDeducedElementType(Op, KnownElemTy);
GR->addDeducedElementType(Op, normalizeType(KnownElemTy));
// check if KnownElemTy is complete
if (!Uncomplete)
eraseTodoType(Op);
Expand Down Expand Up @@ -1492,7 +1494,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeTargetExt(

// Our previous guess about the type seems to be wrong, let's update
// inferred type according to a new, more precise type information.
updateAssignType(AssignCI, V, PoisonValue::get(AssignedType));
updateAssignType(AssignCI, V, getNormalizedPoisonValue(AssignedType));
}

void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
Expand All @@ -1507,7 +1509,7 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
return;

setInsertPointSkippingPhis(B, I);
Value *ExpectedElementVal = PoisonValue::get(ExpectedElementType);
Value *ExpectedElementVal = getNormalizedPoisonValue(ExpectedElementType);
MetadataAsValue *VMD = buildMD(ExpectedElementVal);
unsigned AddressSpace = getPointerAddressSpace(Pointer->getType());
bool FirstPtrCastOrAssignPtrType = true;
Expand Down Expand Up @@ -1653,7 +1655,7 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
if (!ElemTy) {
ElemTy = getPointeeTypeByCallInst(DemangledName, CalledF, OpIdx);
if (ElemTy) {
GR->addDeducedElementType(CalledArg, ElemTy);
GR->addDeducedElementType(CalledArg, normalizeType(ElemTy));
} else {
for (User *U : CalledArg->users()) {
if (Instruction *Inst = dyn_cast<Instruction>(U)) {
Expand Down Expand Up @@ -1704,6 +1706,11 @@ void SPIRVEmitIntrinsics::insertPtrCastOrAssignTypeInstr(Instruction *I,
}

Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
// If it's a <1 x Type> vector type, don't modify it. It's not a legal vector
// type in LLT and IRTranslator will replace it by the scalar.
if (isVector1(I.getType()))
return &I;

SmallVector<Type *, 4> Types = {I.getType(), I.getOperand(0)->getType(),
I.getOperand(1)->getType(),
I.getOperand(2)->getType()};
Expand All @@ -1717,6 +1724,11 @@ Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {

Instruction *
SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
// If it's a <1 x Type> vector type, don't modify it. It's not a legal vector
// type in LLT and IRTranslator will replace it by the scalar.
if (isVector1(I.getVectorOperandType()))
return &I;

IRBuilder<> B(I.getParent());
B.SetInsertPoint(&I);
SmallVector<Type *, 3> Types = {I.getType(), I.getVectorOperandType(),
Expand Down Expand Up @@ -1984,8 +1996,9 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
Type *ElemTy = GR->findDeducedElementType(Op);
buildAssignPtr(B, ElemTy ? ElemTy : deduceElementType(Op, true), Op);
} else {
CallInst *AssignCI = buildIntrWithMD(Intrinsic::spv_assign_type,
{OpTy}, Op, Op, {}, B);
CallInst *AssignCI =
buildIntrWithMD(Intrinsic::spv_assign_type, {OpTy},
getNormalizedPoisonValue(OpTy), Op, {}, B);
GR->addAssignPtrTypeInstr(Op, AssignCI);
}
}
Expand Down Expand Up @@ -2034,7 +2047,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
Type *OpTy = Op->getType();
Value *OpTyVal = Op;
if (OpTy->isTargetExtTy())
OpTyVal = PoisonValue::get(OpTy);
OpTyVal = getNormalizedPoisonValue(OpTy);
CallInst *NewOp =
buildIntrWithMD(Intrinsic::spv_track_constant,
{OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
Expand All @@ -2045,7 +2058,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
SmallVector<Type *, 2> Types = {OpTy, OpTy};
SmallVector<Value *, 2> Args = {
NewOp, buildMD(PoisonValue::get(OpElemTy)),
NewOp, buildMD(getNormalizedPoisonValue(OpElemTy)),
B.getInt32(getPointerAddressSpace(OpTy))};
CallInst *PtrCasted =
B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
Expand Down Expand Up @@ -2178,7 +2191,7 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
if (!ElemTy && (ElemTy = deduceFunParamElementType(F, OpIdx)) != nullptr) {
if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(Arg)) {
DenseSet<std::pair<Value *, Value *>> VisitedSubst;
updateAssignType(AssignCI, Arg, PoisonValue::get(ElemTy));
updateAssignType(AssignCI, Arg, getNormalizedPoisonValue(ElemTy));
propagateElemType(Arg, IntegerType::getInt8Ty(F->getContext()),
VisitedSubst);
} else {
Expand Down Expand Up @@ -2232,7 +2245,7 @@ bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) {
continue;
if (II->getIntrinsicID() == Intrinsic::spv_assign_ptr_type ||
II->getIntrinsicID() == Intrinsic::spv_ptrcast) {
updateAssignType(II, &F, PoisonValue::get(FPElemTy));
updateAssignType(II, &F, getNormalizedPoisonValue(FPElemTy));
break;
}
}
Expand All @@ -2256,7 +2269,7 @@ bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) {
for (Function *F : Worklist) {
SmallVector<Value *> Args;
for (const auto &Arg : F->args())
Args.push_back(PoisonValue::get(Arg.getType()));
Args.push_back(getNormalizedPoisonValue(Arg.getType()));
IRB.CreateCall(F, Args);
}
IRB.CreateRetVoid();
Expand Down Expand Up @@ -2286,7 +2299,7 @@ void SPIRVEmitIntrinsics::applyDemangledPtrArgTypes(IRBuilder<> &B) {
buildAssignPtr(B, ElemTy, Arg);
}
} else if (isa<Instruction>(Param)) {
GR->addDeducedElementType(Param, ElemTy);
GR->addDeducedElementType(Param, normalizeType(ElemTy));
// insertAssignTypeIntrs() will complete buildAssignPtr()
} else {
B.SetInsertPoint(CI->getParent()
Expand All @@ -2302,6 +2315,7 @@ void SPIRVEmitIntrinsics::applyDemangledPtrArgTypes(IRBuilder<> &B) {
if (!RefF || !isPointerTy(RefF->getReturnType()) ||
GR->findDeducedElementType(RefF))
continue;
ElemTy = normalizeType(ElemTy);
GR->addDeducedElementType(RefF, ElemTy);
GR->addReturnType(
RefF, TypedPointerType::get(
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,28 @@ inline const Type *unifyPtrType(const Type *Ty) {
return toTypedPointer(const_cast<Type *>(Ty));
}

inline bool isVector1(Type *Ty) {
auto *FVTy = dyn_cast<FixedVectorType>(Ty);
return FVTy && FVTy->getNumElements() == 1;
}

// Modify an LLVM type to conform with future transformations in IRTranslator.
// At the moment use cases comprise only a <1 x Type> vector. To extend when/if
// needed.
inline Type *normalizeType(Type *Ty) {
auto *FVTy = dyn_cast<FixedVectorType>(Ty);
if (!FVTy || FVTy->getNumElements() != 1)
return Ty;
// If it's a <1 x Type> vector type, replace it by the element type, because
// it's not a legal vector type in LLT and IRTranslator will represent it as
// the scalar eventually.
return normalizeType(FVTy->getElementType());
}

inline PoisonValue *getNormalizedPoisonValue(Type *Ty) {
return PoisonValue::get(normalizeType(Ty));
}

MachineInstr *getVRegDef(MachineRegisterInfo &MRI, Register Reg);

#define SPIRV_BACKEND_SERVICE_FUN_NAME "__spirv_backend_service_fun"
Expand Down
Loading