https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/179235
>From 36cd0a0d4c17435804591d9dc62cc8d9e9b4c74b Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Mon, 2 Feb 2026 13:05:41 +0100 Subject: [PATCH] ValueTracking: Move ldexp KnownFPClass handling to support Will enable code sharing with SImplifyDemandedFPClass, SelectionDAG and GlobalISel. --- llvm/include/llvm/Support/KnownFPClass.h | 6 +++ llvm/lib/Analysis/ValueTracking.cpp | 42 +++++---------------- llvm/lib/Support/KnownFPClass.cpp | 48 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h index 6409a7e44a116..c0040fa73beb8 100644 --- a/llvm/include/llvm/Support/KnownFPClass.h +++ b/llvm/include/llvm/Support/KnownFPClass.h @@ -21,6 +21,7 @@ namespace llvm { class APFloat; struct fltSemantics; +struct KnownBits; struct KnownFPClass { /// Floating-point classes the value could be one of. @@ -390,6 +391,11 @@ struct KnownFPClass { static LLVM_ABI KnownFPClass frexp_mant( const KnownFPClass &Src, DenormalMode Mode = DenormalMode::getDynamic()); + /// Propagate known class for ldexp + static LLVM_ABI KnownFPClass + ldexp(const KnownFPClass &Src, const KnownBits &N, const fltSemantics &Flt, + DenormalMode Mode = DenormalMode::getDynamic()); + void resetAll() { *this = KnownFPClass(); } }; diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 87062e7e92a76..aecba4df442ef 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5402,45 +5402,21 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, const FPClassTest ExpInfoMask = fcZero | fcSubnormal | fcInf; if ((InterestedClasses & ExpInfoMask) == fcNone) break; - if ((KnownSrc.KnownFPClasses & ExpInfoMask) == fcNone) - break; + + KnownBits ExpBits; + if ((KnownSrc.KnownFPClasses & ExpInfoMask) != fcNone) { + const Value *ExpArg = II->getArgOperand(1); + ExpBits = computeKnownBits(ExpArg, DemandedElts, Q, Depth + 1); + } const fltSemantics &Flt = II->getType()->getScalarType()->getFltSemantics(); - unsigned Precision = APFloat::semanticsPrecision(Flt); - const Value *ExpArg = II->getArgOperand(1); - - KnownBits ExpBits = computeKnownBits(ExpArg, DemandedElts, Q, Depth + 1); - const int MantissaBits = Precision - 1; - if (ExpBits.getSignedMinValue().sge(static_cast<int64_t>(MantissaBits))) - Known.knownNot(fcSubnormal); const Function *F = II->getFunction(); - const fltSemantics &FltSem = - II->getType()->getScalarType()->getFltSemantics(); - if (ExpBits.isConstant() && ExpBits.getConstant().isZero()) { - // ldexp(x, 0) -> x, so propagate everything. - Known.propagateCanonicalizingSrc(KnownSrc, F->getDenormalMode(FltSem)); - } else if (ExpBits.isNegative()) { - // If we know the power is <= 0, can't introduce inf - if (KnownSrc.isKnownNeverPosInfinity()) - Known.knownNot(fcPosInf); - if (KnownSrc.isKnownNeverNegInfinity()) - Known.knownNot(fcNegInf); - } else if (ExpBits.isNonNegative()) { - // If we know the power is >= 0, can't introduce subnormal or zero - if (KnownSrc.isKnownNeverPosSubnormal()) - Known.knownNot(fcPosSubnormal); - if (KnownSrc.isKnownNeverNegSubnormal()) - Known.knownNot(fcNegSubnormal); - if (F && - KnownSrc.isKnownNeverLogicalPosZero(F->getDenormalMode(FltSem))) - Known.knownNot(fcPosZero); - if (F && - KnownSrc.isKnownNeverLogicalNegZero(F->getDenormalMode(FltSem))) - Known.knownNot(fcNegZero); - } + DenormalMode Mode = + F ? F->getDenormalMode(Flt) : DenormalMode::getDynamic(); + Known = KnownFPClass::ldexp(KnownSrc, ExpBits, Flt, Mode); break; } case Intrinsic::arithmetic_fence: { diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp index e7662523d3f95..ddced8044175f 100644 --- a/llvm/lib/Support/KnownFPClass.cpp +++ b/llvm/lib/Support/KnownFPClass.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/KnownFPClass.h" #include "llvm/ADT/APFloat.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/KnownBits.h" using namespace llvm; @@ -626,3 +627,50 @@ KnownFPClass KnownFPClass::frexp_mant(const KnownFPClass &KnownSrc, Known.propagateNaN(KnownSrc); return Known; } + +KnownFPClass KnownFPClass::ldexp(const KnownFPClass &KnownSrc, + const KnownBits &ExpBits, + const fltSemantics &Flt, DenormalMode Mode) { + KnownFPClass Known; + Known.propagateNaN(KnownSrc, /*PropagateSign=*/true); + + // Sign is preserved, but underflows may produce zeroes. + if (KnownSrc.isKnownNever(fcNegative)) + Known.knownNot(fcNegative); + else if (KnownSrc.cannotBeOrderedLessThanZero()) + Known.knownNot(OrderedLessThanZeroMask); + + if (KnownSrc.isKnownNever(fcPositive)) + Known.knownNot(fcPositive); + else if (KnownSrc.cannotBeOrderedGreaterThanZero()) + Known.knownNot(OrderedGreaterThanZeroMask); + + unsigned Precision = APFloat::semanticsPrecision(Flt); + const int MantissaBits = Precision - 1; + + if (ExpBits.getSignedMinValue().sge(static_cast<int64_t>(MantissaBits))) + Known.knownNot(fcSubnormal); + + if (ExpBits.isConstant() && ExpBits.getConstant().isZero()) { + // ldexp(x, 0) -> x, so propagate everything. + Known.propagateCanonicalizingSrc(KnownSrc, Mode); + } else if (ExpBits.isNegative()) { + // If we know the power is <= 0, can't introduce inf + if (KnownSrc.isKnownNeverPosInfinity()) + Known.knownNot(fcPosInf); + if (KnownSrc.isKnownNeverNegInfinity()) + Known.knownNot(fcNegInf); + } else if (ExpBits.isNonNegative()) { + // If we know the power is >= 0, can't introduce subnormal or zero + if (KnownSrc.isKnownNeverPosSubnormal()) + Known.knownNot(fcPosSubnormal); + if (KnownSrc.isKnownNeverNegSubnormal()) + Known.knownNot(fcNegSubnormal); + if (KnownSrc.isKnownNeverLogicalPosZero(Mode)) + Known.knownNot(fcPosZero); + if (KnownSrc.isKnownNeverLogicalNegZero(Mode)) + Known.knownNot(fcNegZero); + } + + return Known; +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
