diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index c8c835115a992..b7c6d25657bc0 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2224,6 +2224,9 @@ static bool mayHaveOtherReferences(GlobalValue &GV, const LLVMUsed &U) { static bool hasUsesToReplace(GlobalAlias &GA, const LLVMUsed &U, bool &RenameTarget) { + if (GA.isWeakForLinker()) + return false; + RenameTarget = false; bool Ret = false; if (hasUseOtherThanLLVMUsed(GA, U)) diff --git a/llvm/test/Transforms/GlobalOpt/alias-weak.ll b/llvm/test/Transforms/GlobalOpt/alias-weak.ll new file mode 100644 index 0000000000000..aec2a56313b12 --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/alias-weak.ll @@ -0,0 +1,57 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 4 +; RUN: opt < %s -passes=globalopt -S | FileCheck %s + +@f1_alias = linkonce_odr hidden alias void (), ptr @f1 +@f2_alias = linkonce_odr hidden alias void (), ptr @f2 + +define void @foo() { + call void @f1_alias() + ret void +} + +define void @bar() { + call void @f1() + ret void +} + +define void @baz() { + call void @f2_alias() + ret void +} + +; We cannot use `f1_alias` to replace `f1` because they are both in use +; and `f1_alias` could be replaced at link time. +define internal void @f1() { + ret void +} + +; FIXME: We can use `f2_alias` to replace `f2` because `b2` is not in use. +define internal void @f2() { + ret void +} +;. +; CHECK: @f1_alias = linkonce_odr hidden alias void (), ptr @f1 +; CHECK: @f2_alias = linkonce_odr hidden alias void (), ptr @f2 +;. +; CHECK-LABEL: define void @foo() local_unnamed_addr { +; CHECK-NEXT: call void @f1_alias() +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: define void @bar() local_unnamed_addr { +; CHECK-NEXT: call void @f1() +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: define void @baz() local_unnamed_addr { +; CHECK-NEXT: call void @f2_alias() +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: define internal void @f1() { +; CHECK-NEXT: ret void +; +; +; CHECK-LABEL: define internal void @f2() { +; CHECK-NEXT: ret void +;