summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Analysis/ValueTracking.cpp2
-rw-r--r--lib/Transforms/Utils/Local.cpp4
-rw-r--r--test/Transforms/InstCombine/align-external.ll13
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
+}