[llvm-branch-commits] [llvm] InstCombine: Add baseline tests for fabs SimplifyDemandedFPClass improvements (PR #175027)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 8 09:03:59 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/175027

InstCombine: Add baseline tests for fabs SimplifyDemandedFPClass improvements

InstCombine: Improve SimplifyDemandedFPClass fabs handling

Try to eliminate the fabs if the source is known positive.

>From 2118005018702cce41a258819104576fa4dcd073 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 8 Jan 2026 16:57:23 +0100
Subject: [PATCH 1/2] InstCombine: Add baseline tests for fabs
 SimplifyDemandedFPClass improvements

---
 .../InstCombine/simplify-demanded-fpclass.ll  | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index 82b1d63d3c673..5d7306bb144e3 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -645,6 +645,55 @@ define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_non
   ret float %fneg
 }
 
+define nofpclass(snan) float @fabs_src_known_positive(float nofpclass(nan ninf nnorm nsub nzero) %always.positive) {
+; CHECK-LABEL: define nofpclass(snan) float @fabs_src_known_positive
+; CHECK-SAME: (float nofpclass(nan ninf nzero nsub nnorm) [[ALWAYS_POSITIVE:%.*]]) {
+; CHECK-NEXT:    ret float [[ALWAYS_POSITIVE]]
+;
+  %fabs = call float @llvm.fabs.f32(float %always.positive)
+  ret float %fabs
+}
+
+define nofpclass(snan) float @fabs_src_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
+; CHECK-LABEL: define nofpclass(snan) float @fabs_src_known_positive_or_nan
+; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ALWAYS_POSITIVE_OR_NAN]])
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %fabs = call float @llvm.fabs.f32(float %always.positive.or.nan)
+  ret float %fabs
+}
+
+define nofpclass(snan) float @fabs_nnan_src_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
+; CHECK-LABEL: define nofpclass(snan) float @fabs_nnan_src_known_positive_or_nan
+; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[FABS:%.*]] = call nnan float @llvm.fabs.f32(float [[ALWAYS_POSITIVE_OR_NAN]])
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %fabs = call nnan float @llvm.fabs.f32(float %always.positive.or.nan)
+  ret float %fabs
+}
+
+define nofpclass(nan) float @ret_nonan_fabs_src_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
+; CHECK-LABEL: define nofpclass(nan) float @ret_nonan_fabs_src_known_positive_or_nan
+; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ALWAYS_POSITIVE_OR_NAN]])
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %fabs = call float @llvm.fabs.f32(float %always.positive.or.nan)
+  ret float %fabs
+}
+
+define nofpclass(snan) float @fabs_src_known_negative(float nofpclass(nan pinf pnorm psub pzero) %always.negative) {
+; CHECK-LABEL: define nofpclass(snan) float @fabs_src_known_negative
+; CHECK-SAME: (float nofpclass(nan pinf pzero psub pnorm) [[ALWAYS_NEGATIVE:%.*]]) {
+; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ALWAYS_NEGATIVE]])
+; CHECK-NEXT:    ret float [[FABS]]
+;
+  %fabs = call float @llvm.fabs.f32(float %always.negative)
+  ret float %fabs
+}
+
 ; should fold to ret copysign(%x)
 define nofpclass(inf) float @ret_nofpclass_inf__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {
 ; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_unknown_select_pinf_rhs

>From ed681de48f3a902af616073bde0f9f882805d997 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 8 Jan 2026 16:59:46 +0100
Subject: [PATCH 2/2] InstCombine: Improve SimplifyDemandedFPClass fabs
 handling

Try to eliminate the fabs if the source is known positive.
---
 .../InstCombine/InstCombineSimplifyDemanded.cpp      |  5 +++++
 .../simplify-demanded-fpclass-shufflevector.ll       |  3 +--
 .../InstCombine/simplify-demanded-fpclass.ll         | 12 ++++--------
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3ee26b502652f..28639f90a7977 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2226,6 +2226,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
       if (SimplifyDemandedFPClass(I, 0, llvm::inverse_fabs(DemandedMask), Known,
                                   Depth + 1))
         return I;
+
+      if (Known.SignBit == false ||
+          ((DemandedMask & fcNan) == fcNone && Known.isKnownNever(fcNegative)))
+        return CI->getArgOperand(0);
+
       Known.fabs();
       break;
     case Intrinsic::arithmetic_fence:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-shufflevector.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-shufflevector.ll
index 042e77c3ee2a9..ee8be3ca1bf89 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-shufflevector.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-shufflevector.ll
@@ -197,8 +197,7 @@ define nofpclass(nan ninf nnorm nsub nzero) <4 x half> @ret_positives_non_nan___
 ; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) <4 x half> @ret_positives_non_nan___shuffle_fabs(
 ; CHECK-SAME: i1 [[COND:%.*]], <4 x half> nofpclass(ninf nzero nsub nnorm) [[KNOWN_POSITIVE0:%.*]], <4 x half> nofpclass(ninf nzero nsub nnorm) [[KNOWN_POSITIVE1:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x half> [[KNOWN_POSITIVE0]], <4 x half> [[KNOWN_POSITIVE1]], <4 x i32> <i32 4, i32 2, i32 3, i32 0>
-; CHECK-NEXT:    [[SHUFFLE:%.*]] = call <4 x half> @llvm.fabs.v4f16(<4 x half> [[TMP1]])
-; CHECK-NEXT:    ret <4 x half> [[SHUFFLE]]
+; CHECK-NEXT:    ret <4 x half> [[TMP1]]
 ;
   %fabs.0 = call <4 x half> @llvm.fabs.v4f16(<4 x half> %known.positive0)
   %fabs.1 = call <4 x half> @llvm.fabs.v4f16(<4 x half> %known.positive1)
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index 5d7306bb144e3..ee172a53b4f55 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -667,8 +667,7 @@ define nofpclass(snan) float @fabs_src_known_positive_or_nan(float nofpclass(nin
 define nofpclass(snan) float @fabs_nnan_src_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
 ; CHECK-LABEL: define nofpclass(snan) float @fabs_nnan_src_known_positive_or_nan
 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
-; CHECK-NEXT:    [[FABS:%.*]] = call nnan float @llvm.fabs.f32(float [[ALWAYS_POSITIVE_OR_NAN]])
-; CHECK-NEXT:    ret float [[FABS]]
+; CHECK-NEXT:    ret float [[ALWAYS_POSITIVE_OR_NAN]]
 ;
   %fabs = call nnan float @llvm.fabs.f32(float %always.positive.or.nan)
   ret float %fabs
@@ -677,8 +676,7 @@ define nofpclass(snan) float @fabs_nnan_src_known_positive_or_nan(float nofpclas
 define nofpclass(nan) float @ret_nonan_fabs_src_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
 ; CHECK-LABEL: define nofpclass(nan) float @ret_nonan_fabs_src_known_positive_or_nan
 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
-; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ALWAYS_POSITIVE_OR_NAN]])
-; CHECK-NEXT:    ret float [[FABS]]
+; CHECK-NEXT:    ret float [[ALWAYS_POSITIVE_OR_NAN]]
 ;
   %fabs = call float @llvm.fabs.f32(float %always.positive.or.nan)
   ret float %fabs
@@ -923,8 +921,7 @@ define nofpclass(snan) float @copysign_nnan_sign_known_negative_or_nan(float %x,
 define nofpclass(snan) float @copysign_nnan__known_positive__sign_known_positive_or_nan(float nofpclass(ninf nnorm nsub nzero) %known.positive, float nofpclass(ninf nnorm nsub nzero) %always.positive.or.nan) {
 ; CHECK-LABEL: define nofpclass(snan) float @copysign_nnan__known_positive__sign_known_positive_or_nan
 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[KNOWN_POSITIVE:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ALWAYS_POSITIVE_OR_NAN:%.*]]) {
-; CHECK-NEXT:    [[COPYSIGN:%.*]] = call nnan float @llvm.fabs.f32(float [[KNOWN_POSITIVE]])
-; CHECK-NEXT:    ret float [[COPYSIGN]]
+; CHECK-NEXT:    ret float [[KNOWN_POSITIVE]]
 ;
   %copysign = call nnan float @llvm.copysign.f32(float %known.positive, float %always.positive.or.nan)
   ret float %copysign
@@ -957,8 +954,7 @@ define nofpclass(snan) float @copysign_nnan__known_negative__sign_known_positive
 define nofpclass(snan) float @copysign_nnan__known_positive__sign_known_negative_or_nan(float nofpclass(ninf nnorm nsub nzero) %known.positive, float nofpclass(pinf pnorm psub pzero) %always.negative.or.nan) {
 ; CHECK-LABEL: define nofpclass(snan) float @copysign_nnan__known_positive__sign_known_negative_or_nan
 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[KNOWN_POSITIVE:%.*]], float nofpclass(pinf pzero psub pnorm) [[ALWAYS_NEGATIVE_OR_NAN:%.*]]) {
-; CHECK-NEXT:    [[TMP1:%.*]] = call nnan float @llvm.fabs.f32(float [[KNOWN_POSITIVE]])
-; CHECK-NEXT:    [[COPYSIGN:%.*]] = fneg nnan float [[TMP1]]
+; CHECK-NEXT:    [[COPYSIGN:%.*]] = fneg nnan float [[KNOWN_POSITIVE]]
 ; CHECK-NEXT:    ret float [[COPYSIGN]]
 ;
   %copysign = call nnan float @llvm.copysign.f32(float %known.positive, float %always.negative.or.nan)



More information about the llvm-branch-commits mailing list