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 <[email protected]> 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 <[email protected]> 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) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
