-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[GlobalOpt] Don't resolve aliased ifuncs with undefined resolvees. #96220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes llvm#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 * otherwise none of the ifunc users is a global alias
@llvm/pr-subscribers-llvm-transforms Author: Alexandros Lamprineas (labrinea) ChangesFixes #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:
Full diff: https://github.com/llvm/llvm-project/pull/96220.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index b7c6d25657bc0..411a8454bf18b 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2458,7 +2458,9 @@ static bool OptimizeStaticIFuncs(Module &M) {
bool Changed = false;
for (GlobalIFunc &IF : M.ifuncs())
if (Function *Callee = hasSideeffectFreeStaticResolution(IF))
- if (!IF.use_empty()) {
+ if (!IF.use_empty() &&
+ (!Callee->isDeclaration() ||
+ none_of(IF.users(), [](User *U) { return isa<GlobalAlias>(U); }))) {
IF.replaceAllUsesWith(Callee);
NumIFuncsResolved++;
Changed = true;
diff --git a/llvm/test/Transforms/GlobalOpt/resolve-static-ifunc.ll b/llvm/test/Transforms/GlobalOpt/resolve-static-ifunc.ll
index 2a1717304fb4c..de087343208c7 100644
--- a/llvm/test/Transforms/GlobalOpt/resolve-static-ifunc.ll
+++ b/llvm/test/Transforms/GlobalOpt/resolve-static-ifunc.ll
@@ -7,11 +7,15 @@ target triple = "aarch64-unknown-linux-gnu"
@trivial.ifunc = internal ifunc void (), ptr @trivial.resolver
;.
; CHECK: @unknown_condition = external local_unnamed_addr global i1
+; CHECK: @alias_decl = weak_odr alias void (), ptr @aliased_decl.ifunc
+; CHECK: @alias_def = weak_odr alias void (), ptr @aliased_def._Msimd
; CHECK: @external_ifunc.ifunc = dso_local ifunc void (), ptr @external_ifunc.resolver
; CHECK: @complex.ifunc = internal ifunc void (), ptr @complex.resolver
; CHECK: @sideeffects.ifunc = internal ifunc void (), ptr @sideeffects.resolver
; CHECK: @interposable_ifunc.ifunc = internal ifunc void (), ptr @interposable_ifunc.resolver
; CHECK: @interposable_resolver.ifunc = weak ifunc void (), ptr @interposable_resolver.resolver
+; CHECK: @aliased_decl.ifunc = weak_odr ifunc void (), ptr @aliased_decl.resolver
+; CHECK: @aliased_def.ifunc = weak_odr ifunc void (), ptr @aliased_def.resolver
;.
define ptr @trivial.resolver() {
ret ptr @trivial._Msimd
@@ -89,6 +93,20 @@ define void @interposable_resolver.default() {
ret void
}
+@alias_decl = weak_odr alias void (), ptr @aliased_decl.ifunc
+@aliased_decl.ifunc = weak_odr ifunc void (), ptr @aliased_decl.resolver
+declare void @aliased_decl._Msimd()
+define ptr @aliased_decl.resolver() {
+ ret ptr @aliased_decl._Msimd
+}
+
+@alias_def = weak_odr alias void (), ptr @aliased_def.ifunc
+@aliased_def.ifunc = weak_odr ifunc void (), ptr @aliased_def.resolver
+define void @aliased_def._Msimd() { ret void }
+define ptr @aliased_def.resolver() {
+ ret ptr @aliased_def._Msimd
+}
+
define void @caller() {
; CHECK-LABEL: define void @caller() local_unnamed_addr {
; CHECK-NEXT: call void @trivial._Msimd()
@@ -97,6 +115,8 @@ define void @caller() {
; CHECK-NEXT: call void @sideeffects.ifunc()
; CHECK-NEXT: call void @interposable_ifunc.ifunc()
; CHECK-NEXT: call void @interposable_resolver.ifunc()
+; CHECK-NEXT: call void @aliased_decl.ifunc()
+; CHECK-NEXT: call void @aliased_def._Msimd()
; CHECK-NEXT: ret void
;
call void @trivial.ifunc()
@@ -105,5 +125,7 @@ define void @caller() {
call void @sideeffects.ifunc()
call void @interposable_ifunc.ifunc()
call void @interposable_resolver.ifunc()
+ call void @aliased_decl.ifunc()
+ call void @aliased_def.ifunc()
ret void
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/582 Here is the relevant piece of the build log for the reference:
|
…lvm#96220) Fixes llvm#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
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: