diff options
| author | Amaury Sechet <deadalnix@gmail.com> | 2016-02-17 19:21:28 +0000 |
|---|---|---|
| committer | Amaury Sechet <deadalnix@gmail.com> | 2016-02-17 19:21:28 +0000 |
| commit | 61a7d629ecc118fb72c1e12b7319ee72c93f1c95 (patch) | |
| tree | fd2bd0b46240549ccf97661f9dfe6680c711f379 /llvm | |
| parent | f48bcb2bd94b5a6e3634cf3b95e4a0137a7df2cb (diff) | |
| download | bcm5719-llvm-61a7d629ecc118fb72c1e12b7319ee72c93f1c95.tar.gz bcm5719-llvm-61a7d629ecc118fb72c1e12b7319ee72c93f1c95.zip | |
Fix load alignement when unpacking aggregates structs
Summary: Store and loads unpacked by instcombine do not always have the right alignement. This explicitely compute the alignement and set it.
Reviewers: dblaikie, majnemer, reames, hfinkel, joker.eph
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D17326
llvm-svn: 261139
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 38 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/unpack-fca.ll | 27 |
2 files changed, 53 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 67f7478ab23..0aa575b37ec 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -523,16 +523,17 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) { if (!T->isAggregateType()) return nullptr; + auto Name = LI.getName(); assert(LI.getAlignment() && "Alignment must be set at this point"); if (auto *ST = dyn_cast<StructType>(T)) { // If the struct only have one element, we unpack. - unsigned Count = ST->getNumElements(); - if (Count == 1) { + auto NumElements = ST->getNumElements(); + if (NumElements == 1) { LoadInst *NewLoad = combineLoadToNewType(IC, LI, ST->getTypeAtIndex(0U), ".unpack"); return IC.replaceInstUsesWith(LI, IC.Builder->CreateInsertValue( - UndefValue::get(T), NewLoad, 0, LI.getName())); + UndefValue::get(T), NewLoad, 0, Name)); } // We don't want to break loads with padding here as we'd loose @@ -542,23 +543,29 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) { if (SL->hasPadding()) return nullptr; - auto Name = LI.getName(); + auto Align = LI.getAlignment(); + if (!Align) + Align = DL.getABITypeAlignment(ST); + SmallString<16> LoadName = Name; LoadName += ".unpack"; SmallString<16> EltName = Name; EltName += ".elt"; + auto *Addr = LI.getPointerOperand(); - Value *V = UndefValue::get(T); - auto *IdxType = Type::getInt32Ty(ST->getContext()); + auto *IdxType = Type::getInt32Ty(T->getContext()); auto *Zero = ConstantInt::get(IdxType, 0); - for (unsigned i = 0; i < Count; i++) { + + Value *V = UndefValue::get(T); + for (unsigned i = 0; i < NumElements; i++) { Value *Indices[2] = { Zero, ConstantInt::get(IdxType, i), }; - auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, makeArrayRef(Indices), EltName); - auto *L = IC.Builder->CreateAlignedLoad(Ptr, LI.getAlignment(), - LoadName); + auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, + makeArrayRef(Indices), EltName); + auto EltAlign = MinAlign(Align, SL->getElementOffset(i)); + auto *L = IC.Builder->CreateAlignedLoad(Ptr, EltAlign, LoadName); V = IC.Builder->CreateInsertValue(V, L, i); } @@ -948,11 +955,16 @@ static bool unpackStoreToAggregate(InstCombiner &IC, StoreInst &SI) { if (SL->hasPadding()) return false; + auto Align = SI.getAlignment(); + if (!Align) + Align = DL.getABITypeAlignment(ST); + SmallString<16> EltName = V->getName(); EltName += ".elt"; auto *Addr = SI.getPointerOperand(); SmallString<16> AddrName = Addr->getName(); AddrName += ".repack"; + auto *IdxType = Type::getInt32Ty(ST->getContext()); auto *Zero = ConstantInt::get(IdxType, 0); for (unsigned i = 0; i < Count; i++) { @@ -960,9 +972,11 @@ static bool unpackStoreToAggregate(InstCombiner &IC, StoreInst &SI) { Zero, ConstantInt::get(IdxType, i), }; - auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, makeArrayRef(Indices), AddrName); + auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, + makeArrayRef(Indices), AddrName); auto *Val = IC.Builder->CreateExtractValue(V, i, EltName); - IC.Builder->CreateStore(Val, Ptr); + auto EltAlign = MinAlign(Align, SL->getElementOffset(i)); + IC.Builder->CreateAlignedStore(Val, Ptr, EltAlign); } return true; diff --git a/llvm/test/Transforms/InstCombine/unpack-fca.ll b/llvm/test/Transforms/InstCombine/unpack-fca.ll index 435983924b7..bed3b61939d 100644 --- a/llvm/test/Transforms/InstCombine/unpack-fca.ll +++ b/llvm/test/Transforms/InstCombine/unpack-fca.ll @@ -151,3 +151,30 @@ define i32 @packed_alignment(%struct.S* dereferenceable(9) %s) { %v = extractvalue %struct.T %tv, 1 ret i32 %v } + +%struct.U = type {i8, i8, i8, i8, i8, i8, i8, i8, i64} + +define void @check_alignment(%struct.U* %u, %struct.U* %v) { +; CHECK-LABEL: check_alignment +; CHECK: load i8, i8* {{.*}}, align 8 +; CHECK: load i8, i8* {{.*}}, align 1 +; CHECK: load i8, i8* {{.*}}, align 2 +; CHECK: load i8, i8* {{.*}}, align 1 +; CHECK: load i8, i8* {{.*}}, align 4 +; CHECK: load i8, i8* {{.*}}, align 1 +; CHECK: load i8, i8* {{.*}}, align 2 +; CHECK: load i8, i8* {{.*}}, align 1 +; CHECK: load i64, i64* {{.*}}, align 8 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 8 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 1 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 2 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 1 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 4 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 1 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 2 +; CHECK: store i8 {{.*}}, i8* {{.*}}, align 1 +; CHECK: store i64 {{.*}}, i64* {{.*}}, align 8 + %1 = load %struct.U, %struct.U* %u + store %struct.U %1, %struct.U* %v + ret void +} |

