Fix a somewhat surprising miscompile where code relying on an ABI

alignment could lose it due to the alloca type moving down to a much
smaller alignment guarantee.

Now SROA will actively compute a proper alignment, factoring the target
data, any explicit alignment, and the offset within the struct. This
will in some cases lower the alignment requirements, but when we lower
them below those of the type, we drop the alignment entirely to give
freedom to the code generator to align it however is convenient.

Thanks to Duncan for the lovely test case that pinned this down. =]

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164891 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth
2012-09-29 10:41:21 +00:00
parent 454627252b
commit b67c9a5b02
2 changed files with 35 additions and 4 deletions
+13 -3
View File
@@ -3002,9 +3002,19 @@ bool SROA::rewriteAllocaPartition(AllocaInst &AI,
assert(PI == P.begin() && "Begin offset is zero on later partition");
NewAI = &AI;
} else {
// FIXME: The alignment here is overly conservative -- we could in many
// cases get away with much weaker alignment constraints.
NewAI = new AllocaInst(AllocaTy, 0, AI.getAlignment(),
unsigned Alignment = AI.getAlignment();
if (!Alignment) {
// The minimum alignment which users can rely on when the explicit
// alignment is omitted or zero is that required by the ABI for this
// type.
Alignment = TD->getABITypeAlignment(AI.getAllocatedType());
}
Alignment = MinAlign(Alignment, PI->BeginOffset);
// If we will get at least this much alignment from the type alone, leave
// the alloca's alignment unconstrained.
if (Alignment <= TD->getABITypeAlignment(AllocaTy))
Alignment = 0;
NewAI = new AllocaInst(AllocaTy, 0, Alignment,
AI.getName() + ".sroa." + Twine(PI - P.begin()),
&AI);
++NumNewAllocas;