Skip to content

Commit 7c946f0

Browse files
authored
[GlobalOpt] Don't resolve aliased ifuncs with undefined resolvees. (#96220)
Fixes #96197. A global alias should always point to a definition. Ifuncs are definitions, so far so good. However an ifunc may be statically resolved to a function that is declared but not defined in the translation unit. With this patch we perform static resolution if: * the resolvee is defined, else if * none of the ifunc users is a global alias
1 parent c6a257f commit 7c946f0

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

llvm/lib/Transforms/IPO/GlobalOpt.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2458,7 +2458,9 @@ static bool OptimizeStaticIFuncs(Module &M) {
24582458
bool Changed = false;
24592459
for (GlobalIFunc &IF : M.ifuncs())
24602460
if (Function *Callee = hasSideeffectFreeStaticResolution(IF))
2461-
if (!IF.use_empty()) {
2461+
if (!IF.use_empty() &&
2462+
(!Callee->isDeclaration() ||
2463+
none_of(IF.users(), [](User *U) { return isa<GlobalAlias>(U); }))) {
24622464
IF.replaceAllUsesWith(Callee);
24632465
NumIFuncsResolved++;
24642466
Changed = true;

llvm/test/Transforms/GlobalOpt/resolve-static-ifunc.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ target triple = "aarch64-unknown-linux-gnu"
77
@trivial.ifunc = internal ifunc void (), ptr @trivial.resolver
88
;.
99
; CHECK: @unknown_condition = external local_unnamed_addr global i1
10+
; CHECK: @alias_decl = weak_odr alias void (), ptr @aliased_decl.ifunc
11+
; CHECK: @alias_def = weak_odr alias void (), ptr @aliased_def._Msimd
1012
; CHECK: @external_ifunc.ifunc = dso_local ifunc void (), ptr @external_ifunc.resolver
1113
; CHECK: @complex.ifunc = internal ifunc void (), ptr @complex.resolver
1214
; CHECK: @sideeffects.ifunc = internal ifunc void (), ptr @sideeffects.resolver
1315
; CHECK: @interposable_ifunc.ifunc = internal ifunc void (), ptr @interposable_ifunc.resolver
1416
; CHECK: @interposable_resolver.ifunc = weak ifunc void (), ptr @interposable_resolver.resolver
17+
; CHECK: @aliased_decl.ifunc = weak_odr ifunc void (), ptr @aliased_decl.resolver
18+
; CHECK: @aliased_def.ifunc = weak_odr ifunc void (), ptr @aliased_def.resolver
1519
;.
1620
define ptr @trivial.resolver() {
1721
ret ptr @trivial._Msimd
@@ -89,6 +93,20 @@ define void @interposable_resolver.default() {
8993
ret void
9094
}
9195

96+
@alias_decl = weak_odr alias void (), ptr @aliased_decl.ifunc
97+
@aliased_decl.ifunc = weak_odr ifunc void (), ptr @aliased_decl.resolver
98+
declare void @aliased_decl._Msimd()
99+
define ptr @aliased_decl.resolver() {
100+
ret ptr @aliased_decl._Msimd
101+
}
102+
103+
@alias_def = weak_odr alias void (), ptr @aliased_def.ifunc
104+
@aliased_def.ifunc = weak_odr ifunc void (), ptr @aliased_def.resolver
105+
define void @aliased_def._Msimd() { ret void }
106+
define ptr @aliased_def.resolver() {
107+
ret ptr @aliased_def._Msimd
108+
}
109+
92110
define void @caller() {
93111
; CHECK-LABEL: define void @caller() local_unnamed_addr {
94112
; CHECK-NEXT: call void @trivial._Msimd()
@@ -97,6 +115,8 @@ define void @caller() {
97115
; CHECK-NEXT: call void @sideeffects.ifunc()
98116
; CHECK-NEXT: call void @interposable_ifunc.ifunc()
99117
; CHECK-NEXT: call void @interposable_resolver.ifunc()
118+
; CHECK-NEXT: call void @aliased_decl.ifunc()
119+
; CHECK-NEXT: call void @aliased_def._Msimd()
100120
; CHECK-NEXT: ret void
101121
;
102122
call void @trivial.ifunc()
@@ -105,5 +125,7 @@ define void @caller() {
105125
call void @sideeffects.ifunc()
106126
call void @interposable_ifunc.ifunc()
107127
call void @interposable_resolver.ifunc()
128+
call void @aliased_decl.ifunc()
129+
call void @aliased_def.ifunc()
108130
ret void
109131
}

0 commit comments

Comments
 (0)