[llvm-branch-commits] [llvm] ValueTracking: Move ldexp KnownFPClass handling to support (PR #179235)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 2 06:47:39 PST 2026
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 <Matthew.Arsenault at amd.com>
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;
+}
More information about the llvm-branch-commits
mailing list