diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2944,9 +2944,11 @@ Constant *Aliasee = J->getAliasee(); GlobalValue *Target = dyn_cast(Aliasee->stripPointerCasts()); // We can't trivially replace the alias with the aliasee if the aliasee is - // non-trivial in some way. + // non-trivial in some way. We also can't replace the alias with the aliasee + // if the aliasee is interposable because aliases point to the local + // definition. // TODO: Try to handle non-zero GEPs of local aliasees. - if (!Target) + if (!Target || Target->isInterposable()) continue; Target->removeDeadConstantUsers(); diff --git a/llvm/test/Transforms/GlobalOpt/alias-resolve.ll b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll --- a/llvm/test/Transforms/GlobalOpt/alias-resolve.ll +++ b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll @@ -16,11 +16,19 @@ @foo4 = weak_odr unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @bar4, i32 0, i32 1) ; CHECK: @foo4 = weak_odr unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @bar4, i32 0, i32 1) +@priva = private alias void (), void ()* @bar5 +; CHECK: @priva = private alias void (), void ()* @bar5 + define void @bar2() { ret void } ; CHECK: define void @bar2() +define weak void @bar5() { + ret void +} +; CHECK: define weak void @bar5() + define void @baz() { entry: call void @foo1() @@ -34,6 +42,10 @@ call void @weak1() ; CHECK: call void @weak1() + + call void @priva() +; CHECK: call void @priva() + ret void }