[llvm] [InstCombine] Fold fabs over selects (PR #86390)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 23 03:32:36 PDT 2024
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/86390
This patch folds fabs over select if it is beneficial. I also tried other interger/fp intrinsics. Only handling fabs shows benefit to some real-world applications.
>From 41101962d9632be635e734cd5259008ed811f277 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 23 Mar 2024 18:20:47 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
.../InstCombine/intrinsic-select.ll | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/intrinsic-select.ll b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
index f37226bbd5b09c..382e66a0c0979a 100644
--- a/llvm/test/Transforms/InstCombine/intrinsic-select.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
@@ -280,3 +280,33 @@ entry:
%ret = icmp eq i64 %masked, 0
ret i1 %ret
}
+
+define double @test_fabs_select1(double %a) {
+; CHECK-LABEL: @test_fabs_select1(
+; CHECK-NEXT: [[COND:%.*]] = fcmp uno double [[A:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], double 0x7FF8000000000000, double [[A]]
+; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[SEL1]])
+; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND]], double [[FABS]], double [[A]]
+; CHECK-NEXT: ret double [[SEL2]]
+;
+ %cond = fcmp uno double %a, 0.000000e+00
+ %sel1 = select i1 %cond, double 0x7FF8000000000000, double %a
+ %fabs = call double @llvm.fabs.f64(double %sel1)
+ %sel2 = select i1 %cond, double %fabs, double %a
+ ret double %sel2
+}
+
+define double @test_fabs_select2(double %a) {
+; CHECK-LABEL: @test_fabs_select2(
+; CHECK-NEXT: [[ABS1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[ABS1]], 0x7FF0000000000000
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], double -0.000000e+00, double [[ABS1]]
+; CHECK-NEXT: [[ABS2:%.*]] = call double @llvm.fabs.f64(double [[SEL]])
+; CHECK-NEXT: ret double [[ABS2]]
+;
+ %abs1 = call double @llvm.fabs.f64(double %a)
+ %cmp = fcmp oeq double %abs1, 0x7FF0000000000000
+ %sel = select i1 %cmp, double -0.000000e+00, double %abs1
+ %abs2 = call double @llvm.fabs.f64(double %sel)
+ ret double %abs2
+}
>From b65d65fa0ca1b5fe44d777f6a8d092d18ea140ec Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 23 Mar 2024 18:25:01 +0800
Subject: [PATCH 2/2] [InstCombine] Fold fabs over select
---
.../InstCombine/InstCombineCalls.cpp | 1 +
llvm/test/Transforms/InstCombine/fabs.ll | 6 ++---
.../InstCombine/intrinsic-select.ll | 7 ++----
.../InstCombine/simplify-demanded-fpclass.ll | 24 +++++++++----------
4 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 526fe5d080599f..0f1b98cc6ef2af 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3432,6 +3432,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
case Intrinsic::uadd_sat:
case Intrinsic::ssub_sat:
case Intrinsic::sadd_sat:
+ case Intrinsic::fabs:
for (Value *Op : II->args())
if (auto *Sel = dyn_cast<SelectInst>(Op))
if (Instruction *R = FoldOpIntoSelect(*II, Sel))
diff --git a/llvm/test/Transforms/InstCombine/fabs.ll b/llvm/test/Transforms/InstCombine/fabs.ll
index 7e380c2e4590a0..d8251befca4819 100644
--- a/llvm/test/Transforms/InstCombine/fabs.ll
+++ b/llvm/test/Transforms/InstCombine/fabs.ll
@@ -179,9 +179,9 @@ define float @fabs_select_constant_neg0(i32 %c) {
define float @fabs_select_var_constant_negative(i32 %c, float %x) {
; CHECK-LABEL: @fabs_select_var_constant_negative(
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], float [[X:%.*]], float -1.000000e+00
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
-; CHECK-NEXT: ret float [[FABS]]
+; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT:%.*]])
+; CHECK-NEXT: [[FABS1:%.*]] = select i1 [[CMP]], float [[FABS]], float 1.000000e+00
+; CHECK-NEXT: ret float [[FABS1]]
;
%cmp = icmp eq i32 %c, 0
%select = select i1 %cmp, float %x, float -1.0
diff --git a/llvm/test/Transforms/InstCombine/intrinsic-select.ll b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
index 382e66a0c0979a..bdbfd625442f1b 100644
--- a/llvm/test/Transforms/InstCombine/intrinsic-select.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
@@ -285,9 +285,7 @@ define double @test_fabs_select1(double %a) {
; CHECK-LABEL: @test_fabs_select1(
; CHECK-NEXT: [[COND:%.*]] = fcmp uno double [[A:%.*]], 0.000000e+00
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], double 0x7FF8000000000000, double [[A]]
-; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[SEL1]])
-; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND]], double [[FABS]], double [[A]]
-; CHECK-NEXT: ret double [[SEL2]]
+; CHECK-NEXT: ret double [[SEL1]]
;
%cond = fcmp uno double %a, 0.000000e+00
%sel1 = select i1 %cond, double 0x7FF8000000000000, double %a
@@ -300,8 +298,7 @@ define double @test_fabs_select2(double %a) {
; CHECK-LABEL: @test_fabs_select2(
; CHECK-NEXT: [[ABS1:%.*]] = call double @llvm.fabs.f64(double [[A:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[ABS1]], 0x7FF0000000000000
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], double -0.000000e+00, double [[ABS1]]
-; CHECK-NEXT: [[ABS2:%.*]] = call double @llvm.fabs.f64(double [[SEL]])
+; CHECK-NEXT: [[ABS2:%.*]] = select i1 [[CMP]], double 0.000000e+00, double [[ABS1]]
; CHECK-NEXT: ret double [[ABS2]]
;
%abs1 = call double @llvm.fabs.f64(double %a)
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index 5dfeb0734fbbed..a7d01b4f824db0 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -387,8 +387,8 @@ define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_pinf_rhs(i1 %cond, f
define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives__fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000
; CHECK-NEXT: ret float [[FABS]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -411,8 +411,8 @@ define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__fabs_
define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_nan__fabs_select_pinf_rhs(i1 %cond, float %x) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives_nan__fabs_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000
; CHECK-NEXT: ret float [[FABS]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -665,8 +665,8 @@ define nofpclass(inf pnorm psub pzero) float @ret_nofpclass_no_positives_noinf__
define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000
; CHECK-NEXT: ret float [[COPYSIGN]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -678,8 +678,8 @@ define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__copys
define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[TMP2]], float 0x7FF0000000000000
; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]
; CHECK-NEXT: ret float [[COPYSIGN]]
;
@@ -692,8 +692,8 @@ define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__copys
define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_nonan__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives_nonan__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000
; CHECK-NEXT: ret float [[COPYSIGN]]
;
%select = select i1 %cond, float %x, float 0x7FF0000000000000
@@ -705,8 +705,8 @@ define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_no
define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs
; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000
-; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[SELECT]])
+; CHECK-NEXT: [[TMP2:%.*]] = call float @llvm.fabs.f32(float [[X]])
+; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], float [[TMP2]], float 0x7FF0000000000000
; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]
; CHECK-NEXT: ret float [[COPYSIGN]]
;
More information about the llvm-commits
mailing list