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