@@ -475,7 +475,7 @@ void SPIRVEmitIntrinsics::propagateElemType(
475475 DenseMap<Function *, CallInst *> Ptrcasts;
476476 SmallVector<User *> Users (Op->users ());
477477 for (auto *U : Users) {
478- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
478+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
479479 continue ;
480480 if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
481481 continue ;
@@ -506,7 +506,7 @@ void SPIRVEmitIntrinsics::propagateElemTypeRec(
506506 return ;
507507 SmallVector<User *> Users (Op->users ());
508508 for (auto *U : Users) {
509- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic (U))
509+ if (!isa<Instruction>(U) || isSpvIntrinsic (U))
510510 continue ;
511511 if (!VisitedSubst.insert (std::make_pair (U, Op)).second )
512512 continue ;
@@ -958,6 +958,14 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
958958 return ;
959959 Uncomplete = isTodoType (I);
960960 Ops.push_back (std::make_pair (Ref->getPointerOperand (), 0 ));
961+ } else if (auto *Ref = dyn_cast<BitCastInst>(I)) {
962+ if (!isPointerTy (I->getType ()))
963+ return ;
964+ KnownElemTy = GR->findDeducedElementType (I);
965+ if (!KnownElemTy)
966+ return ;
967+ Uncomplete = isTodoType (I);
968+ Ops.push_back (std::make_pair (Ref->getOperand (0 ), 0 ));
961969 } else if (auto *Ref = dyn_cast<GetElementPtrInst>(I)) {
962970 if (GR->findDeducedElementType (Ref->getPointerOperand ()))
963971 return ;
@@ -1030,7 +1038,6 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
10301038 }
10311039 }
10321040 }
1033- TypeValidated.insert (I);
10341041 // Non-recursive update of types in the function uncomplete returns.
10351042 // This may happen just once per a function, the latch is a pair of
10361043 // findDeducedElementType(F) / addDeducedElementType(F, ...).
@@ -1043,6 +1050,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
10431050 } else if (UncompleteRets) {
10441051 UncompleteRets->insert (I);
10451052 }
1053+ TypeValidated.insert (I);
10461054 return ;
10471055 }
10481056 Uncomplete = isTodoType (CurrF);
@@ -1369,10 +1377,6 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
13691377 Instruction *I, Value *Pointer, Type *ExpectedElementType,
13701378 unsigned OperandToReplace, IRBuilder<> &B) {
13711379 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 );
13761380
13771381 // Do not emit spv_ptrcast if Pointer's element type is ExpectedElementType
13781382 Type *PointerElemTy = deduceElementTypeHelper (Pointer, false );
@@ -1759,8 +1763,7 @@ bool SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
17591763 IRBuilder<> &B,
17601764 bool UnknownElemTypeI8) {
17611765 reportFatalOnTokenType (I);
1762- if (!isPointerTy (I->getType ()) || !requireAssignType (I) ||
1763- isa<BitCastInst>(I))
1766+ if (!isPointerTy (I->getType ()) || !requireAssignType (I))
17641767 return false ;
17651768
17661769 setInsertPointAfterDef (B, I);
@@ -1861,8 +1864,9 @@ void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
18611864void SPIRVEmitIntrinsics::processInstrAfterVisit (Instruction *I,
18621865 IRBuilder<> &B) {
18631866 auto *II = dyn_cast<IntrinsicInst>(I);
1864- if (II && II->getIntrinsicID () == Intrinsic::spv_const_composite &&
1865- TrackConstants) {
1867+ bool IsConstComposite =
1868+ II && II->getIntrinsicID () == Intrinsic::spv_const_composite;
1869+ if (IsConstComposite && TrackConstants) {
18661870 setInsertPointAfterDef (B, I);
18671871 auto t = AggrConsts.find (I);
18681872 assert (t != AggrConsts.end ());
@@ -1886,12 +1890,27 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
18861890 : B.SetInsertPoint (I);
18871891 BPrepared = true ;
18881892 }
1893+ Type *OpTy = Op->getType ();
18891894 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);
1895+ if (OpTy->isTargetExtTy ())
1896+ OpTyVal = PoisonValue::get (OpTy);
1897+ CallInst *NewOp =
1898+ buildIntrWithMD (Intrinsic::spv_track_constant,
1899+ {OpTy, OpTyVal->getType ()}, Op, OpTyVal, {}, B);
1900+ Type *OpElemTy = nullptr ;
1901+ if (!IsConstComposite && isPointerTy (OpTy) &&
1902+ (OpElemTy = GR->findDeducedElementType (Op)) != nullptr &&
1903+ OpElemTy != IntegerType::getInt8Ty (I->getContext ())) {
1904+ buildAssignPtr (B, IntegerType::getInt8Ty (I->getContext ()), NewOp);
1905+ SmallVector<Type *, 2 > Types = {OpTy, OpTy};
1906+ SmallVector<Value *, 2 > Args = {
1907+ NewOp, buildMD (PoisonValue::get (OpElemTy)),
1908+ B.getInt32 (getPointerAddressSpace (OpTy))};
1909+ CallInst *PtrCasted =
1910+ B.CreateIntrinsic (Intrinsic::spv_ptrcast, {Types}, Args);
1911+ buildAssignPtr (B, OpElemTy, PtrCasted);
1912+ NewOp = PtrCasted;
1913+ }
18951914 I->setOperand (OpNo, NewOp);
18961915 }
18971916 }
@@ -2022,8 +2041,16 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
20222041 if (!isUntypedPointerTy (Arg->getType ()))
20232042 continue ;
20242043 Type *ElemTy = GR->findDeducedElementType (Arg);
2025- if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr )
2026- buildAssignPtr (B, ElemTy, Arg);
2044+ if (!ElemTy && (ElemTy = deduceFunParamElementType (F, OpIdx)) != nullptr ) {
2045+ if (CallInst *AssignCI = GR->findAssignPtrTypeInstr (Arg)) {
2046+ DenseSet<std::pair<Value *, Value *>> VisitedSubst;
2047+ updateAssignType (AssignCI, Arg, PoisonValue::get (ElemTy));
2048+ propagateElemType (Arg, IntegerType::getInt8Ty (F->getContext ()),
2049+ VisitedSubst);
2050+ } else {
2051+ buildAssignPtr (B, ElemTy, Arg);
2052+ }
2053+ }
20272054 }
20282055}
20292056
0 commit comments