Repository: llvm/llvm-project
File: llvm/lib/Support/KnownFPClass.cpp (C++)

Code before:
      (KnownLHS.isKnownNeverInfinity() ||
       KnownRHS.isKnownNeverLogicalZero(Mode)))
    Known.knownNot(fcNan);

  return Known;
}

// TODO: This generalizes to known ranges
KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
                                const APFloat &CRHS, DenormalMode Mode) {
  // Match denormal scaling pattern, similar to the case in ldexp. If the
  // constant's exponent is sufficiently large, the result cannot be subnormal.

  const fltSemantics &Flt = CRHS.getSemantics();
  unsigned Precision = APFloat::semanticsPrecision(Flt);
  const int MantissaBits = Precision - 1;

  int MinKnownExponent = ilogb(CRHS);
  bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);

  KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
  if (CannotBeSubnormal)
    Known.knownNot(fcSubnormal);

  // Multiply of values <= 1 cannot introduce overflow.
  if (KnownLHS.isKnownNever(fcInf) && MinKnownExponent <= 0)
    Known.knownNot(fcInf);

  return Known;
}

KnownFPClass KnownFPClass::fdiv(const KnownFPClass &KnownLHS,
                                const KnownFPClass &KnownRHS,
                                DenormalMode Mode) {
  KnownFPClass Known;

  // Only 0/0, Inf/Inf produce NaN.
  if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
      (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
      (KnownLHS.isKnownNeverLogicalZero(Mode) ||
       KnownRHS.isKnownNeverLogicalZero(Mode))) {
    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);

Review comment (suggestion):
`ilogb` returns `floor(log2(fabs(x)))`: https://godbolt.org/z/644seE3nh

https://github.com/llvm/llvm-project/blob/6874e945fe9d57d49c9c0902ffeeb8ffe03033a3/llvm/include/llvm/ADT/APFloat.h#L1588-L1597

Code after:
      (KnownLHS.isKnownNeverInfinity() ||
       KnownRHS.isKnownNeverLogicalZero(Mode)))
    Known.knownNot(fcNan);

  return Known;
}

// TODO: This generalizes to known ranges
KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
                                const APFloat &CRHS, DenormalMode Mode) {
  // Match denormal scaling pattern, similar to the case in ldexp. If the
  // constant's exponent is sufficiently large, the result cannot be subnormal.

  const fltSemantics &Flt = CRHS.getSemantics();
  unsigned Precision = APFloat::semanticsPrecision(Flt);
  const int MantissaBits = Precision - 1;

  int MinKnownExponent = ilogb(CRHS);
  bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);

  KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
  if (CannotBeSubnormal)
    Known.knownNot(fcSubnormal);

  // Multiply of values <= 1 cannot introduce overflow.
  if (KnownLHS.isKnownNever(fcInf)) {
    if (MinKnownExponent < 0)
      Known.knownNot(fcInf);
    else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
                                          Flt)) == APFloat::cmpEqual)
      Known.knownNot(fcInf);
  }

  return Known;
}

KnownFPClass KnownFPClass::fdiv(const KnownFPClass &KnownLHS,
                                const KnownFPClass &KnownRHS,
                                DenormalMode Mode) {
  KnownFPClass Known;

  // Only 0/0, Inf/Inf produce NaN.
  if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
      (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
      (KnownLHS.isKnownNeverLogicalZero(Mode) ||
       KnownRHS.isKnownNeverLogicalZero(Mode))) {
    Known.knownNot(fcNan);
  }

  // xor sign bit.
  // X / -0.0 is -Inf (or NaN).