[llvm] d9ba05b - [KnownFPClass] Split FDIV and FREM in `computeKnownFPClass` (#218726)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 02:34:00 PDT 2026
Author: ZERICO2005
Date: 2026-08-26T09:33:55Z
New Revision: d9ba05b9ebf87c57da3afc55442d3332f85a5821
URL: https://github.com/llvm/llvm-project/commit/d9ba05b9ebf87c57da3afc55442d3332f85a5821
DIFF: https://github.com/llvm/llvm-project/commit/d9ba05b9ebf87c57da3afc55442d3332f85a5821.diff
LOG: [KnownFPClass] Split FDIV and FREM in `computeKnownFPClass` (#218726)
In `Analysis/ValueTracking.cpp` and
`CodeGen/GlobalISel/GISelValueTracking.cpp`, the code for handling
`FDIV` and `FREM` reside in the same switch case. This code is very
confusing to follow and difficult to work on. I have split them so that
`FDIV` and `FREM` reside in different switch cases.
I plan to do an additional NFC PR to move the `FREM` deductions to a new
`KnownFPClass::frem` function.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3245a0302d4ae..66fde465ea761 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5914,22 +5914,19 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
break;
}
- case Instruction::FDiv:
- case Instruction::FRem: {
+ case Instruction::FDiv: {
const bool WantNan = (InterestedClasses & fcNan) != fcNone;
- if (Op->getOpcode() == Instruction::FRem)
- Known.knownNot(fcInf);
+ const Function *F = cast<Instruction>(Op)->getFunction();
+ const fltSemantics &FltSem =
+ Op->getType()->getScalarType()->getFltSemantics();
+ DenormalMode Mode =
+ F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
if (Op->getOperand(0) == Op->getOperand(1) &&
isGuaranteedNotToBeUndef(Op->getOperand(0), Q.AC, Q.CxtI, Q.DT)) {
- if (Op->getOpcode() == Instruction::FDiv) {
- // X / X is always exactly 1.0 or a NaN.
- Known.KnownFPClasses = fcNan | fcPosNormal;
- } else {
- // X % X is always exactly [+-]0.0 or a NaN.
- Known.KnownFPClasses = fcNan | fcZero;
- }
+ // X / X is always exactly 1.0 or a NaN.
+ Known.KnownFPClasses = fcNan | fcPosNormal;
if (!WantNan)
break;
@@ -5938,16 +5935,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
computeKnownFPClass(Op->getOperand(0), DemandedElts,
fcNan | fcInf | fcZero | fcSubnormal, KnownSrc, Q,
Depth + 1);
- const Function *F = cast<Instruction>(Op)->getFunction();
- const fltSemantics &FltSem =
- Op->getType()->getScalarType()->getFltSemantics();
-
- DenormalMode Mode =
- F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
- Known = Op->getOpcode() == Instruction::FDiv
- ? KnownFPClass::fdiv_self(KnownSrc, Mode)
- : KnownFPClass::frem_self(KnownSrc, Mode);
+ Known = KnownFPClass::fdiv_self(KnownSrc, Mode);
break;
}
@@ -5957,57 +5946,86 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
break;
KnownFPClass KnownLHS, KnownRHS;
- const bool IsFDiv = Opc == Instruction::FDiv;
- FPClassTest InterestedRHS =
- IsFDiv ? fcAllFlags : fcNan | fcInf | fcZero | fcNegative;
+ computeKnownFPClass(Op->getOperand(1), DemandedElts, fcAllFlags, KnownRHS,
+ Q, Depth + 1);
- computeKnownFPClass(Op->getOperand(1), DemandedElts, InterestedRHS,
- KnownRHS, Q, Depth + 1);
+ bool KnowSomethingUseful =
+ KnownRHS.isKnownNeverNaN() ||
+ KnownRHS.isKnownNever(fcNegNormal | fcNegSubnormal) ||
+ KnownRHS.isKnownNever(fcPosNormal | fcPosSubnormal);
- bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN();
- if (IsFDiv) {
- KnowSomethingUseful |=
- KnownRHS.isKnownNever(fcNegNormal | fcNegSubnormal) ||
- KnownRHS.isKnownNever(fcPosNormal | fcPosSubnormal);
- } else {
- KnowSomethingUseful |= KnownRHS.isKnownNever(fcNegative) ||
- KnownRHS.isKnownNever(fcPositive);
- }
-
- if (KnowSomethingUseful || (!IsFDiv && WantPositive)) {
+ if (KnowSomethingUseful)
computeKnownFPClass(Op->getOperand(0), DemandedElts, fcAllFlags, KnownLHS,
Q, Depth + 1);
- }
+
+ Known = KnownFPClass::fdiv(KnownLHS, KnownRHS, Mode);
+ break;
+ }
+ case Instruction::FRem: {
+ const bool WantNan = (InterestedClasses & fcNan) != fcNone;
+
+ Known.knownNot(fcInf);
const Function *F = cast<Instruction>(Op)->getFunction();
- const fltSemantics &FltSem =
- Op->getType()->getScalarType()->getFltSemantics();
+ DenormalMode Mode =
+ F ? F->getDenormalMode(
+ Op->getType()->getScalarType()->getFltSemantics())
+ : DenormalMode::getDynamic();
- if (IsFDiv) {
- DenormalMode Mode =
- F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
- Known = KnownFPClass::fdiv(KnownLHS, KnownRHS, Mode);
- } else {
- // Inf REM x and x REM 0 produce NaN.
- if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
- KnownLHS.isKnownNeverInfinity() && F &&
- KnownRHS.isKnownNeverLogicalZero(F->getDenormalMode(FltSem))) {
- Known.knownNot(fcNan);
- }
+ if (Op->getOperand(0) == Op->getOperand(1) &&
+ isGuaranteedNotToBeUndef(Op->getOperand(0), Q.AC, Q.CxtI, Q.DT)) {
+ // X % X is always exactly [+-]0.0 or a NaN.
+ Known.KnownFPClasses = fcNan | fcZero;
- // The sign for frem is the same as the first operand.
- if (KnownLHS.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- if (KnownLHS.cannotBeOrderedGreaterThanZero())
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+ if (!WantNan)
+ break;
- // See if we can be more aggressive about the sign of 0.
- if (KnownLHS.isKnownNever(fcNegative))
- Known.knownNot(fcNegative);
- if (KnownLHS.isKnownNever(fcPositive))
- Known.knownNot(fcPositive);
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(Op->getOperand(0), DemandedElts,
+ fcNan | fcInf | fcZero | fcSubnormal, KnownSrc, Q,
+ Depth + 1);
+
+ Known = KnownFPClass::frem_self(KnownSrc, Mode);
+ break;
}
+ const bool WantNegative = (InterestedClasses & fcNegative) != fcNone;
+ const bool WantPositive = (InterestedClasses & fcPositive) != fcNone;
+ if (!WantNan && !WantNegative && !WantPositive)
+ break;
+
+ KnownFPClass KnownLHS, KnownRHS;
+ computeKnownFPClass(Op->getOperand(1), DemandedElts,
+ fcNan | fcInf | fcZero | fcNegative, KnownRHS, Q,
+ Depth + 1);
+
+ bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN() ||
+ KnownRHS.isKnownNever(fcNegative) ||
+ KnownRHS.isKnownNever(fcPositive);
+
+ if (KnowSomethingUseful || WantPositive)
+ computeKnownFPClass(Op->getOperand(0), DemandedElts, fcAllFlags, KnownLHS,
+ Q, Depth + 1);
+
+ // Inf REM x and x REM 0 produce NaN.
+ if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
+ KnownLHS.isKnownNeverInfinity() &&
+ KnownRHS.isKnownNeverLogicalZero(Mode)) {
+ Known.knownNot(fcNan);
+ }
+
+ // The sign for frem is the same as the first operand.
+ if (KnownLHS.cannotBeOrderedLessThanZero())
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ if (KnownLHS.cannotBeOrderedGreaterThanZero())
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+
+ // See if we can be more aggressive about the sign of 0.
+ if (KnownLHS.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ if (KnownLHS.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
+
break;
}
case Instruction::FPExt: {
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 003a33d8c5a2b..0f2595015efc7 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -1808,96 +1808,110 @@ void GISelValueTracking::computeKnownFPClass(Register R,
}
break;
}
- case TargetOpcode::G_FDIV:
- case TargetOpcode::G_FREM: {
+ case TargetOpcode::G_FDIV: {
+ const bool WantNan = (InterestedClasses & fcNan) != fcNone;
+
Register LHS = MI.getOperand(1).getReg();
Register RHS = MI.getOperand(2).getReg();
- if (Opcode == TargetOpcode::G_FREM)
- Known.knownNot(fcInf);
-
DenormalMode Mode =
MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
if (LHS == RHS && isGuaranteedNotToBeUndef(LHS, MRI, Depth + 1)) {
- if (Opcode == TargetOpcode::G_FDIV) {
- const bool WantNan = (InterestedClasses & fcNan) != fcNone;
- if (!WantNan) {
- // X / X is always exactly 1.0 or a NaN.
- Known.KnownFPClasses = fcPosNormal | fcNan;
- break;
- }
- KnownFPClass KnownSrc;
- computeKnownFPClass(LHS, DemandedElts,
- fcNan | fcInf | fcZero | fcSubnormal, KnownSrc,
- Depth + 1);
- Known = KnownFPClass::fdiv_self(KnownSrc, Mode);
- } else {
- const bool WantNan = (InterestedClasses & fcNan) != fcNone;
- if (!WantNan) {
- // X % X is always exactly [+-]0.0 or a NaN.
- Known.KnownFPClasses = fcZero | fcNan;
- break;
- }
- KnownFPClass KnownSrc;
- computeKnownFPClass(LHS, DemandedElts,
- fcNan | fcInf | fcZero | fcSubnormal, KnownSrc,
- Depth + 1);
- Known = KnownFPClass::frem_self(KnownSrc, Mode);
- }
+ // X / X is always exactly 1.0 or a NaN.
+ Known.KnownFPClasses = fcPosNormal | fcNan;
+
+ if (!WantNan)
+ break;
+
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(LHS, DemandedElts,
+ fcNan | fcInf | fcZero | fcSubnormal, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::fdiv_self(KnownSrc, Mode);
break;
}
- const bool WantNan = (InterestedClasses & fcNan) != fcNone;
const bool WantNegative = (InterestedClasses & fcNegative) != fcNone;
const bool WantPositive = (InterestedClasses & fcPositive) != fcNone;
- if (!WantNan && !WantNegative && !WantPositive) {
+ if (!WantNan && !WantNegative && !WantPositive)
break;
- }
KnownFPClass KnownLHS, KnownRHS;
- const bool IsFDiv = Opcode == TargetOpcode::G_FDIV;
- FPClassTest InterestedRHS =
- IsFDiv ? fcAllFlags : fcNan | fcInf | fcZero | fcNegative;
+ computeKnownFPClass(RHS, DemandedElts, fcAllFlags, KnownRHS, Depth + 1);
- computeKnownFPClass(RHS, DemandedElts, InterestedRHS, KnownRHS, Depth + 1);
+ bool KnowSomethingUseful =
+ KnownRHS.isKnownNeverNaN() ||
+ KnownRHS.isKnownNever(fcNegNormal | fcNegSubnormal) ||
+ KnownRHS.isKnownNever(fcPosNormal | fcPosSubnormal);
- bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN();
- if (IsFDiv) {
- KnowSomethingUseful |=
- KnownRHS.isKnownNever(fcNegNormal | fcNegSubnormal) ||
- KnownRHS.isKnownNever(fcPosNormal | fcPosSubnormal);
- } else {
- KnowSomethingUseful |= KnownRHS.isKnownNever(fcNegative) ||
- KnownRHS.isKnownNever(fcPositive);
+ if (KnowSomethingUseful)
+ computeKnownFPClass(LHS, DemandedElts, fcAllFlags, KnownLHS, Depth + 1);
+
+ Known = KnownFPClass::fdiv(KnownLHS, KnownRHS, Mode);
+ break;
+ }
+ case TargetOpcode::G_FREM: {
+ const bool WantNan = (InterestedClasses & fcNan) != fcNone;
+
+ Register LHS = MI.getOperand(1).getReg();
+ Register RHS = MI.getOperand(2).getReg();
+
+ Known.knownNot(fcInf);
+
+ DenormalMode Mode =
+ MF->getDenormalMode(getFltSemanticForLLT(DstTy.getScalarType()));
+
+ if (LHS == RHS && isGuaranteedNotToBeUndef(LHS, MRI, Depth + 1)) {
+ // X % X is always exactly [+-]0.0 or a NaN.
+ Known.KnownFPClasses = fcZero | fcNan;
+
+ if (!WantNan)
+ break;
+
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(LHS, DemandedElts,
+ fcNan | fcInf | fcZero | fcSubnormal, KnownSrc,
+ Depth + 1);
+ Known = KnownFPClass::frem_self(KnownSrc, Mode);
+ break;
}
- if (KnowSomethingUseful || (!IsFDiv && WantPositive)) {
+ const bool WantNegative = (InterestedClasses & fcNegative) != fcNone;
+ const bool WantPositive = (InterestedClasses & fcPositive) != fcNone;
+ if (!WantNan && !WantNegative && !WantPositive)
+ break;
+
+ KnownFPClass KnownLHS, KnownRHS;
+ computeKnownFPClass(RHS, DemandedElts, fcNan | fcInf | fcZero | fcNegative,
+ KnownRHS, Depth + 1);
+
+ bool KnowSomethingUseful = KnownRHS.isKnownNeverNaN() ||
+ KnownRHS.isKnownNever(fcNegative) ||
+ KnownRHS.isKnownNever(fcPositive);
+
+ if (KnowSomethingUseful || WantPositive)
computeKnownFPClass(LHS, DemandedElts, fcAllFlags, KnownLHS, Depth + 1);
+
+ // Inf REM x and x REM 0 produce NaN.
+ if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
+ KnownLHS.isKnownNeverInfinity() &&
+ KnownRHS.isKnownNeverLogicalZero(Mode)) {
+ Known.knownNot(fcNan);
}
- if (IsFDiv) {
- Known = KnownFPClass::fdiv(KnownLHS, KnownRHS, Mode);
- } else {
- // Inf REM x and x REM 0 produce NaN.
- if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
- KnownLHS.isKnownNeverInfinity() &&
- KnownRHS.isKnownNeverLogicalZero(Mode)) {
- Known.knownNot(fcNan);
- }
+ // The sign for frem is the same as the first operand.
+ if (KnownLHS.cannotBeOrderedLessThanZero())
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ if (KnownLHS.cannotBeOrderedGreaterThanZero())
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- // The sign for frem is the same as the first operand.
- if (KnownLHS.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- if (KnownLHS.cannotBeOrderedGreaterThanZero())
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+ // See if we can be more aggressive about the sign of 0.
+ if (KnownLHS.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ if (KnownLHS.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
- // See if we can be more aggressive about the sign of 0.
- if (KnownLHS.isKnownNever(fcNegative))
- Known.knownNot(fcNegative);
- if (KnownLHS.isKnownNever(fcPositive))
- Known.knownNot(fcPositive);
- }
break;
}
case TargetOpcode::G_FFREXP: {
More information about the llvm-commits
mailing list