[llvm] [FunctionAttr] Invalid callers with mismatching signature (PR #154289)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 19 01:34:53 PDT 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/154289
If FunctionAttrs infers additional attributes on a function, it also invalidates analysis on callers of that function. The way it does this right now limits this to calls with matching signature. However, the function attributes will also be used when the signatures do not match. Use getCalledOperand() to avoid a signature check.
This is not a correctness fix, just improves analysis quality. I noticed this due to https://github.com/llvm/llvm-project/pull/144497#issuecomment-3199330709, where LICM ends up with a stale MemoryDef that could be a MemoryUse (which is a bug in LICM, but still non-optimal).
>From 1cd6f9c8df336d754aac22ef8a90bc881dcba564 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 19 Aug 2025 10:29:42 +0200
Subject: [PATCH 1/2] Add test
---
.../mismatched-signature-invalidation.ll | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
create mode 100644 llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
diff --git a/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll b/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
new file mode 100644
index 0000000000000..5fc91eeb19794
--- /dev/null
+++ b/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
@@ -0,0 +1,31 @@
+; RUN: opt -disable-output -passes="function(print<memoryssa>),cgscc(function-attrs),function(print<memoryssa>)" < %s 2>&1 | FileCheck %s
+
+ at g = external global i16
+
+define i16 @fn() {
+ %v = load i16, ptr @g
+ ret i16 %v
+}
+
+declare void @fn2(i16)
+
+; CHECK-LABEL: MemorySSA for function: test
+; CHECK: 1 = MemoryDef(3)
+; CHECK-NEXT: %call = call i16 @fn(i32 0)
+
+; CHECK-LABEL: MemorySSA for function: test
+; CHECK: 1 = MemoryDef(3)
+; CHECK-NEXT: %call = call i16 @fn(i32 0)
+
+define void @test() {
+entry:
+ br label %loop
+
+loop:
+ %call = call i16 @fn(i32 0) ; intentional signature mismatch
+ call void @fn2(i16 %call)
+ br i1 false, label %loop, label %exit
+
+exit:
+ ret void
+}
>From 075b5871be6c9afa98d1c0ed334659deb970774b Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 19 Aug 2025 10:30:23 +0200
Subject: [PATCH 2/2] [FunctionAttrs] Invalidate callers even on signature
mismatch
---
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 2 +-
.../FunctionAttrs/mismatched-signature-invalidation.ll | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 44394f6deb9a2..7d367fcb21012 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -2328,7 +2328,7 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
// through function attributes.
for (auto *U : Changed->users()) {
if (auto *Call = dyn_cast<CallBase>(U)) {
- if (Call->getCalledFunction() == Changed)
+ if (Call->getCalledOperand() == Changed)
FAM.invalidate(*Call->getFunction(), FuncPA);
}
}
diff --git a/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll b/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
index 5fc91eeb19794..c42535756e8f1 100644
--- a/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
+++ b/llvm/test/Transforms/FunctionAttrs/mismatched-signature-invalidation.ll
@@ -14,7 +14,7 @@ declare void @fn2(i16)
; CHECK-NEXT: %call = call i16 @fn(i32 0)
; CHECK-LABEL: MemorySSA for function: test
-; CHECK: 1 = MemoryDef(3)
+; CHECK: MemoryUse(2)
; CHECK-NEXT: %call = call i16 @fn(i32 0)
define void @test() {
More information about the llvm-commits
mailing list