[IR] Reject inlining strictfp alwaysinline callee into non-strictfp caller (#210701)
Commitaf0c933edaadded a verifier check requiring every strictfp call site to reside in a strictfp function. It caused verify error `call site marked strictfp without caller function marked strictfp` since AlwaysInliner force-inlines strictfp callees into non-strictfp callers, bypassing checkStrictFP.47b3b76825explictly not implemented inlining strictfp function into non-strictfp function. But the restriction was lost in8eb6757564.8eb6757564was only NFC for the normal inliner pass. It regressed AlwaysInliner path which bypasses checkStrictFP. This PR restores the restriction. --------- Co-authored-by: Jinsong Ji <jinsong.ji@intel.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Nikita Popov <github@npopov.com>
This commit is contained in:
parent
4138dc431a
commit
a2b42b10a1
4 changed files with 42 additions and 0 deletions
|
|
@ -1393,6 +1393,11 @@ LLVM_ABI AttributeMask getUBImplyingAttributes();
|
|||
LLVM_ABI bool areInlineCompatible(const Function &Caller,
|
||||
const Function &Callee);
|
||||
|
||||
/// \returns Return false if callee is strictfp and caller is not. Return true
|
||||
/// otherwise.
|
||||
LLVM_ABI bool isStrictFPInlineCompatible(const Function &Caller,
|
||||
const Function &Callee);
|
||||
|
||||
/// Checks if there are any incompatible function attributes between
|
||||
/// \p A and \p B.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -3210,6 +3210,9 @@ std::optional<InlineResult> llvm::getAttributeBasedInliningDecision(
|
|||
if (Call.getAttributes().hasFnAttr(Attribute::NoInline))
|
||||
return InlineResult::failure("noinline call site attribute");
|
||||
|
||||
if (!AttributeFuncs::isStrictFPInlineCompatible(*Caller, *Callee))
|
||||
return InlineResult::failure("incompatible strictfp attributes");
|
||||
|
||||
auto IsViable = isInlineViable(*Callee);
|
||||
if (IsViable.isSuccess())
|
||||
return InlineResult::success();
|
||||
|
|
|
|||
|
|
@ -2785,6 +2785,11 @@ bool AttributeFuncs::areInlineCompatible(const Function &Caller,
|
|||
return hasCompatibleFnAttrs(Caller, Callee);
|
||||
}
|
||||
|
||||
bool AttributeFuncs::isStrictFPInlineCompatible(const Function &Caller,
|
||||
const Function &Callee) {
|
||||
return checkStrictFP(Caller, Callee);
|
||||
}
|
||||
|
||||
bool AttributeFuncs::areOutlineCompatible(const Function &A,
|
||||
const Function &B) {
|
||||
return hasCompatibleFnAttrs(A, B);
|
||||
|
|
|
|||
29
llvm/test/Transforms/Inline/always-inline-strictfp.ll
Normal file
29
llvm/test/Transforms/Inline/always-inline-strictfp.ll
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: opt -passes=always-inline %s -S | FileCheck %s
|
||||
|
||||
; Check strictfp alwaysinline callee isn't inlined into non-strictfp caller.
|
||||
|
||||
declare void @foo()
|
||||
|
||||
define void @callee() alwaysinline strictfp {
|
||||
; CHECK-LABEL: define void @callee(
|
||||
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: call void @foo() #[[ATTR1:[0-9]+]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
call void @foo() strictfp
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @caller() {
|
||||
; CHECK-LABEL: define void @caller() {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: call void @callee()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
call void @callee()
|
||||
ret void
|
||||
}
|
||||
Loading…
Reference in a new issue