The alignment of the pointer part of the store instruction may have an
authorBill Wendling <isanbard@gmail.com>
Fri, 16 Mar 2012 07:40:08 +0000 (07:40 +0000)
committerBill Wendling <isanbard@gmail.com>
Fri, 16 Mar 2012 07:40:08 +0000 (07:40 +0000)
alignment. If that's the case, then we want to make sure that we don't increase
the alignment of the store instruction. Because if we increase it to be "more
aligned" than the pointer, code-gen may use instructions which require a greater
alignment than the pointer guarantees.
<rdar://problem/11043589>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152907 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
test/Transforms/InstCombine/2012-03-16-StoreAlignment.ll [new file with mode: 0644]

index 7446a51a4db11822c8a752c8f8fff8f80acea0aa..fa68000df584121d2a1524d909a82782774f698a 100644 (file)
@@ -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 (file)
index 0000000..7f05a89
--- /dev/null
@@ -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
+}