[FunctionAttr] Invalidate callers with mismatching signature (#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).
This commit is contained in:
Nikita Popov 2025-08-20 11:38:31 +02:00 committed by GitHub
parent 5dbf73f54d
commit 5ae749b77d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 1 deletions

View File

@ -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);
}
}

View File

@ -0,0 +1,31 @@
; RUN: opt -disable-output -passes="function(print<memoryssa>),cgscc(function-attrs),function(print<memoryssa>)" < %s 2>&1 | FileCheck %s
@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: MemoryUse(2)
; 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
}