@@ -199,6 +199,8 @@ class SPIRVEmitIntrinsics
199199 DenseMap<Function *, CallInst *> Ptrcasts);
200200
201201 void replaceAllUsesWith (Value *Src, Value *Dest, bool DeleteOld = true );
202+ void replaceAllUsesWithAndErase (IRBuilder<> &B, Instruction *Src,
203+ Instruction *Dest, bool DeleteOld = true );
202204
203205 bool runOnFunction (Function &F);
204206 bool postprocessTypes (Module &M);
@@ -322,6 +324,17 @@ static inline void reportFatalOnTokenType(const Instruction *I) {
322324 false );
323325}
324326
327+ static void emitAssignName (Instruction *I, IRBuilder<> &B) {
328+ if (!I->hasName () || I->getType ()->isAggregateType () ||
329+ expectIgnoredInIRTranslation (I))
330+ return ;
331+ reportFatalOnTokenType (I);
332+ setInsertPointAfterDef (B, I);
333+ std::vector<Value *> Args = {I};
334+ addStringImm (I->getName (), B, Args);
335+ B.CreateIntrinsic (Intrinsic::spv_assign_name, {I->getType ()}, Args);
336+ }
337+
325338void SPIRVEmitIntrinsics::replaceAllUsesWith (Value *Src, Value *Dest,
326339 bool DeleteOld) {
327340 Src->replaceAllUsesWith (Dest);
@@ -336,6 +349,19 @@ void SPIRVEmitIntrinsics::replaceAllUsesWith(Value *Src, Value *Dest,
336349 }
337350}
338351
352+ void SPIRVEmitIntrinsics::replaceAllUsesWithAndErase (IRBuilder<> &B,
353+ Instruction *Src,
354+ Instruction *Dest,
355+ bool DeleteOld) {
356+ replaceAllUsesWith (Src, Dest, DeleteOld);
357+ std::string Name = Src->hasName () ? Src->getName ().str () : " " ;
358+ Src->eraseFromParent ();
359+ if (!Name.empty ()) {
360+ Dest->setName (Name);
361+ emitAssignName (Dest, B);
362+ }
363+ }
364+
339365static bool IsKernelArgInt8 (Function *F, StoreInst *SI) {
340366 return SI && F->getCallingConv () == CallingConv::SPIR_KERNEL &&
341367 isPointerTy (SI->getValueOperand ()->getType ()) &&
@@ -475,7 +501,7 @@ void SPIRVEmitIntrinsics::propagateElemType(
475501 DenseMap<Function *, CallInst *> Ptrcasts;
476502 SmallVector<User *> Users (Op->users ());
477503 for (auto *U : Users) {
478- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
504+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
479505 continue ;
480506 if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
481507 continue ;
@@ -506,7 +532,7 @@ void SPIRVEmitIntrinsics::propagateElemTypeRec(
506532 return ;
507533 SmallVector<User *> Users (Op->users ());
508534 for (auto *U : Users) {
509- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
535+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
510536 continue ;
511537 if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
512538 continue ;
@@ -958,6 +984,14 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
958984 return ;
959985 Uncomplete = isTodoType (I);
960986 Ops.push_back (std::make_pair (Ref->getPointerOperand (), 0 ));
987+ } else if (auto *Ref = dyn_cast<BitCastInst>(I)) {
988+ if (!isPointerTy (I->getType ()))
989+ return ;
990+ KnownElemTy = GR->findDeducedElementType (I);
991+ if (!KnownElemTy)
992+ return ;
993+ Uncomplete = isTodoType (I);
994+ Ops.push_back (std::make_pair (Ref->getOperand (0 ), 0 ));
961995 } else if (auto *Ref = dyn_cast<GetElementPtrInst>(I)) {
962996 if (GR->findDeducedElementType (Ref->getPointerOperand ()))
963997 return ;
@@ -1030,7 +1064,6 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
10301064 }
10311065 }
10321066 }
1033- TypeValidated.insert (I);
10341067 // Non-recursive update of types in the function uncomplete returns.
10351068 // This may happen just once per a function, the latch is a pair of
10361069 // findDeducedElementType(F) / addDeducedElementType(F, ...).
@@ -1043,6 +1076,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
10431076 } else if (UncompleteRets) {
10441077 UncompleteRets->insert (I);
10451078 }
1079+ TypeValidated.insert (I);
10461080 return ;
10471081 }
10481082 Uncomplete = isTodoType (CurrF);
@@ -1300,8 +1334,7 @@ Instruction *SPIRVEmitIntrinsics::visitGetElementPtrInst(GetElementPtrInst &I) {
13001334 for (auto &Op : I.operands ())
13011335 Args.push_back (Op);
13021336 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_gep, {Types}, {Args});
1303- replaceAllUsesWith (&I, NewI);
1304- I.eraseFromParent ();
1337+ replaceAllUsesWithAndErase (B, &I, NewI);
13051338 return NewI;
13061339}
13071340
@@ -1323,10 +1356,7 @@ Instruction *SPIRVEmitIntrinsics::visitBitCastInst(BitCastInst &I) {
13231356 SmallVector<Type *, 2 > Types = {I.getType (), Source->getType ()};
13241357 SmallVector<Value *> Args (I.op_begin (), I.op_end ());
13251358 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_bitcast, {Types}, {Args});
1326- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1327- replaceAllUsesWith (&I, NewI);
1328- I.eraseFromParent ();
1329- NewI->setName (InstName);
1359+ replaceAllUsesWithAndErase (B, &I, NewI);
13301360 return NewI;
13311361}
13321362
@@ -1369,10 +1399,6 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
13691399 Instruction *I, Value *Pointer, Type *ExpectedElementType,
13701400 unsigned OperandToReplace, IRBuilder<> &B) {
13711401 TypeValidated.insert (I);
1372- // If Pointer is the result of nop BitCastInst (ptr -> ptr), use the source
1373- // pointer instead. The BitCastInst should be later removed when visited.
1374- while (BitCastInst *BC = dyn_cast<BitCastInst>(Pointer))
1375- Pointer = BC->getOperand (0 );
13761402
13771403 // Do not emit spv_ptrcast if Pointer's element type is ExpectedElementType
13781404 Type *PointerElemTy = deduceElementTypeHelper (Pointer, false );
@@ -1585,10 +1611,7 @@ Instruction *SPIRVEmitIntrinsics::visitInsertElementInst(InsertElementInst &I) {
15851611 B.SetInsertPoint (&I);
15861612 SmallVector<Value *> Args (I.op_begin (), I.op_end ());
15871613 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_insertelt, {Types}, {Args});
1588- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1589- replaceAllUsesWith (&I, NewI);
1590- I.eraseFromParent ();
1591- NewI->setName (InstName);
1614+ replaceAllUsesWithAndErase (B, &I, NewI);
15921615 return NewI;
15931616}
15941617
@@ -1600,10 +1623,7 @@ SPIRVEmitIntrinsics::visitExtractElementInst(ExtractElementInst &I) {
16001623 I.getIndexOperand ()->getType ()};
16011624 SmallVector<Value *, 2 > Args = {I.getVectorOperand (), I.getIndexOperand ()};
16021625 auto *NewI = B.CreateIntrinsic (Intrinsic::spv_extractelt, {Types}, {Args});
1603- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1604- replaceAllUsesWith (&I, NewI);
1605- I.eraseFromParent ();
1606- NewI->setName (InstName);
1626+ replaceAllUsesWithAndErase (B, &I, NewI);
16071627 return NewI;
16081628}
16091629
@@ -1637,8 +1657,7 @@ Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
16371657 Args.push_back (B.getInt32 (Op));
16381658 auto *NewI =
16391659 B.CreateIntrinsic (Intrinsic::spv_extractv, {I.getType ()}, {Args});
1640- replaceAllUsesWith (&I, NewI);
1641- I.eraseFromParent ();
1660+ replaceAllUsesWithAndErase (B, &I, NewI);
16421661 return NewI;
16431662}
16441663
@@ -1697,10 +1716,7 @@ Instruction *SPIRVEmitIntrinsics::visitAllocaInst(AllocaInst &I) {
16971716 ArraySize ? B.CreateIntrinsic (Intrinsic::spv_alloca_array,
16981717 {PtrTy, ArraySize->getType ()}, {ArraySize})
16991718 : B.CreateIntrinsic (Intrinsic::spv_alloca, {PtrTy}, {});
1700- std::string InstName = I.hasName () ? I.getName ().str () : " " ;
1701- replaceAllUsesWith (&I, NewI);
1702- I.eraseFromParent ();
1703- NewI->setName (InstName);
1719+ replaceAllUsesWithAndErase (B, &I, NewI);
17041720 return NewI;
17051721}
17061722
@@ -1759,8 +1775,7 @@ bool SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
17591775 IRBuilder<> &B,
17601776 bool UnknownElemTypeI8) {
17611777 reportFatalOnTokenType (I);
1762- if (!isPointerTy (I->getType ()) || !requireAssignType (I) ||
1763- isa<BitCastInst>(I))
1778+ if (!isPointerTy (I->getType ()) || !requireAssignType (I))
17641779 return false ;
17651780
17661781 setInsertPointAfterDef (B, I);
@@ -1861,8 +1876,9 @@ void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
18611876void SPIRVEmitIntrinsics::processInstrAfterVisit (Instruction *I,
18621877 IRBuilder<> &B) {
18631878 auto *II = dyn_cast<IntrinsicInst>(I);
1864- if (II && II->getIntrinsicID () == Intrinsic::spv_const_composite &&
1865- TrackConstants) {
1879+ bool IsConstComposite =
1880+ II && II->getIntrinsicID () == Intrinsic::spv_const_composite;
1881+ if (IsConstComposite && TrackConstants) {
18661882 setInsertPointAfterDef (B, I);
18671883 auto t = AggrConsts.find (I);
18681884 assert (t != AggrConsts.end ());
@@ -1886,23 +1902,31 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
18861902 : B.SetInsertPoint (I);
18871903 BPrepared = true ;
18881904 }
1905+ Type *OpTy = Op->getType ();
18891906 Value *OpTyVal = Op;
1890- if (Op->getType ()->isTargetExtTy ())
1891- OpTyVal = PoisonValue::get (Op->getType ());
1892- auto *NewOp = buildIntrWithMD (Intrinsic::spv_track_constant,
1893- {Op->getType (), OpTyVal->getType ()}, Op,
1894- OpTyVal, {}, B);
1907+ if (OpTy->isTargetExtTy ())
1908+ OpTyVal = PoisonValue::get (OpTy);
1909+ CallInst *NewOp =
1910+ buildIntrWithMD (Intrinsic::spv_track_constant,
1911+ {OpTy, OpTyVal->getType ()}, Op, OpTyVal, {}, B);
1912+ Type *OpElemTy = nullptr ;
1913+ if (!IsConstComposite && isPointerTy (OpTy) &&
1914+ (OpElemTy = GR->findDeducedElementType (Op)) != nullptr &&
1915+ OpElemTy != IntegerType::getInt8Ty (I->getContext ())) {
1916+ buildAssignPtr (B, IntegerType::getInt8Ty (I->getContext ()), NewOp);
1917+ SmallVector<Type *, 2 > Types = {OpTy, OpTy};
1918+ SmallVector<Value *, 2 > Args = {
1919+ NewOp, buildMD (PoisonValue::get (OpElemTy)),
1920+ B.getInt32 (getPointerAddressSpace (OpTy))};
1921+ CallInst *PtrCasted =
1922+ B.CreateIntrinsic (Intrinsic::spv_ptrcast, {Types}, Args);
1923+ buildAssignPtr (B, OpElemTy, PtrCasted);
1924+ NewOp = PtrCasted;
1925+ }
18951926 I->setOperand (OpNo, NewOp);
18961927 }
18971928 }
1898- if (I->hasName () && !I->getType ()->isAggregateType () &&
1899- !expectIgnoredInIRTranslation (I)) {
1900- reportFatalOnTokenType (I);
1901- setInsertPointAfterDef (B, I);
1902- std::vector<Value *> Args = {I};
1903- addStringImm (I->getName (), B, Args);
1904- B.CreateIntrinsic (Intrinsic::spv_assign_name, {I->getType ()}, Args);
1905- }
1929+ emitAssignName (I, B);
19061930}
19071931
19081932Type *SPIRVEmitIntrinsics::deduceFunParamElementType (Function *F,
@@ -2022,8 +2046,16 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
20222046 if (!isUntypedPointerTy (Arg->getType ()))
20232047 continue ;
20242048 Type *ElemTy = GR->findDeducedElementType (Arg);
2025- if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr )
2026- buildAssignPtr (B, ElemTy, Arg);
2049+ if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr ) {
2050+ if (CallInst *AssignCI = GR->findAssignPtrTypeInstr (Arg)) {
2051+ DenseSet<std::pair<Value *, Value *>> VisitedSubst;
2052+ updateAssignType (AssignCI, Arg, PoisonValue::get (ElemTy));
2053+ propagateElemType (Arg, IntegerType::getInt8Ty (F->getContext ()),
2054+ VisitedSubst);
2055+ } else {
2056+ buildAssignPtr (B, ElemTy, Arg);
2057+ }
2058+ }
20272059 }
20282060}
20292061
0 commit comments