[llvm] [GlobalOpt] Don't replace aliasee with alias that has weak linkage (PR #91483)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 9 07:19:02 PDT 2024
https://github.com/DianQK updated https://github.com/llvm/llvm-project/pull/91483
>From 937ab674ce246630600b0537336a1c4f890c079b Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Thu, 9 May 2024 21:23:06 +0800
Subject: [PATCH 1/3] Pre-commit test cases
---
llvm/test/Transforms/GlobalOpt/alias-weak.ll | 52 ++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 llvm/test/Transforms/GlobalOpt/alias-weak.ll
diff --git a/llvm/test/Transforms/GlobalOpt/alias-weak.ll b/llvm/test/Transforms/GlobalOpt/alias-weak.ll
new file mode 100644
index 0000000000000..4b7d4f3e364eb
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/alias-weak.ll
@@ -0,0 +1,52 @@
+; 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
+
+ at f1_alias = linkonce_odr hidden alias void (), ptr @f1
+ at 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
+}
+
+; FIXME: 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
+}
+
+define internal void @f2() {
+ ret void
+}
+; 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_alias()
+; 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 linkonce_odr hidden void @f1_alias() local_unnamed_addr {
+; CHECK-NEXT: ret void
+;
+;
+; CHECK-LABEL: define linkonce_odr hidden void @f2_alias() local_unnamed_addr {
+; CHECK-NEXT: ret void
+;
>From ab7be415ab419c2c94adc560b4a05ef6dba27642 Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Wed, 8 May 2024 22:33:05 +0800
Subject: [PATCH 2/3] [GlobalOpt] Don't replace aliasee with alias that has
weak linkage
---
llvm/lib/Transforms/IPO/GlobalOpt.cpp | 3 +++
llvm/test/Transforms/GlobalOpt/alias-weak.ll | 13 +++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
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
index 4b7d4f3e364eb..aec2a56313b12 100644
--- a/llvm/test/Transforms/GlobalOpt/alias-weak.ll
+++ b/llvm/test/Transforms/GlobalOpt/alias-weak.ll
@@ -19,22 +19,27 @@ define void @baz() {
ret void
}
-; FIXME: We cannot use `f1_alias` to replace `f1` because they are both in use
+; 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_alias()
+; CHECK-NEXT: call void @f1()
; CHECK-NEXT: ret void
;
;
@@ -43,10 +48,10 @@ define internal void @f2() {
; CHECK-NEXT: ret void
;
;
-; CHECK-LABEL: define linkonce_odr hidden void @f1_alias() local_unnamed_addr {
+; CHECK-LABEL: define internal void @f1() {
; CHECK-NEXT: ret void
;
;
-; CHECK-LABEL: define linkonce_odr hidden void @f2_alias() local_unnamed_addr {
+; CHECK-LABEL: define internal void @f2() {
; CHECK-NEXT: ret void
;
>From b901a982d8e618d13049e5a804d19bce30fbac3c Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Thu, 9 May 2024 20:45:18 +0800
Subject: [PATCH 3/3] [GlobalOpt] Replace aliasee if it is not in use
---
llvm/lib/Transforms/IPO/GlobalOpt.cpp | 21 ++++++++++++++++---
llvm/test/Transforms/GlobalOpt/alias-weak.ll | 5 ++---
.../cfi-nounwind-direct-call.ll | 4 ++--
.../LowerTypeTests/cfi-unwind-direct-call.ll | 8 +++----
4 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index b7c6d25657bc0..d6a8609b7c328 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2215,6 +2215,17 @@ static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U) {
return !U.usedCount(&GA) && !U.compilerUsedCount(&GA);
}
+static bool hasMoreThanOneUseOtherThanLLVMUsed(GlobalValue &V,
+ const LLVMUsed &U) {
+ unsigned N = 2;
+ assert((!U.usedCount(&V) || !U.compilerUsedCount(&V)) &&
+ "We should have removed the duplicated "
+ "element from llvm.compiler.used");
+ if (U.usedCount(&V) || U.compilerUsedCount(&V))
+ ++N;
+ return V.hasNUsesOrMore(N);
+}
+
static bool mayHaveOtherReferences(GlobalValue &GV, const LLVMUsed &U) {
if (!GV.hasLocalLinkage())
return true;
@@ -2224,9 +2235,6 @@ 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))
@@ -2245,6 +2253,13 @@ static bool hasUsesToReplace(GlobalAlias &GA, const LLVMUsed &U,
// define ... @a(...)
Constant *Aliasee = GA.getAliasee();
GlobalValue *Target = cast<GlobalValue>(Aliasee->stripPointerCasts());
+ // Don't perform the transform if the alias may be replaced at link time while
+ // someone is using the aliasee (e.g., multiple aliases potentially target it
+ // or someone calls it).
+ if (GA.isWeakForLinker())
+ Ret = false;
+ if (hasMoreThanOneUseOtherThanLLVMUsed(*Target, U))
+ return Ret;
if (mayHaveOtherReferences(*Target, U))
return Ret;
diff --git a/llvm/test/Transforms/GlobalOpt/alias-weak.ll b/llvm/test/Transforms/GlobalOpt/alias-weak.ll
index aec2a56313b12..e24085f00d714 100644
--- a/llvm/test/Transforms/GlobalOpt/alias-weak.ll
+++ b/llvm/test/Transforms/GlobalOpt/alias-weak.ll
@@ -25,13 +25,12 @@ define internal void @f1() {
ret void
}
-; FIXME: We can use `f2_alias` to replace `f2` because `b2` is not in use.
+; 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()
@@ -52,6 +51,6 @@ define internal void @f2() {
; CHECK-NEXT: ret void
;
;
-; CHECK-LABEL: define internal void @f2() {
+; CHECK-LABEL: define linkonce_odr hidden void @f2_alias() local_unnamed_addr {
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
index 2795333effd76..f05befb10658b 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
@@ -121,7 +121,7 @@ attributes #6 = { noreturn nounwind }
; CHECK-LABEL: define dso_local noundef range(i32 0, 2) i32 @_Z10call_catchi
; CHECK-SAME: (i32 noundef [[NUM:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !type [[META4]] !type [[META5]] !type [[META6]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: store ptr @_Z9nothrow_ei.cfi_jt, ptr @catch_ptr, align 8, !tbaa [[TBAA7:![0-9]+]]
+; CHECK-NEXT: store ptr @.cfi.jumptable, ptr @catch_ptr, align 8, !tbaa [[TBAA7:![0-9]+]]
; CHECK-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp ne i32 [[NUM]], 0
; CHECK-NEXT: [[DOT_I:%.*]] = zext i1 [[TOBOOL_NOT_I]] to i32
; CHECK-NEXT: ret i32 [[DOT_I]]
@@ -152,7 +152,7 @@ attributes #6 = { noreturn nounwind }
;
;
; CHECK: Function Attrs: naked nocf_check noinline nounwind
-; CHECK-LABEL: define internal void @_Z9nothrow_ei.cfi_jt
+; CHECK-LABEL: define private void @.cfi.jumptable
; CHECK-SAME: () #[[ATTR5:[0-9]+]] align 8 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z9nothrow_ei) #[[ATTR7:[0-9]+]]
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
index 3e1f8b97e98b8..ca540a1cc5f97 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll
@@ -174,8 +174,8 @@ attributes #8 = { noreturn nounwind }
; CHECK-LABEL: define dso_local void @_Z10call_catchi(
; CHECK-SAME: i32 noundef [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] personality ptr @__gxx_personality_v0 !type [[META4]] !type [[META5]] !type [[META6]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: store ptr @_Z7throw_ei.cfi_jt, ptr @catch_ptr, align 8, !tbaa [[TBAA11:![0-9]+]]
-; CHECK-NEXT: invoke void @_Z7throw_ei.cfi_jt(i32 noundef [[NUM]]) #[[ATTR8:[0-9]+]]
+; CHECK-NEXT: store ptr @.cfi.jumptable, ptr @catch_ptr, align 8, !tbaa [[TBAA11:![0-9]+]]
+; CHECK-NEXT: invoke void @.cfi.jumptable(i32 noundef [[NUM]]) #[[ATTR8:[0-9]+]]
; CHECK-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]], !callees [[META13:![0-9]+]]
; CHECK: lpad:
; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 }
@@ -220,7 +220,7 @@ attributes #8 = { noreturn nounwind }
;
;
; CHECK: Function Attrs: naked nocf_check noinline
-; CHECK-LABEL: define internal void @_Z7throw_ei.cfi_jt(
+; CHECK-LABEL: define private void @.cfi.jumptable(
; CHECK-SAME: ) #[[ATTR5:[0-9]+]] align 8 {
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z7throw_ei) #[[ATTR6]]
@@ -236,6 +236,6 @@ attributes #8 = { noreturn nounwind }
; CHECK: [[META10]] = !{!"Simple C++ TBAA"}
; CHECK: [[TBAA11]] = !{[[META12:![0-9]+]], [[META12]], i64 0}
; CHECK: [[META12]] = !{!"any pointer", [[META9]], i64 0}
-; CHECK: [[META13]] = !{ptr @_Z7throw_ei.cfi_jt}
+; CHECK: [[META13]] = !{ptr @.cfi.jumptable}
; CHECK: [[META14]] = !{}
;.
More information about the llvm-commits
mailing list