[llvm] [InstCombine] Fold more 'fcmp' 'select' instrs idioms into 'fabs' (PR #83381)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 28 22:55:38 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yashwant Singh (yashssh)
<details>
<summary>Changes</summary>
Based on these C/C++ patterns when compiled with 'Ofast' return X > 0.0 ? X : -X;
return X < 0.0 ? -X : X;
InstCombine tries to propogate FMF to 'select' instructions before attempting a fold, but it can't safely propgate 'nsz' hence wasn't performing the optimization. OOTH we should be able to do this optimization at 'Ofast' same as gcc(https://godbolt.org/z/c69fe5fa6).
Bit of a workaround but this patch allows us to query the "no-signed-zeroes" function attribute added to the function during 'Ofast' compilation. Allowing instcombine to safely match the idiom.
---
Full diff: https://github.com/llvm/llvm-project/pull/83381.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+5-1)
- (modified) llvm/test/Transforms/InstCombine/fabs.ll (+27)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 71fa9b9ba41ebb..bd56d92d5d3d0f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2742,7 +2742,11 @@ static Instruction *foldSelectWithFCmpToFabs(SelectInst &SI,
// Note: We require "nnan" for this fold because fcmp ignores the signbit
// of NAN, but IEEE-754 specifies the signbit of NAN values with
// fneg/fabs operations.
- if (!SI.hasNoSignedZeros() || !SI.hasNoNaNs())
+ if (!SI.hasNoNaNs())
+ return nullptr;
+
+ bool functionHasNoSignedZeroes = SI.getParent()->getParent()->hasFnAttribute("no-signed-zeros-fp-math");
+ if(!functionHasNoSignedZeroes && !SI.hasNoSignedZeros())
return nullptr;
if (Swap)
diff --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll
index 7e380c2e4590a0..88b02a852f3d74 100644
--- a/llvm/test/Transforms/InstCombine/fabs.ll
+++ b/llvm/test/Transforms/InstCombine/fabs.ll
@@ -547,6 +547,20 @@ define double @select_fcmp_nnan_nsz_ult_zero_unary_fneg(double %x) {
ret double %fabs
}
+
+define float @absfloat32f_olt_fast_no_signed_zeroes(float %x) "no-signed-zeros-fp-math" {
+; CHECK-LABEL: @absfloat32f_olt_fast_no_signed_zeroes(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = call nnan ninf float @llvm.fabs.f32(float [[X:%.*]])
+; CHECK-NEXT: ret float [[RETVAL_0]]
+;
+entry:
+ %cmp = fcmp fast olt float %x, 0.000000e+00
+ %fneg = fneg fast float %x
+ %retval.0 = select i1 %cmp, float %fneg, float %x
+ ret float %retval.0
+}
+
; X < -0.0 ? -X : X --> fabs(X)
define float @select_fcmp_nnan_nsz_olt_negzero(float %x) {
@@ -839,6 +853,19 @@ define <2 x float> @select_fcmp_nnan_nsz_ugt_zero_unary_fneg(<2 x float> %x) {
ret <2 x float> %fabs
}
+define float @absfloat32f_ogt_fast_no_signed_zeroes(float %x) "no-signed-zeros-fp-math" {
+; CHECK-LABEL: @absfloat32f_ogt_fast_no_signed_zeroes(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RETVAL_0:%.*]] = call nnan ninf float @llvm.fabs.f32(float [[X:%.*]])
+; CHECK-NEXT: ret float [[RETVAL_0]]
+;
+entry:
+ %cmp = fcmp fast ogt float %x, 0.000000e+00
+ %fneg = fneg fast float %x
+ %retval.0 = select i1 %cmp, float %x, float %fneg
+ ret float %retval.0
+}
+
; X > -0.0 ? X : (0.0 - X) --> fabs(X)
define half @select_fcmp_nnan_nsz_ogt_negzero(half %x) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/83381
More information about the llvm-commits
mailing list