summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/SROA.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-10-01 12:16:54 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-10-01 12:16:54 +0000
commit673850aa2dceb8fe1b7a20b72339bf803af8609f (patch)
tree36c32dd5a1769c76218f88ba8c118ea451d27d7a /lib/Transforms/Scalar/SROA.cpp
parent90012586f79895a8104e1e65689041fec52d788d (diff)
downloadllvm-673850aa2dceb8fe1b7a20b72339bf803af8609f.tar.gz
llvm-673850aa2dceb8fe1b7a20b72339bf803af8609f.tar.bz2
llvm-673850aa2dceb8fe1b7a20b72339bf803af8609f.tar.xz
Fix several issues with alignment. We weren't always accounting for type
alignment requirements of the new alloca. As one consequence which was reported as a bug by Duncan, we overaligned memcpy calls to ranges of allocas after they were rewritten to types with lower alignment requirements. Other consquences are possible, but I don't have any test cases for them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164937 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/SROA.cpp')
-rw-r--r--lib/Transforms/Scalar/SROA.cpp63
1 files changed, 32 insertions, 31 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index c3f95ad01d..e9a3c389e2 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -2145,6 +2145,20 @@ private:
return getAdjustedPtr(IRB, TD, &NewAI, Offset, PointerTy, getName(""));
}
+ unsigned getAdjustedAlign(uint64_t Offset) {
+ unsigned NewAIAlign = NewAI.getAlignment();
+ if (!NewAIAlign)
+ NewAIAlign = TD.getABITypeAlignment(NewAI.getAllocatedType());
+ return MinAlign(NewAIAlign, Offset);
+ }
+ unsigned getAdjustedAlign() {
+ return getAdjustedAlign(BeginOffset - NewAllocaBeginOffset);
+ }
+
+ bool isTypeAlignSufficient(Type *Ty) {
+ return TD.getABITypeAlignment(Ty) >= getAdjustedAlign();
+ }
+
ConstantInt *getIndex(IRBuilder<> &IRB, uint64_t Offset) {
assert(VecTy && "Can only call getIndex when rewriting a vector");
uint64_t RelOffset = Offset - NewAllocaBeginOffset;
@@ -2253,9 +2267,8 @@ private:
Value *NewPtr = getAdjustedAllocaPtr(IRB,
LI.getPointerOperand()->getType());
LI.setOperand(0, NewPtr);
- if (LI.getAlignment())
- LI.setAlignment(MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset));
+ if (LI.getAlignment() || !isTypeAlignSufficient(LI.getType()))
+ LI.setAlignment(getAdjustedAlign());
DEBUG(dbgs() << " to: " << LI << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2307,6 +2320,9 @@ private:
Value *NewPtr = getAdjustedAllocaPtr(IRB,
SI.getPointerOperand()->getType());
SI.setOperand(1, NewPtr);
+ if (SI.getAlignment() ||
+ !isTypeAlignSufficient(SI.getValueOperand()->getType()))
+ SI.setAlignment(getAdjustedAlign());
if (SI.getAlignment())
SI.setAlignment(MinAlign(NewAI.getAlignment(),
BeginOffset - NewAllocaBeginOffset));
@@ -2325,14 +2341,8 @@ private:
// pointer to the new alloca.
if (!isa<Constant>(II.getLength())) {
II.setDest(getAdjustedAllocaPtr(IRB, II.getRawDest()->getType()));
-
Type *CstTy = II.getAlignmentCst()->getType();
- if (!NewAI.getAlignment())
- II.setAlignment(ConstantInt::get(CstTy, 0));
- else
- II.setAlignment(
- ConstantInt::get(CstTy, MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset)));
+ II.setAlignment(ConstantInt::get(CstTy, getAdjustedAlign()));
deleteIfTriviallyDead(OldPtr);
return false;
@@ -2353,15 +2363,10 @@ private:
!TD.isLegalInteger(TD.getTypeSizeInBits(ScalarTy)))) {
Type *SizeTy = II.getLength()->getType();
Constant *Size = ConstantInt::get(SizeTy, EndOffset - BeginOffset);
- unsigned Align = 1;
- if (NewAI.getAlignment())
- Align = MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset);
-
CallInst *New
= IRB.CreateMemSet(getAdjustedAllocaPtr(IRB,
II.getRawDest()->getType()),
- II.getValue(), Size, Align,
+ II.getValue(), Size, getAdjustedAlign(),
II.isVolatile());
(void)New;
DEBUG(dbgs() << " to: " << *New << "\n");
@@ -2443,6 +2448,16 @@ private:
const AllocaPartitioning::MemTransferOffsets &MTO
= P.getMemTransferOffsets(II);
+ // Compute the relative offset within the transfer.
+ unsigned IntPtrWidth = TD.getPointerSizeInBits();
+ APInt RelOffset(IntPtrWidth, BeginOffset - (IsDest ? MTO.DestBegin
+ : MTO.SourceBegin));
+
+ unsigned Align = II.getAlignment();
+ if (Align > 1)
+ Align = MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
+ MinAlign(II.getAlignment(), getAdjustedAlign()));
+
// For unsplit intrinsics, we simply modify the source and destination
// pointers in place. This isn't just an optimization, it is a matter of
// correctness. With unsplit intrinsics we may be dealing with transfers
@@ -2458,11 +2473,7 @@ private:
II.setSource(getAdjustedAllocaPtr(IRB, II.getRawSource()->getType()));
Type *CstTy = II.getAlignmentCst()->getType();
- if (II.getAlignment() > 1)
- II.setAlignment(ConstantInt::get(
- CstTy, MinAlign(II.getAlignment(),
- MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset))));
+ II.setAlignment(ConstantInt::get(CstTy, Align));
DEBUG(dbgs() << " to: " << II << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2474,11 +2485,6 @@ private:
// memmove with memcpy, and we don't need to worry about all manner of
// downsides to splitting and transforming the operations.
- // Compute the relative offset within the transfer.
- unsigned IntPtrWidth = TD.getPointerSizeInBits();
- APInt RelOffset(IntPtrWidth, BeginOffset - (IsDest ? MTO.DestBegin
- : MTO.SourceBegin));
-
// If this doesn't map cleanly onto the alloca type, and that type isn't
// a single value type, just emit a memcpy.
bool EmitMemCpy
@@ -2521,11 +2527,6 @@ private:
OtherPtr = getAdjustedPtr(IRB, TD, OtherPtr, RelOffset, OtherPtrTy,
getName("." + OtherPtr->getName()));
- unsigned Align = II.getAlignment();
- if (Align > 1)
- Align = MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
- MinAlign(II.getAlignment(), NewAI.getAlignment()));
-
// Strip all inbounds GEPs and pointer casts to try to dig out any root
// alloca that should be re-examined after rewriting this instruction.
if (AllocaInst *AI