@@ -12571,8 +12571,35 @@ 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-flat 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, it has to be from a non-flat to flat.
12584+ // We assume the source address space is the correct one.
12585+ Value *V = &getAssociatedValue ();
12586+ if (auto *ASCI = dyn_cast<AddrSpaceCastInst>(V)) {
12587+ assert (ASCI->getDestAddressSpace () == 0 &&
12588+ " The destination address space should be a flat address space" );
12589+ [[maybe_unused]] bool R = takeAddressSpace (ASCI->getSrcAddressSpace ());
12590+ assert (R && " the take should happen" );
12591+ indicateOptimisticFixpoint ();
12592+ return ;
12593+ }
12594+ if (auto *C = dyn_cast<ConstantExpr>(V)) {
12595+ if (C->getOpcode () == Instruction::AddrSpaceCast) {
12596+ [[maybe_unused]] bool R = takeAddressSpace (
12597+ C->getOperand (0 )->getType ()->getPointerAddressSpace ());
12598+ assert (R && " the take should happen" );
12599+ indicateOptimisticFixpoint ();
12600+ return ;
12601+ }
12602+ }
1257612603 }
1257712604
1257812605 ChangeStatus updateImpl (Attributor &A) override {
@@ -12582,6 +12609,23 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1258212609 auto Pred = [&](Value &Obj) {
1258312610 if (isa<UndefValue>(&Obj))
1258412611 return true ;
12612+ // If an argument in generic address space has addrspace cast uses, and
12613+ // those casts are same, then we take the dst addrspace.
12614+ if (auto *Arg = dyn_cast<Argument>(&Obj)) {
12615+ if (Arg->getType ()->getPointerAddressSpace () == 0 ) {
12616+ unsigned CastAddrSpace = 0 ;
12617+ for (auto *U : Arg->users ()) {
12618+ auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
12619+ if (!ASCI)
12620+ continue ;
12621+ if (CastAddrSpace && CastAddrSpace != ASCI->getDestAddressSpace ())
12622+ return false ;
12623+ CastAddrSpace = ASCI->getDestAddressSpace ();
12624+ }
12625+ if (CastAddrSpace)
12626+ return takeAddressSpace (CastAddrSpace);
12627+ }
12628+ }
1258512629 return takeAddressSpace (Obj.getType ()->getPointerAddressSpace ());
1258612630 };
1258712631
@@ -12594,16 +12638,18 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1259412638
1259512639 // / See AbstractAttribute::manifest(...).
1259612640 ChangeStatus manifest (Attributor &A) override {
12597- Value *AssociatedValue = & getAssociatedValue ();
12598- Value *OriginalValue = peelAddrspacecast (AssociatedValue);
12599- if (getAddressSpace () == NoAddressSpace ||
12600- getAddressSpace () == getAssociatedType ()->getPointerAddressSpace ())
12641+ unsigned NewAS = getAddressSpace ();
12642+
12643+ if (NewAS == NoAddressSpace ||
12644+ NewAS == getAssociatedType ()->getPointerAddressSpace ())
1260112645 return ChangeStatus::UNCHANGED;
1260212646
12647+ Value *AssociatedValue = &getAssociatedValue ();
12648+ Value *OriginalValue = peelAddrspacecast (AssociatedValue);
1260312649 PointerType *NewPtrTy =
12604- PointerType::get (getAssociatedType ()->getContext (), getAddressSpace () );
12650+ PointerType::get (getAssociatedType ()->getContext (), NewAS );
1260512651 bool UseOriginalValue =
12606- OriginalValue->getType ()->getPointerAddressSpace () == getAddressSpace () ;
12652+ OriginalValue->getType ()->getPointerAddressSpace () == NewAS ;
1260712653
1260812654 bool Changed = false ;
1260912655
@@ -12664,11 +12710,16 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1266412710 }
1266512711
1266612712 static Value *peelAddrspacecast (Value *V) {
12667- if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12668- return peelAddrspacecast (I->getPointerOperand ());
12713+ if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12714+ assert (I->getSrcAddressSpace () && " there should not be AS 0 -> AS X" );
12715+ return I->getPointerOperand ();
12716+ }
1266912717 if (auto *C = dyn_cast<ConstantExpr>(V))
12670- if (C->getOpcode () == Instruction::AddrSpaceCast)
12671- return peelAddrspacecast (C->getOperand (0 ));
12718+ if (C->getOpcode () == Instruction::AddrSpaceCast) {
12719+ assert (C->getOperand (0 )->getType ()->getPointerAddressSpace () &&
12720+ " there should not be AS 0 -> AS X" );
12721+ return C->getOperand (0 );
12722+ }
1267212723 return V;
1267312724 }
1267412725};
0 commit comments