Skip to content

Commit c20f3dd

Browse files
committed
[MergeFuncs] Don't introduce calls to weak_odr functions.
Avoid creating new calls to weak_odr functions when merging 2 functions. Consider 2 functions below, both present in 2 modules. Without this patch, MergeFuncs in the first module may optimize A to call B and in the second module B to call A. Note that the 2 optimizations are vaild in isolation, but the linker then could pick A from module 1 (which calls B) and B from module 2 which calls A, introducing an infinte call cycle. There may be other linkage types we need to be more careful about as well. define weak_odr hidden void @"A"(ptr %p) { entry: tail call void @"foo"(ptr %p) ret void } define weak_odr hidden void @"B"(ptr %p) { entry: tail call void @"foo"(ptr %p) ret void }
1 parent 9418e74 commit c20f3dd

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

llvm/lib/Transforms/IPO/MergeFunctions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,8 @@ bool MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
891891

892892
// Merge two equivalent functions. Upon completion, Function G is deleted.
893893
void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
894-
if (F->isInterposable()) {
895-
assert(G->isInterposable());
894+
if (F->isInterposable() || G->hasWeakODRLinkage()) {
895+
assert(G->isInterposable() || G->hasWeakODRLinkage());
896896

897897
// Both writeThunkOrAlias() calls below must succeed, either because we can
898898
// create aliases for G and NewF, or because a thunk for F is profitable.

llvm/test/Transforms/MergeFunc/merge-weak-odr.ll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ entry:
5454
}
5555

5656
declare void @zar(ptr)
57-
; CHECK-LABEL: define weak_odr hidden void @weak_odr_caller_of_foo_1(
57+
; CHECK-LABEL: define private void @0(
5858
; CHECK-SAME: ptr [[P:%.*]]) {
5959
; CHECK-NEXT: [[ENTRY:.*:]]
6060
; CHECK-NEXT: tail call void @foo(ptr [[P]])
@@ -72,7 +72,7 @@ declare void @zar(ptr)
7272
; CHECK-NEXT: ret void
7373
;
7474
;
75-
; CHECK-LABEL: define hidden void @non_weak_caller_of_zar_1(
75+
; CHECK-LABEL: define private void @1(
7676
; CHECK-SAME: ptr [[P:%.*]]) {
7777
; CHECK-NEXT: [[ENTRY:.*:]]
7878
; CHECK-NEXT: tail call void @zar(ptr [[P]])
@@ -83,7 +83,13 @@ declare void @zar(ptr)
8383
;
8484
; CHECK-LABEL: define weak_odr hidden void @weak_odr_caller_of_foo_2(
8585
; CHECK-SAME: ptr [[TMP0:%.*]]) {
86-
; CHECK-NEXT: tail call void @weak_odr_caller_of_foo_1(ptr [[TMP0]])
86+
; CHECK-NEXT: tail call void @[[GLOB0:[0-9]+]](ptr [[TMP0]])
87+
; CHECK-NEXT: ret void
88+
;
89+
;
90+
; CHECK-LABEL: define weak_odr hidden void @weak_odr_caller_of_foo_1(
91+
; CHECK-SAME: ptr [[TMP0:%.*]]) {
92+
; CHECK-NEXT: tail call void @[[GLOB0]](ptr [[TMP0]])
8793
; CHECK-NEXT: ret void
8894
;
8995
;
@@ -95,6 +101,12 @@ declare void @zar(ptr)
95101
;
96102
; CHECK-LABEL: define weak_odr hidden void @weak_odr_caller_of_zar_2(
97103
; CHECK-SAME: ptr [[TMP0:%.*]]) {
98-
; CHECK-NEXT: tail call void @non_weak_caller_of_zar_1(ptr [[TMP0]])
104+
; CHECK-NEXT: tail call void @[[GLOB1:[0-9]+]](ptr [[TMP0]])
105+
; CHECK-NEXT: ret void
106+
;
107+
;
108+
; CHECK-LABEL: define hidden void @non_weak_caller_of_zar_1(
109+
; CHECK-SAME: ptr [[TMP0:%.*]]) {
110+
; CHECK-NEXT: tail call void @[[GLOB1]](ptr [[TMP0]])
99111
; CHECK-NEXT: ret void
100112
;

0 commit comments

Comments
 (0)