[llvm] 39e30cc - [KnowFPClass] Refactor fmul & fdiv (NFC) (#191651)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 30 02:24:59 PDT 2026


Author: Max Graey
Date: 2026-04-30T10:24:55+01:00
New Revision: 39e30cc8a1fa7be2f6d0ff607969ac0a46219924

URL: https://github.com/llvm/llvm-project/commit/39e30cc8a1fa7be2f6d0ff607969ac0a46219924
DIFF: https://github.com/llvm/llvm-project/commit/39e30cc8a1fa7be2f6d0ff607969ac0a46219924.diff

LOG: [KnowFPClass] Refactor fmul & fdiv (NFC) (#191651)

- Remove `0 * Inf ->  NaN` redundant check and a nan setting.

  The reason:
  ```rust
  1. Inf * Y   ->  {Inf, NaN}
  2.   0 * Y   ->  {Zero, NaN}
  3.   0 * Inf ->  NaN
  ```
But after `1.` and `2.` we already have `{Inf, NaN} ∩ {Zero, NaN} ->
NaN`
So `3.` is redundant and [can be
removed](https://github.com/llvm/llvm-project/pull/191651/changes#diff-eacbd8c8620db92a00453be14b3b433c618946ad7b57c10b039437641e9777c4L389):
```diff
   // +/-0 * +/-inf = nan
-  if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
-       KnownRHS.isKnownAlways(fcInf | fcNan)) ||
-      (KnownLHS.isKnownAlways(fcInf | fcNan) &&
-       KnownRHS.isKnownAlways(fcZero | fcNan)))
-    Known.knownNot(~fcNan);
```
- Group repeated twice sign inferring into `propagateXorSign` helper
- Add more conventional comments

Added: 
    

Modified: 
    llvm/include/llvm/Support/KnownFPClass.h
    llvm/lib/Support/KnownFPClass.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 3ded51909615b..7e018d25d2d1d 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -391,6 +391,19 @@ struct KnownFPClass {
       knownNot(fcSNan);
   }
 
+  // Propagate knowledge for operations whose result sign is the xor of the
+  // operand signs, such as multiply and divide. This only rules out possible
+  // non-NaN sign classes. NaNs do not have a constrained sign class here.
+  void propagateXorSign(const KnownFPClass &LHS, const KnownFPClass &RHS) {
+    if ((LHS.isKnownNever(fcNegative) && RHS.isKnownNever(fcNegative)) ||
+        (LHS.isKnownNever(fcPositive) && RHS.isKnownNever(fcPositive)))
+      knownNot(fcNegative);
+
+    if ((LHS.isKnownNever(fcPositive) && RHS.isKnownNever(fcNegative)) ||
+        (LHS.isKnownNever(fcNegative) && RHS.isKnownNever(fcPositive)))
+      knownNot(fcPositive);
+  }
+
   /// Propagate knowledge from a source value that could be a denormal or
   /// zero. We have to be conservative since output flushing is not guaranteed,
   /// so known-never-zero may not hold.

diff  --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 856d227961c0a..3e2f6a1704b01 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -365,38 +365,24 @@ KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
                                 DenormalMode Mode) {
   KnownFPClass Known;
 
-  // xor sign bit.
-  if ((KnownLHS.isKnownNever(fcNegative) &&
-       KnownRHS.isKnownNever(fcNegative)) ||
-      (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
-    Known.knownNot(fcNegative);
-
-  if ((KnownLHS.isKnownNever(fcPositive) &&
-       KnownRHS.isKnownNever(fcNegative)) ||
-      (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
-    Known.knownNot(fcPositive);
+  // +X * +Y or -X * -Y => +Q
+  // +X * -Y or -X * +Y => -Q
+  Known.propagateXorSign(KnownLHS, KnownRHS);
 
-  // inf * anything => inf or nan
+  // Inf * Y => Inf or NaN
   if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
       KnownRHS.isKnownAlways(fcInf | fcNan))
     Known.knownNot(fcNormal | fcSubnormal | fcZero);
 
-  // 0 * anything => 0 or nan
+  // 0 * Y => 0 or NaN
   if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
       KnownLHS.isKnownAlways(fcZero | fcNan))
     Known.knownNot(fcNormal | fcSubnormal | fcInf);
 
-  // +/-0 * +/-inf = nan
-  if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
-       KnownRHS.isKnownAlways(fcInf | fcNan)) ||
-      (KnownLHS.isKnownAlways(fcInf | fcNan) &&
-       KnownRHS.isKnownAlways(fcZero | fcNan)))
-    Known.knownNot(~fcNan);
-
   if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
     return Known;
 
-  // If 0 * +/-inf produces NaN.
+  // 0 * +/-inf => NaN
   if ((KnownRHS.isKnownNeverInfinity() ||
        KnownLHS.isKnownNeverLogicalZero(Mode)) &&
       (KnownLHS.isKnownNeverInfinity() ||
@@ -448,24 +434,16 @@ KnownFPClass KnownFPClass::fdiv(const KnownFPClass &KnownLHS,
     Known.knownNot(fcNan);
   }
 
-  // xor sign bit.
-  // X / -0.0 is -Inf (or NaN).
-  // +X / +X is +X
-  if ((KnownLHS.isKnownNever(fcNegative) &&
-       KnownRHS.isKnownNever(fcNegative)) ||
-      (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
-    Known.knownNot(fcNegative);
-
-  if ((KnownLHS.isKnownNever(fcPositive) &&
-       KnownRHS.isKnownNever(fcNegative)) ||
-      (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
-    Known.knownNot(fcPositive);
+  //  X / -0.0 => -Inf (or NaN)
+  // +X / +Y or -X / -Y => +Q
+  // +X / -Y or -X / +Y => -Q
+  Known.propagateXorSign(KnownLHS, KnownRHS);
 
-  // 0 / x => 0 or nan
+  // 0 / X => 0 or NaN
   if (KnownLHS.isKnownAlways(fcZero))
     Known.knownNot(fcSubnormal | fcNormal | fcInf);
 
-  // x / 0 => nan or inf
+  // X / 0 => NaN or Inf
   if (KnownRHS.isKnownAlways(fcZero))
     Known.knownNot(fcFinite);
 


        


More information about the llvm-commits mailing list