@@ -12562,7 +12562,7 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1256212562 AAAddressSpaceImpl (const IRPosition &IRP, Attributor &A)
1256312563 : AAAddressSpace(IRP, A) {}
1256412564
12565- int32_t getAddressSpace () const override {
12565+ uint32_t getAddressSpace () const override {
1256612566 assert (isValidState () && " the AA is invalid" );
1256712567 return AssumedAddressSpace;
1256812568 }
@@ -12571,17 +12571,59 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1257112571 void initialize (Attributor &A) override {
1257212572 assert (getAssociatedType ()->isPtrOrPtrVectorTy () &&
1257312573 " Associated value is not a pointer" );
12574- if (getAssociatedType ()->getPointerAddressSpace ())
12574+ // If the pointer already has non-generic address space, we assume it is the
12575+ // correct one.
12576+ if (getAssociatedType ()->getPointerAddressSpace ()) {
12577+ [[maybe_unused]] bool R =
12578+ takeAddressSpace (getAssociatedType ()->getPointerAddressSpace ());
12579+ assert (R && " the take should happen" );
1257512580 indicateOptimisticFixpoint ();
12581+ return ;
12582+ }
12583+ // If the pointer is an addrspacecast, we assume the source address space is
12584+ // the correct one.
12585+ Value *V = &getAssociatedValue ();
12586+ if (auto *ASC = dyn_cast<AddrSpaceCastInst>(V)) {
12587+ [[maybe_unused]] bool R = takeAddressSpace (ASC->getSrcAddressSpace ());
12588+ assert (R && " the take should happen" );
12589+ indicateOptimisticFixpoint ();
12590+ return ;
12591+ }
12592+ if (auto *C = dyn_cast<ConstantExpr>(V)) {
12593+ if (C->getOpcode () == Instruction::AddrSpaceCast) {
12594+ [[maybe_unused]] bool R = takeAddressSpace (
12595+ C->getOperand (0 )->getType ()->getPointerAddressSpace ());
12596+ assert (R && " the take should happen" );
12597+ indicateOptimisticFixpoint ();
12598+ return ;
12599+ }
12600+ }
1257612601 }
1257712602
1257812603 ChangeStatus updateImpl (Attributor &A) override {
12579- int32_t OldAddressSpace = AssumedAddressSpace;
12604+ uint32_t OldAddressSpace = AssumedAddressSpace;
1258012605 auto *AUO = A.getOrCreateAAFor <AAUnderlyingObjects>(getIRPosition (), this ,
1258112606 DepClassTy::REQUIRED);
1258212607 auto Pred = [&](Value &Obj) {
1258312608 if (isa<UndefValue>(&Obj))
1258412609 return true ;
12610+ // If an argument in generic address space has addrspace cast uses, and
12611+ // those casts are same, then we take the dst addrspace.
12612+ if (auto *Arg = dyn_cast<Argument>(&Obj)) {
12613+ if (Arg->getType ()->getPointerAddressSpace () == 0 ) {
12614+ unsigned CastAddrSpace = 0 ;
12615+ for (auto *U : Arg->users ()) {
12616+ auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
12617+ if (!ASCI)
12618+ continue ;
12619+ if (CastAddrSpace && CastAddrSpace != ASCI->getDestAddressSpace ())
12620+ return false ;
12621+ CastAddrSpace = ASCI->getDestAddressSpace ();
12622+ }
12623+ if (CastAddrSpace)
12624+ return takeAddressSpace (CastAddrSpace);
12625+ }
12626+ }
1258512627 return takeAddressSpace (Obj.getType ()->getPointerAddressSpace ());
1258612628 };
1258712629
@@ -12594,19 +12636,17 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1259412636
1259512637 // / See AbstractAttribute::manifest(...).
1259612638 ChangeStatus manifest (Attributor &A) override {
12597- Value *AssociatedValue = &getAssociatedValue ();
12598- Value *OriginalValue = peelAddrspacecast (AssociatedValue);
12599- if (getAddressSpace () == NoAddressSpace ||
12600- static_cast <uint32_t >(getAddressSpace ()) ==
12601- getAssociatedType ()->getPointerAddressSpace ())
12639+ unsigned NewAS = getAddressSpace ();
12640+ if (NewAS == NoAddressSpace ||
12641+ NewAS == getAssociatedType ()->getPointerAddressSpace ())
1260212642 return ChangeStatus::UNCHANGED;
1260312643
12604- PointerType *NewPtrTy =
12605- PointerType::get (getAssociatedType ()->getContext (),
12606- static_cast <uint32_t >(getAddressSpace ()));
12644+ Value *AssociatedValue = &getAssociatedValue ();
12645+ Value *OriginalValue = peelAddrspacecast (AssociatedValue);
1260712646 bool UseOriginalValue =
12608- OriginalValue->getType ()->getPointerAddressSpace () ==
12609- static_cast <uint32_t >(getAddressSpace ());
12647+ OriginalValue->getType ()->getPointerAddressSpace () == NewAS;
12648+ PointerType *NewPtrTy =
12649+ PointerType::get (getAssociatedType ()->getContext (), NewAS);
1261012650
1261112651 bool Changed = false ;
1261212652
@@ -12656,9 +12696,9 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1265612696 }
1265712697
1265812698private:
12659- int32_t AssumedAddressSpace = NoAddressSpace;
12699+ uint32_t AssumedAddressSpace = NoAddressSpace;
1266012700
12661- bool takeAddressSpace (int32_t AS) {
12701+ bool takeAddressSpace (uint32_t AS) {
1266212702 if (AssumedAddressSpace == NoAddressSpace) {
1266312703 AssumedAddressSpace = AS;
1266412704 return true ;
@@ -12667,11 +12707,16 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1266712707 }
1266812708
1266912709 static Value *peelAddrspacecast (Value *V) {
12670- if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12671- return peelAddrspacecast (I->getPointerOperand ());
12710+ if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12711+ assert (I->getSrcAddressSpace () && " there should not be AS 0 -> AS X" );
12712+ return I->getPointerOperand ();
12713+ }
1267212714 if (auto *C = dyn_cast<ConstantExpr>(V))
12673- if (C->getOpcode () == Instruction::AddrSpaceCast)
12674- return peelAddrspacecast (C->getOperand (0 ));
12715+ if (C->getOpcode () == Instruction::AddrSpaceCast) {
12716+ assert (C->getOperand (0 )->getType ()->getPointerAddressSpace () &&
12717+ " there should not be AS 0 -> AS X" );
12718+ return C->getOperand (0 );
12719+ }
1267512720 return V;
1267612721 }
1267712722};
0 commit comments