Fix a theoretical problem (not seen in the wild): if different instances of a
authorDuncan Sands <baldrick@free.fr>
Tue, 29 Nov 2011 18:26:38 +0000 (18:26 +0000)
committerDuncan Sands <baldrick@free.fr>
Tue, 29 Nov 2011 18:26:38 +0000 (18:26 +0000)
weak variable are compiled by different compilers, such as GCC and LLVM, while
LLVM may increase the alignment to the preferred alignment there is no reason to
think that GCC will use anything more than the ABI alignment.  Since it is the
GCC version that might end up in the final program (as the linkage is weak), it
is wrong to increase the alignment of loads from the global up to the preferred
alignment as the alignment might only be the ABI alignment.

Increasing alignment up to the ABI alignment might be OK, but I'm not totally
convinced that it is.  It seems better to just leave the alignment of weak
globals alone.

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

lib/Analysis/ValueTracking.cpp
lib/Transforms/Utils/Local.cpp
test/Transforms/InstCombine/align-external.ll

index 8192c1471fc6e623096335a32a8546f06c8298f7..58adc26a1d7543589b770c52bd251744bb47e06b 100644 (file)
@@ -108,7 +108,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
         // If the object is defined in the current Module, we'll be giving
         // it the preferred alignment. Otherwise, we have to assume that it
         // may only have the minimum ABI alignment.
-        if (!GVar->isDeclaration() && !GVar->mayBeOverridden())
+        if (!GVar->isDeclaration() && !GVar->isWeakForLinker())
           Align = TD->getPreferredAlignment(GVar);
         else
           Align = TD->getABITypeAlignment(ObjectType);
index 134ab71050a33e384e01b9ef992d553c2e2b9ba4..bbbfcba4709c0db51a852aea6e38f40e80783928 100644 (file)
@@ -748,6 +748,10 @@ static unsigned enforceKnownAlignment(Value *V, unsigned Align,
     // If there is a large requested alignment and we can, bump up the alignment
     // of the global.
     if (GV->isDeclaration()) return Align;
+    // If the memory we set aside for the global may not be the memory used by
+    // the final program then it is impossible for us to reliably enforce the
+    // preferred alignment.
+    if (GV->isWeakForLinker()) return Align;
     
     if (GV->getAlignment() >= PrefAlign)
       return GV->getAlignment();
index 6e8ad87f19e057a02b78311d2be2146855568d6f..d4a5d429912bf25e030c1baaced8a60913c049f1 100644 (file)
@@ -1,7 +1,7 @@
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 
-; Don't assume that external global variables have their preferred
-; alignment. They may only have the ABI minimum alignment.
+; Don't assume that external global variables or those with weak linkage have
+; their preferred alignment. They may only have the ABI minimum alignment.
 
 ; CHECK: %s = shl i64 %a, 3
 ; CHECK: %r = or i64 %s, ptrtoint (i32* @A to i64)
@@ -11,7 +11,7 @@
 target datalayout = "-i32:8:32"
 
 @A = external global i32
-@B = external global i32
+@B = weak_odr global i32 0
 
 define i64 @foo(i64 %a) {
   %t = ptrtoint i32* @A to i64
@@ -20,3 +20,10 @@ define i64 @foo(i64 %a) {
   %q = add i64 %r, 1
   ret i64 %q
 }
+
+define i32 @bar() {
+; CHECK: @bar
+  %r = load i32* @B, align 1
+; CHECK: align 1
+  ret i32 %r
+}