[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