[llvm-branch-commits] [llvm] InstCombine: Handle fmul by -0 case in SimplifyDemandedFPClass (PR #174023)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 30 13:47:16 PST 2025
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/174023
The fmul visitor handles this case as copysign and fneg.
>From ff4c66264cd154059312d8f3aa7aa7e70eb8ca91 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 30 Dec 2025 20:19:45 +0100
Subject: [PATCH] InstCombine: Handle fmul by -0 case in
SimplifyDemandedFPClass
The fmul visitor handles this case as copysign and fneg.
---
.../InstCombineSimplifyDemanded.cpp | 20 +++++++++++++++++--
.../simplify-demanded-fpclass-fmul.ll | 6 ++++--
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 9799ddacd7bd2..0b5854f169440 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2356,8 +2356,6 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
}
// TODO: Apply knowledge of no-infinity returns to sources.
-
- // TODO: Known -0, turn into copysign(y, fneg(x)) like visitFMul.
if (KnownLHS.isKnownNeverInfOrNaN() &&
KnownRHS.isKnownAlways(fcPosZero | fcNan)) {
// => copysign(+0, lhs)
@@ -2376,6 +2374,24 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
return Copysign;
}
+ if (KnownLHS.isKnownNeverInfOrNaN() &&
+ KnownRHS.isKnownAlways(fcNegZero | fcNan)) {
+ // => copysign(0, fneg(lhs))
+ // Note: Dropping canonicalize
+ Value *Copysign = Builder.CreateCopySign(Y, Builder.CreateFNegFMF(X, I));
+ Copysign->takeName(I);
+ return Copysign;
+ }
+
+ if (KnownLHS.isKnownAlways(fcNegZero | fcNan) &&
+ KnownRHS.isKnownNeverInfOrNaN()) {
+ // => copysign(+0, fneg(rhs))
+ // Note: Dropping canonicalize
+ Value *Copysign = Builder.CreateCopySign(X, Builder.CreateFNegFMF(Y, I));
+ Copysign->takeName(I);
+ return Copysign;
+ }
+
Type *EltTy = VTy->getScalarType();
DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
index 7d0b8ebae20cc..cb83fdc3e7a6b 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fmul.ll
@@ -941,7 +941,8 @@ define nofpclass(ninf) float @ret_ninf__fmul_nnan_unknown__zero(float %unknown)
define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan(float nofpclass(inf sub norm pzero) %nzero.or.nan, float nofpclass(inf nan) %not.inf.or.nan) {
; CHECK-LABEL: define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan(
; CHECK-SAME: float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], float nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[NZERO_OR_NAN]], [[NOT_INF_OR_NAN]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[NOT_INF_OR_NAN]]
+; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[NZERO_OR_NAN]], float [[TMP1]])
; CHECK-NEXT: ret float [[MUL]]
;
%mul = fmul contract float %nzero.or.nan, %not.inf.or.nan
@@ -952,7 +953,8 @@ define nofpclass(snan) float @known__nzero_or_nan__fmul__not_inf_or_nan(float no
define nofpclass(snan) float @known__not_inf_or_nan__fmul__nzero_or_nan(float nofpclass(inf nan) %not.inf.or.nan, float nofpclass(inf sub norm pzero) %nzero.or.nan) {
; CHECK-LABEL: define nofpclass(snan) float @known__not_inf_or_nan__fmul__nzero_or_nan(
; CHECK-SAME: float nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], float nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[MUL:%.*]] = fmul contract float [[NOT_INF_OR_NAN]], [[NZERO_OR_NAN]]
+; CHECK-NEXT: [[TMP1:%.*]] = fneg contract float [[NOT_INF_OR_NAN]]
+; CHECK-NEXT: [[MUL:%.*]] = call float @llvm.copysign.f32(float [[NZERO_OR_NAN]], float [[TMP1]])
; CHECK-NEXT: ret float [[MUL]]
;
%mul = fmul contract float %not.inf.or.nan, %nzero.or.nan
More information about the llvm-branch-commits
mailing list