diff options
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 4 | ||||
-rw-r--r-- | test/Transforms/InstCombine/align-external.ll | 13 |
3 files changed, 15 insertions, 4 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 8192c1471f..58adc26a1d 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -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); diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 134ab71050..bbbfcba470 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -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(); diff --git a/test/Transforms/InstCombine/align-external.ll b/test/Transforms/InstCombine/align-external.ll index 6e8ad87f19..d4a5d42991 100644 --- a/test/Transforms/InstCombine/align-external.ll +++ b/test/Transforms/InstCombine/align-external.ll @@ -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 +} |