[llvm] [PartiallyInlineLibCalls] Emit missed- and passed-optimization remarks when partially inlining sqrt (PR #123966)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 23 12:10:40 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: None (TiborGY)
<details>
<summary>Changes</summary>
**PR 2/2**
### Introduction
This build on PR #<!-- -->122654 and adds both passed- and missed-optimization remarks to the PartiallyInlineLibCalls pass. This pass is currently only responsible for the partial inlining of sqrt/sqrtf C library calls, on targets that have a fast HW instruction for square root but demand that `errno` is set on invalid input. One such target is x86_64-unknown-linux-gnu.
### About this PR
Before this PR, the pass was silent, which can be confusing if someone is looking at the asm output and finds the branch it is inserting. So I have added a passed-optimization remark.
At the same time this branch may also impede vectorization in some cases, sqrt is often found in scientific code with nested loops, etc. Therefore I have also added a missed-optimization remark alerting the user to the fact that the `errno` requirement is having an effect on optimizations.
I have also added some further missed-optimization remarks that are emitted when a C library call cannot be optimized by the pass due to strict FP exception behavior or a tail call circumstance.
### Testing
I have added some regression testing to the existing tests that I could find for this pass. I am not 100% sure they are good/sufficient tests, but they are passing. Let me know if more testing is required for new opt-remarks.
---
Full diff: https://github.com/llvm/llvm-project/pull/123966.diff
4 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp (+35-3)
- (modified) llvm/test/Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll (+5-1)
- (modified) llvm/test/Transforms/PartiallyInlineLibCalls/X86/musttail.ll (+3-1)
- (modified) llvm/test/Transforms/PartiallyInlineLibCalls/strictfp.ll (+3-1)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp b/llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp
index 2b50ccdc2eeb4f..e56b561ef1f591 100644
--- a/llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp
+++ b/llvm/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp
@@ -56,6 +56,20 @@ static bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
// dst = phi(v0, v1)
//
+ ORE->emit([&]() {
+ return OptimizationRemark(DEBUG_TYPE, "SqrtPartiallyInlined",
+ Call->getDebugLoc(), &CurrBB)
+ << "Partially inlined call to sqrt function despite having to use "
+ "errno for error handling: target has fast sqrt instruction";
+ });
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "BranchInserted",
+ Call->getDebugLoc(), &CurrBB)
+ << "Branch to library sqrt fn had to be inserted to satisfy the "
+ "current target's requirement for math functions to set errno on "
+ "invalid inputs";
+ });
+
Type *Ty = Call->getType();
IRBuilder<> Builder(Call->getNextNode());
@@ -125,11 +139,29 @@ static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI,
if (!Call || !(CalledFunc = Call->getCalledFunction()))
continue;
- if (Call->isNoBuiltin() || Call->isStrictFP())
+ if (Call->isNoBuiltin())
continue;
-
- if (Call->isMustTailCall())
+ if (Call->isStrictFP()) {
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "StrictFloat",
+ Call->getDebugLoc(), &*CurrBB)
+ << "Could not consider library function for partial inlining:"
+ " strict FP exception behavior is active";
+ });
continue;
+ }
+ // Partially inlining a libcall that has the musttail attribute leads to
+ // broken LLVM IR, triggering an assertion in the IR verifier.
+ // Work around that by forgoing this optimization for musttail calls.
+ if (Call->isMustTailCall()) {
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "MustTailCall",
+ Call->getDebugLoc(), &*CurrBB)
+ << "Could not consider library function for partial inlining:"
+ " must tail call";
+ });
+ continue;
+ }
// Skip if function either has local linkage or is not a known library
// function.
diff --git a/llvm/test/Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll b/llvm/test/Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll
index e6c2a7e629a5d6..49a34d9d4a0a6f 100644
--- a/llvm/test/Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll
+++ b/llvm/test/Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll
@@ -1,8 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu -pass-remarks=partially-inline-libcalls \
+; RUN: -pass-remarks-missed=partially-inline-libcalls 2>%t < %s | FileCheck %s
+; RUN: cat %t | FileCheck %s -check-prefix=CHECK-REMARK
define float @f(float %val) {
; CHECK-LABEL: @f(
+; CHECK-REMARK: Partially inlined call to sqrt function despite having to use errno for error handling: target has fast sqrt instruction
+; CHECK-REMARK: Branch to library sqrt fn had to be inserted to satisfy the current target's requirement for math functions to set errno on invalid inputs
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RES:%.*]] = tail call float @sqrtf(float [[VAL:%.*]]) #[[READNONE:.*]]
; CHECK-NEXT: [[TMP0:%.*]] = fcmp oge float [[VAL]], 0.000000e+00
diff --git a/llvm/test/Transforms/PartiallyInlineLibCalls/X86/musttail.ll b/llvm/test/Transforms/PartiallyInlineLibCalls/X86/musttail.ll
index 65dd616b43ea69..c877990df309a0 100644
--- a/llvm/test/Transforms/PartiallyInlineLibCalls/X86/musttail.ll
+++ b/llvm/test/Transforms/PartiallyInlineLibCalls/X86/musttail.ll
@@ -1,8 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu -pass-remarks-missed=partially-inline-libcalls 2>%t < %s | FileCheck %s
+; RUN: cat %t | FileCheck %s -check-prefix=CHECK-REMARK
define double @foo(double %x) {
; CHECK-LABEL: @foo(
+; CHECK-REMARK: Could not consider library function for partial inlining: must tail call
; CHECK-NEXT: [[R:%.*]] = musttail call double @sqrt(double [[X:%.*]])
; CHECK-NEXT: ret double [[R]]
;
diff --git a/llvm/test/Transforms/PartiallyInlineLibCalls/strictfp.ll b/llvm/test/Transforms/PartiallyInlineLibCalls/strictfp.ll
index 8d18d1969b04d3..6a58de096b84a5 100644
--- a/llvm/test/Transforms/PartiallyInlineLibCalls/strictfp.ll
+++ b/llvm/test/Transforms/PartiallyInlineLibCalls/strictfp.ll
@@ -1,7 +1,9 @@
-; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu -pass-remarks-missed=partially-inline-libcalls 2>%t < %s | FileCheck %s
+; RUN: cat %t | FileCheck %s -check-prefix=CHECK-REMARK
define float @f(float %val) strictfp {
; CHECK-LABEL: @f
+; CHECK-REMARK: Could not consider library function for partial inlining: strict FP exception behavior is active
; CHECK: call{{.*}}@sqrtf
; CHECK-NOT: call{{.*}}@sqrtf
%res = tail call float @sqrtf(float %val) strictfp
``````````
</details>
https://github.com/llvm/llvm-project/pull/123966
More information about the llvm-commits
mailing list