diff options
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 18 | ||||
-rw-r--r-- | test/Transforms/InstCombine/2012-03-16-StoreAlignment.ll | 12 |
2 files changed, 27 insertions, 3 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 7446a51a4d..fa68000df5 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -379,10 +379,22 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { unsigned EffectiveStoreAlign = StoreAlign != 0 ? StoreAlign : TD->getABITypeAlignment(Val->getType()); - if (KnownAlign > EffectiveStoreAlign) + if (KnownAlign > EffectiveStoreAlign) { SI.setAlignment(KnownAlign); - else if (StoreAlign == 0) - SI.setAlignment(EffectiveStoreAlign); + } else if (StoreAlign == 0) { + unsigned PtrAlign = 0; + if (GlobalValue *GV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts())) + PtrAlign = GV->getAlignment(); + + if (PtrAlign != 0 && PtrAlign < EffectiveStoreAlign) + // The pointer alignment may be less than the effective store + // alignment. If so, then we don't want to increase the alignment here, + // since that could lead to code-gen using instructions which require a + // higher alignment than the pointer guarantees. + SI.setAlignment(PtrAlign); + else + SI.setAlignment(EffectiveStoreAlign); + } } // Don't hack volatile/atomic stores. diff --git a/test/Transforms/InstCombine/2012-03-16-StoreAlignment.ll b/test/Transforms/InstCombine/2012-03-16-StoreAlignment.ll new file mode 100644 index 0000000000..7f05a89c50 --- /dev/null +++ b/test/Transforms/InstCombine/2012-03-16-StoreAlignment.ll @@ -0,0 +1,12 @@ +; RUN: opt < %s -S -instcombine | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" + +%0 = type { i32, i8, i8, i8 } + +@G = external hidden global %0, align 4 + +define void @f1(i64 %a1) nounwind ssp align 2 { +; CHECK: store i64 %a1, i64* bitcast (%0* @G to i64*), align 4 + store i64 %a1, i64* bitcast (%0* @G to i64*) + ret void +} |