@@ -12587,16 +12587,38 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1258712587 }
1258812588
1258912589 ChangeStatus updateImpl (Attributor &A) override {
12590+ unsigned FlatAS = A.getInfoCache ().getDL ().getFlatAddressSpace ();
12591+ assert (FlatAS != InvalidAddressSpace);
1259012592 uint32_t OldAddressSpace = AssumedAddressSpace;
12591- auto *AUO = A.getOrCreateAAFor <AAUnderlyingObjects>(getIRPosition (), this ,
12592- DepClassTy::REQUIRED);
12593- auto Pred = [&](Value &Obj) {
12593+
12594+ auto CheckAddressSpace = [&](Value &Obj) {
1259412595 if (isa<UndefValue>(&Obj))
1259512596 return true ;
12597+ // If an argument in flat address space only has addrspace cast uses, and
12598+ // those casts are same, then we take the dst addrspace.
12599+ if (auto *Arg = dyn_cast<Argument>(&Obj)) {
12600+ if (FlatAS != InvalidAddressSpace &&
12601+ Arg->getType ()->getPointerAddressSpace () == FlatAS) {
12602+ unsigned CastAddrSpace = FlatAS;
12603+ for (auto *U : Arg->users ()) {
12604+ auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
12605+ if (!ASCI)
12606+ return takeAddressSpace (Obj.getType ()->getPointerAddressSpace ());
12607+ if (CastAddrSpace != FlatAS &&
12608+ CastAddrSpace != ASCI->getDestAddressSpace ())
12609+ return false ;
12610+ CastAddrSpace = ASCI->getDestAddressSpace ();
12611+ }
12612+ if (CastAddrSpace != FlatAS)
12613+ return takeAddressSpace (CastAddrSpace);
12614+ }
12615+ }
1259612616 return takeAddressSpace (Obj.getType ()->getPointerAddressSpace ());
1259712617 };
1259812618
12599- if (!AUO->forallUnderlyingObjects (Pred))
12619+ auto *AUO = A.getOrCreateAAFor <AAUnderlyingObjects>(getIRPosition (), this ,
12620+ DepClassTy::REQUIRED);
12621+ if (!AUO->forallUnderlyingObjects (CheckAddressSpace))
1260012622 return indicatePessimisticFixpoint ();
1260112623
1260212624 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
@@ -12605,17 +12627,22 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1260512627
1260612628 // / See AbstractAttribute::manifest(...).
1260712629 ChangeStatus manifest (Attributor &A) override {
12608- if (getAddressSpace () == InvalidAddressSpace ||
12609- getAddressSpace () == getAssociatedType ()->getPointerAddressSpace ())
12630+ unsigned NewAS = getAddressSpace ();
12631+
12632+ if (NewAS == InvalidAddressSpace ||
12633+ NewAS == getAssociatedType ()->getPointerAddressSpace ())
1261012634 return ChangeStatus::UNCHANGED;
1261112635
12636+ unsigned FlatAS = A.getInfoCache ().getDL ().getFlatAddressSpace ();
12637+ assert (FlatAS != InvalidAddressSpace);
12638+
1261212639 Value *AssociatedValue = &getAssociatedValue ();
12613- Value *OriginalValue = peelAddrspacecast (AssociatedValue);
12640+ Value *OriginalValue = peelAddrspacecast (AssociatedValue, FlatAS );
1261412641
1261512642 PointerType *NewPtrTy =
12616- PointerType::get (getAssociatedType ()->getContext (), getAddressSpace () );
12643+ PointerType::get (getAssociatedType ()->getContext (), NewAS );
1261712644 bool UseOriginalValue =
12618- OriginalValue->getType ()->getPointerAddressSpace () == getAddressSpace () ;
12645+ OriginalValue->getType ()->getPointerAddressSpace () == NewAS ;
1261912646
1262012647 bool Changed = false ;
1262112648
@@ -12675,12 +12702,19 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1267512702 return AssumedAddressSpace == AS;
1267612703 }
1267712704
12678- static Value *peelAddrspacecast (Value *V) {
12679- if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12680- return peelAddrspacecast (I->getPointerOperand ());
12705+ static Value *peelAddrspacecast (Value *V, unsigned FlatAS) {
12706+ if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12707+ assert (I->getSrcAddressSpace () != FlatAS &&
12708+ " there should not be flat AS -> non-flat AS" );
12709+ return I->getPointerOperand ();
12710+ }
1268112711 if (auto *C = dyn_cast<ConstantExpr>(V))
12682- if (C->getOpcode () == Instruction::AddrSpaceCast)
12683- return peelAddrspacecast (C->getOperand (0 ));
12712+ if (C->getOpcode () == Instruction::AddrSpaceCast) {
12713+ assert (C->getOperand (0 )->getType ()->getPointerAddressSpace () !=
12714+ FlatAS &&
12715+ " there should not be flat AS -> non-flat AS X" );
12716+ return C->getOperand (0 );
12717+ }
1268412718 return V;
1268512719 }
1268612720};
0 commit comments