Set load alignment on aggregate loads.

When optimizing a extractvalue(load), we generate a load from the
aggregate type.  This load didn't have alignment set and so would
get the alignment of the type.  This breaks when the type is packed
and so the alignment should be lower.

For example, loading { int, int } would give us alignment of 4, but
the original load from this type may have an alignment of 1 if packed.

Reviewed by David Majnemer

Differential revision: http://reviews.llvm.org/D17158

llvm-svn: 260587
This commit is contained in:
Pete Cooper 2016-02-11 21:10:40 +00:00
parent c67f5a6ab1
commit 5562c333b8
2 changed files with 17 additions and 1 deletions

View File

@ -552,7 +552,8 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) {
ConstantInt::get(IdxType, i),
};
auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, makeArrayRef(Indices), EltName);
auto *L = IC.Builder->CreateLoad(ST->getTypeAtIndex(i), Ptr, LoadName);
auto *L = IC.Builder->CreateAlignedLoad(Ptr, LI.getAlignment(),
LoadName);
V = IC.Builder->CreateInsertValue(V, L, i);
}

View File

@ -136,3 +136,18 @@ define %B @structB(%B* %b.ptr) {
%1 = load %B, %B* %b.ptr, align 8
ret %B %1
}
%struct.S = type <{ i8, %struct.T }>
%struct.T = type { i32, i32 }
; Make sure that we do not increase alignment of packed struct element
define i32 @packed_alignment(%struct.S* dereferenceable(9) %s) {
; CHECK-LABEL: packed_alignment
; CHECK-NEXT: %tv.elt1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
; CHECK-NEXT: %tv.unpack2 = load i32, i32* %tv.elt1, align 1
; CHECK-NEXT: ret i32 %tv.unpack2
%t = getelementptr inbounds %struct.S, %struct.S* %s, i32 0, i32 1
%tv = load %struct.T, %struct.T* %t, align 1
%v = extractvalue %struct.T %tv, 1
ret i32 %v
}