diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 790a16d2aff..6454f1ea1eb 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -713,6 +713,13 @@ private: return Base::visitBitCastInst(BC); } + void visitAddrSpaceCastInst(AddrSpaceCastInst &ASC) { + if (ASC.use_empty()) + return markAsDead(ASC); + + return Base::visitAddrSpaceCastInst(ASC); + } + void visitGetElementPtrInst(GetElementPtrInst &GEPI) { if (GEPI.use_empty()) return markAsDead(GEPI); @@ -776,7 +783,10 @@ private: if (!IsOffsetKnown) return PI.setAborted(&LI); - const DataLayout &DL = LI.getModule()->getDataLayout(); + if (LI.isVolatile() && + LI.getPointerAddressSpace() != DL.getAllocaAddrSpace()) + return PI.setAborted(&LI); + uint64_t Size = DL.getTypeStoreSize(LI.getType()); return handleLoadOrStore(LI.getType(), LI, Offset, Size, LI.isVolatile()); } @@ -788,7 +798,10 @@ private: if (!IsOffsetKnown) return PI.setAborted(&SI); - const DataLayout &DL = SI.getModule()->getDataLayout(); + if (SI.isVolatile() && + SI.getPointerAddressSpace() != DL.getAllocaAddrSpace()) + return PI.setAborted(&SI); + uint64_t Size = DL.getTypeStoreSize(ValOp->getType()); // If this memory access can be shown to *statically* extend outside the @@ -823,6 +836,11 @@ private: if (!IsOffsetKnown) return PI.setAborted(&II); + // Don't replace this with a store with a different address space. TODO: + // Use a store with the casted new alloca? + if (II.isVolatile() && II.getDestAddressSpace() != DL.getAllocaAddrSpace()) + return PI.setAborted(&II); + insertUse(II, Offset, Length ? Length->getLimitedValue() : AllocSize - Offset.getLimitedValue(), (bool)Length); @@ -842,6 +860,13 @@ private: if (!IsOffsetKnown) return PI.setAborted(&II); + // Don't replace this with a load/store with a different address space. + // TODO: Use a store with the casted new alloca? + if (II.isVolatile() && + (II.getDestAddressSpace() != DL.getAllocaAddrSpace() || + II.getSourceAddressSpace() != DL.getAllocaAddrSpace())) + return PI.setAborted(&II); + // This side of the transfer is completely out-of-bounds, and so we can // nuke the entire transfer. However, we also need to nuke the other side // if already added to our partitions. @@ -949,7 +974,7 @@ private: if (!GEP->hasAllZeroIndices()) return GEP; } else if (!isa<BitCastInst>(I) && !isa<PHINode>(I) && - !isa<SelectInst>(I)) { + !isa<SelectInst>(I) && !isa<AddrSpaceCastInst>(I)) { return I; } @@ -1561,7 +1586,8 @@ static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, Value *Int8Ptr = nullptr; APInt Int8PtrOffset(Offset.getBitWidth(), 0); - Type *TargetTy = PointerTy->getPointerElementType(); + PointerType *TargetPtrTy = cast<PointerType>(PointerTy); + Type *TargetTy = TargetPtrTy->getElementType(); do { // First fold any existing GEPs into the offset. @@ -1630,8 +1656,11 @@ static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, Ptr = OffsetPtr; // On the off chance we were targeting i8*, guard the bitcast here. - if (Ptr->getType() != PointerTy) - Ptr = IRB.CreateBitCast(Ptr, PointerTy, NamePrefix + "sroa_cast"); + if (cast<PointerType>(Ptr->getType()) != TargetPtrTy) { + Ptr = IRB.CreatePointerBitCastOrAddrSpaceCast(Ptr, + TargetPtrTy, + NamePrefix + "sroa_cast"); + } return Ptr; } @@ -3082,8 +3111,9 @@ private: continue; } - assert(isa<BitCastInst>(I) || isa<PHINode>(I) || - isa<SelectInst>(I) || isa<GetElementPtrInst>(I)); + assert(isa<BitCastInst>(I) || isa<AddrSpaceCastInst>(I) || + isa<PHINode>(I) || isa<SelectInst>(I) || + isa<GetElementPtrInst>(I)); for (User *U : I->users()) if (Visited.insert(cast<Instruction>(U)).second) Uses.push_back(cast<Instruction>(U)); @@ -3384,6 +3414,11 @@ private: return false; } + bool visitAddrSpaceCastInst(AddrSpaceCastInst &ASC) { + enqueueUsers(ASC); + return false; + } + bool visitGetElementPtrInst(GetElementPtrInst &GEPI) { enqueueUsers(GEPI); return false; |

