summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/AttributorAttributes.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/AttributorAttributes.cpp59
1 files changed, 45 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 45e2a0d0b933..5d17ffa61272 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -12583,16 +12583,36 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
}
ChangeStatus updateImpl(Attributor &A) override {
+ unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
uint32_t OldAddressSpace = AssumedAddressSpace;
- auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
- DepClassTy::REQUIRED);
- auto Pred = [&](Value &Obj) {
+
+ auto CheckAddressSpace = [&](Value &Obj) {
if (isa<UndefValue>(&Obj))
return true;
+ // If an argument in flat address space only has addrspace cast uses, and
+ // those casts are same, then we take the dst addrspace.
+ if (auto *Arg = dyn_cast<Argument>(&Obj)) {
+ if (Arg->getType()->getPointerAddressSpace() == FlatAS) {
+ unsigned CastAddrSpace = FlatAS;
+ for (auto *U : Arg->users()) {
+ auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
+ if (!ASCI)
+ return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
+ if (CastAddrSpace != FlatAS &&
+ CastAddrSpace != ASCI->getDestAddressSpace())
+ return false;
+ CastAddrSpace = ASCI->getDestAddressSpace();
+ }
+ if (CastAddrSpace != FlatAS)
+ return takeAddressSpace(CastAddrSpace);
+ }
+ }
return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
};
- if (!AUO->forallUnderlyingObjects(Pred))
+ auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
+ DepClassTy::REQUIRED);
+ if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
return indicatePessimisticFixpoint();
return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
@@ -12601,17 +12621,21 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
- if (getAddressSpace() == InvalidAddressSpace ||
- getAddressSpace() == getAssociatedType()->getPointerAddressSpace())
+ unsigned NewAS = getAddressSpace();
+
+ if (NewAS == InvalidAddressSpace ||
+ NewAS == getAssociatedType()->getPointerAddressSpace())
return ChangeStatus::UNCHANGED;
+ unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
+
Value *AssociatedValue = &getAssociatedValue();
- Value *OriginalValue = peelAddrspacecast(AssociatedValue);
+ Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
PointerType *NewPtrTy =
- PointerType::get(getAssociatedType()->getContext(), getAddressSpace());
+ PointerType::get(getAssociatedType()->getContext(), NewAS);
bool UseOriginalValue =
- OriginalValue->getType()->getPointerAddressSpace() == getAddressSpace();
+ OriginalValue->getType()->getPointerAddressSpace() == NewAS;
bool Changed = false;
@@ -12671,12 +12695,19 @@ private:
return AssumedAddressSpace == AS;
}
- static Value *peelAddrspacecast(Value *V) {
- if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
- return peelAddrspacecast(I->getPointerOperand());
+ static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
+ if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
+ assert(I->getSrcAddressSpace() != FlatAS &&
+ "there should not be flat AS -> non-flat AS");
+ return I->getPointerOperand();
+ }
if (auto *C = dyn_cast<ConstantExpr>(V))
- if (C->getOpcode() == Instruction::AddrSpaceCast)
- return peelAddrspacecast(C->getOperand(0));
+ if (C->getOpcode() == Instruction::AddrSpaceCast) {
+ assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
+ FlatAS &&
+ "there should not be flat AS -> non-flat AS X");
+ return C->getOperand(0);
+ }
return V;
}
};