diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index a1e1a51b201b0..9e9e7689d808a 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -259,11 +259,15 @@ AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA, if (!Initializer) return nullptr; } else { - if (!GV->hasLocalLinkage() && - (GV->isInterposable() || !(GV->isConstant() && GV->hasInitializer()))) - return nullptr; - if (!GV->hasInitializer()) - return UndefValue::get(&Ty); + if (!GV->hasLocalLinkage()) { + // Externally visible global that's either non-constant, + // or a constant with an uncertain initializer. + if (!GV->hasDefinitiveInitializer() || !GV->isConstant()) + return nullptr; + } + + // Globals with local linkage are always initialized. + assert(!GV->hasLocalLinkage() || GV->hasInitializer()); if (!Initializer) Initializer = GV->getInitializer(); diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll index a90fb54fbe74a..59160c0834980 100644 --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -12,6 +12,7 @@ declare ptr @llvm.call.preallocated.arg(token, i32) @ConstPtr = constant i32 0, align 4 @ConstWeakPtr = weak constant i32 0, align 4 @ConstWeakODRPtr = weak_odr constant i32 0, align 4 +@ExtInitZeroInit = externally_initialized constant i32 zeroinitializer, align 4 ;. ; CHECK: @str = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 1 @@ -19,6 +20,7 @@ declare ptr @llvm.call.preallocated.arg(token, i32) ; CHECK: @ConstPtr = constant i32 0, align 4 ; CHECK: @ConstWeakPtr = weak constant i32 0, align 4 ; CHECK: @ConstWeakODRPtr = weak_odr constant i32 0, align 4 +; CHECK: @ExtInitZeroInit = externally_initialized constant i32 0, align 4 ; CHECK: @S = external global %struct.X ; CHECK: @g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] } ; CHECK: @x = external global i32 @@ -1651,6 +1653,23 @@ define i32 @readWeakOdrConst() { ret i32 %l } +define i32 @readExtInitZeroInit() { +; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; TUNIT-LABEL: define {{[^@]+}}@readExtInitZeroInit +; TUNIT-SAME: () #[[ATTR2]] { +; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 4 +; TUNIT-NEXT: ret i32 [[L]] +; +; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CGSCC-LABEL: define {{[^@]+}}@readExtInitZeroInit +; CGSCC-SAME: () #[[ATTR1]] { +; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 4 +; CGSCC-NEXT: ret i32 [[L]] +; + %l = load i32, ptr @ExtInitZeroInit + ret i32 %l +} + ;. ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; TUNIT: attributes #[[ATTR1]] = { memory(readwrite, argmem: none) }