[llvm-branch-commits] [llvm] InstCombine: Handle nsz in copysign SimplifyDemandedFPClass (PR #176916)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jan 25 07:58:09 PST 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/176916
>From 9a0bca280bc07db4552889163b5c097b006291aa Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 17 Jan 2026 18:48:24 +0100
Subject: [PATCH 1/2] InstCombine: Handle nsz in copysign
SimplifyDemandedFPClass
If the only sign bit difference is for 0, fold through the source.
---
.../InstCombineSimplifyDemanded.cpp | 32 ++++++++++++++++++-
.../InstCombine/simplify-demanded-fpclass.ll | 6 ++--
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index d7eac99d08054..d7a568cdbc5aa 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2143,6 +2143,32 @@ static Value *simplifyDemandedFPClassFnegFabs(KnownFPClass &Known, Value *Src,
return nullptr;
}
+static Value *simplifyDemandedFPClassCopysignMag(Value *MagSrc,
+ FPClassTest DemandedMask,
+ KnownFPClass KnownSrc,
+ bool NSZ) {
+ if (NSZ) {
+ constexpr FPClassTest NegOrZero = fcNegative | fcPosZero;
+ constexpr FPClassTest PosOrZero = fcPositive | fcNegZero;
+
+ if ((DemandedMask & ~NegOrZero) == fcNone &&
+ KnownSrc.isKnownNever(KnownFPClass::OrderedGreaterThanZeroMask | fcNan))
+ return MagSrc;
+
+ if ((DemandedMask & ~PosOrZero) == fcNone &&
+ KnownSrc.isKnownNever(KnownFPClass::OrderedLessThanZeroMask | fcNan))
+ return MagSrc;
+ } else {
+ if ((DemandedMask & ~fcNegative) == fcNone && KnownSrc.SignBit == true)
+ return MagSrc;
+
+ if ((DemandedMask & ~fcPositive) == fcNone && KnownSrc.SignBit == false)
+ return MagSrc;
+ }
+
+ return nullptr;
+}
+
static Value *
simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
const CallInst *CI, FPClassTest DemandedMask,
@@ -2750,7 +2776,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
case Intrinsic::copysign: {
// Flip on more potentially demanded classes
const FPClassTest DemandedMaskAnySign = llvm::unknown_sign(DemandedMask);
- if (SimplifyDemandedFPClass(I, 0, DemandedMaskAnySign, Known, Depth + 1))
+ if (SimplifyDemandedFPClass(CI, 0, DemandedMaskAnySign, Known, Depth + 1))
return I;
if ((DemandedMask & fcNegative) == DemandedMask) {
@@ -2765,6 +2791,10 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
return I;
}
+ if (Value *Simplified = simplifyDemandedFPClassCopysignMag(
+ CI->getArgOperand(0), DemandedMask, Known, FMF.noSignedZeros()))
+ return Simplified;
+
KnownFPClass KnownSign = computeKnownFPClass(CI->getArgOperand(1),
fcAllFlags, CxtI, Depth + 1);
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index 2f5ae5922eb0e..2c96f4fb8b4f2 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -2269,8 +2269,7 @@ define nofpclass(nan ninf nnorm nsub) float @ret_only_positive_or_zero__copysign
define nofpclass(nan ninf nnorm nsub) float @ret_only_positive_or_zero__copysign_nsz_src_known_positive__sign_unknown(float nofpclass(nan ninf nnorm nsub) %always.positive.or.zero, float %unknown) {
; CHECK-LABEL: define nofpclass(nan ninf nsub nnorm) float @ret_only_positive_or_zero__copysign_nsz_src_known_positive__sign_unknown
; CHECK-SAME: (float nofpclass(nan ninf nsub nnorm) [[ALWAYS_POSITIVE_OR_ZERO:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nsz float @llvm.copysign.f32(float [[ALWAYS_POSITIVE_OR_ZERO]], float [[UNKNOWN]])
-; CHECK-NEXT: ret float [[COPYSIGN]]
+; CHECK-NEXT: ret float [[ALWAYS_POSITIVE_OR_ZERO]]
;
%copysign = call nsz float @llvm.copysign.f32(float %always.positive.or.zero, float %unknown)
ret float %copysign
@@ -2303,8 +2302,7 @@ define nofpclass(nan pinf pnorm psub) float @ret_only_negative_or_pzero__copysig
define nofpclass(nan pinf pnorm psub) float @ret_only_negative_or_pzero__copysign_nsz_src_known_negative__sign_unknown(float nofpclass(nan pinf pnorm psub) %always.negative.or.zero, float %unknown) {
; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @ret_only_negative_or_pzero__copysign_nsz_src_known_negative__sign_unknown
; CHECK-SAME: (float nofpclass(nan pinf psub pnorm) [[ALWAYS_NEGATIVE_OR_ZERO:%.*]], float [[UNKNOWN:%.*]]) {
-; CHECK-NEXT: [[COPYSIGN:%.*]] = call nsz float @llvm.copysign.f32(float [[ALWAYS_NEGATIVE_OR_ZERO]], float [[UNKNOWN]])
-; CHECK-NEXT: ret float [[COPYSIGN]]
+; CHECK-NEXT: ret float [[ALWAYS_NEGATIVE_OR_ZERO]]
;
%copysign = call nsz float @llvm.copysign.f32(float %always.negative.or.zero, float %unknown)
ret float %copysign
>From 78ce56cc1413c5eb76c5206a0715c20cd6f49499 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 20 Jan 2026 16:55:29 +0100
Subject: [PATCH 2/2] Address comments
---
.../Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index d7a568cdbc5aa..8e12a5d2a1112 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2152,11 +2152,11 @@ static Value *simplifyDemandedFPClassCopysignMag(Value *MagSrc,
constexpr FPClassTest PosOrZero = fcPositive | fcNegZero;
if ((DemandedMask & ~NegOrZero) == fcNone &&
- KnownSrc.isKnownNever(KnownFPClass::OrderedGreaterThanZeroMask | fcNan))
+ KnownSrc.isKnownAlways(NegOrZero))
return MagSrc;
if ((DemandedMask & ~PosOrZero) == fcNone &&
- KnownSrc.isKnownNever(KnownFPClass::OrderedLessThanZeroMask | fcNan))
+ KnownSrc.isKnownAlways(PosOrZero))
return MagSrc;
} else {
if ((DemandedMask & ~fcNegative) == fcNone && KnownSrc.SignBit == true)
@@ -2776,7 +2776,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
case Intrinsic::copysign: {
// Flip on more potentially demanded classes
const FPClassTest DemandedMaskAnySign = llvm::unknown_sign(DemandedMask);
- if (SimplifyDemandedFPClass(CI, 0, DemandedMaskAnySign, Known, Depth + 1))
+ if (SimplifyDemandedFPClass(I, 0, DemandedMaskAnySign, Known, Depth + 1))
return I;
if ((DemandedMask & fcNegative) == DemandedMask) {
More information about the llvm-branch-commits
mailing list