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 @@ -2932,16 +2932,15 @@ continue; } - // If the alias can change at link time, nothing can be done - bail out. - if (J->isInterposable()) - continue; - Constant *Aliasee = J->getAliasee(); - GlobalValue *Target = dyn_cast(Aliasee->stripPointerCasts()); + GlobalValue *Target = + dyn_cast(Aliasee->stripPointerCastsAndAliases()); // 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 @@ -33,7 +33,10 @@ ; CHECK: call void @bar2() call void @weak1() -; CHECK: call void @weak1() +; CHECK: call void @bar2() + + call void @bar6() +; CHECK: call void @bar6() ret void } @@ -44,3 +47,9 @@ ret void } ;CHECK: define void @foo3 + +define weak void @bar5() { + ret void +} + +@bar6 = alias void(), void ()* @bar5