//===- llvm/Support/KnownFPClass.h - Stores known fplcass -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a class for representing known fpclasses used by
// computeKnownFPClass.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/KnownFPClass.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"

using namespace llvm;

KnownFPClass::KnownFPClass(const APFloat &C)
    : KnownFPClasses(C.classify()), SignBit(C.isNegative()) {}

/// Return true if it's possible to assume IEEE treatment of input denormals in
/// \p F for \p Val.
static bool inputDenormalIsIEEE(DenormalMode Mode) {
  return Mode.Input == DenormalMode::IEEE;
}

static bool inputDenormalIsIEEEOrPosZero(DenormalMode Mode) {
  return Mode.Input == DenormalMode::IEEE ||
         Mode.Input == DenormalMode::PositiveZero;
}

bool KnownFPClass::isKnownNeverLogicalZero(DenormalMode Mode) const {
  return isKnownNeverZero() &&
         (isKnownNeverSubnormal() || inputDenormalIsIEEE(Mode));
}

bool KnownFPClass::isKnownNeverLogicalNegZero(DenormalMode Mode) const {
  return isKnownNeverNegZero() &&
         (isKnownNeverNegSubnormal() || inputDenormalIsIEEEOrPosZero(Mode));
}

bool KnownFPClass::isKnownNeverLogicalPosZero(DenormalMode Mode) const {
  if (!isKnownNeverPosZero())
    return false;

  // If we know there are no denormals, nothing can be flushed to zero.
  if (isKnownNeverSubnormal())
    return true;

  switch (Mode.Input) {
  case DenormalMode::IEEE:
    return true;
  case DenormalMode::PreserveSign:
    // Negative subnormal won't flush to +0
    return isKnownNeverPosSubnormal();
  case DenormalMode::PositiveZero:
  default:
    // Both positive and negative subnormal could flush to +0
    return false;
  }

  llvm_unreachable("covered switch over denormal mode");
}

void KnownFPClass::propagateDenormal(const KnownFPClass &Src,
                                     DenormalMode Mode) {
  KnownFPClasses = Src.KnownFPClasses;
  // If we aren't assuming the source can't be a zero, we don't have to check if
  // a denormal input could be flushed.
  if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
    return;

  // If we know the input can't be a denormal, it can't be flushed to 0.
  if (Src.isKnownNeverSubnormal())
    return;

  if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
    KnownFPClasses |= fcPosZero;

  if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
    if (Mode != DenormalMode::getPositiveZero())
      KnownFPClasses |= fcNegZero;

    if (Mode.Input == DenormalMode::PositiveZero ||
        Mode.Output == DenormalMode::PositiveZero ||
        Mode.Input == DenormalMode::Dynamic ||
        Mode.Output == DenormalMode::Dynamic)
      KnownFPClasses |= fcPosZero;
  }
}

KnownFPClass KnownFPClass::minMaxLike(const KnownFPClass &LHS_,
                                      const KnownFPClass &RHS_, MinMaxKind Kind,
                                      DenormalMode Mode) {
  KnownFPClass KnownLHS = LHS_;
  KnownFPClass KnownRHS = RHS_;

  bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
  KnownFPClass Known = KnownLHS | KnownRHS;

  // If either operand is not NaN, the result is not NaN.
  if (NeverNaN &&
      (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
       Kind == MinMaxKind::minimumnum || Kind == MinMaxKind::maximumnum))
    Known.knownNot(fcNan);

  if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
    // If at least one operand is known to be positive, the result must be
    // positive.
    if ((KnownLHS.cannotBeOrderedLessThanZero() &&
         KnownLHS.isKnownNeverNaN()) ||
        (KnownRHS.cannotBeOrderedLessThanZero() && KnownRHS.isKnownNeverNaN()))
      Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
  } else if (Kind == MinMaxKind::maximum) {
    // If at least one operand is known to be positive, the result must be
    // positive.
    if (KnownLHS.cannotBeOrderedLessThanZero() ||
        KnownRHS.cannotBeOrderedLessThanZero())
      Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
  } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
    // If at least one operand is known to be negative, the result must be
    // negative.
    if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
         KnownLHS.isKnownNeverNaN()) ||
        (KnownRHS.cannotBeOrderedGreaterThanZero() &&
         KnownRHS.isKnownNeverNaN()))
      Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
  } else if (Kind == MinMaxKind::minimum) {
    // If at least one operand is known to be negative, the result must be
    // negative.
    if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
        KnownRHS.cannotBeOrderedGreaterThanZero())
      Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
  } else
    llvm_unreachable("unhandled intrinsic");

  // Fixup zero handling if denormals could be returned as a zero.
  //
  // As there's no spec for denormal flushing, be conservative with the
  // treatment of denormals that could be flushed to zero. For older
  // subtargets on AMDGPU the min/max instructions would not flush the
  // output and return the original value.
  //
  if ((Known.KnownFPClasses & fcZero) != fcNone &&
      !Known.isKnownNeverSubnormal()) {
    if (Mode != DenormalMode::getIEEE())
      Known.KnownFPClasses |= fcZero;
  }

  if (Known.isKnownNeverNaN()) {
    if (KnownLHS.SignBit && KnownRHS.SignBit &&
        *KnownLHS.SignBit == *KnownRHS.SignBit) {
      if (*KnownLHS.SignBit)
        Known.signBitMustBeOne();
      else
        Known.signBitMustBeZero();
    } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
                Kind == MinMaxKind::maximumnum ||
                Kind == MinMaxKind::minimumnum) ||
               // FIXME: Should be using logical zero versions
               ((KnownLHS.isKnownNeverNegZero() ||
                 KnownRHS.isKnownNeverPosZero()) &&
                (KnownLHS.isKnownNeverPosZero() ||
                 KnownRHS.isKnownNeverNegZero()))) {
      // Don't take sign bit from NaN operands.
      if (!KnownLHS.isKnownNeverNaN())
        KnownLHS.SignBit = std::nullopt;
      if (!KnownRHS.isKnownNeverNaN())
        KnownRHS.SignBit = std::nullopt;
      if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
           Kind == MinMaxKind::maxnum) &&
          (KnownLHS.SignBit == false || KnownRHS.SignBit == false))
        Known.signBitMustBeZero();
      else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
                Kind == MinMaxKind::minnum) &&
               (KnownLHS.SignBit == true || KnownRHS.SignBit == true))
        Known.signBitMustBeOne();
    }
  }

  return Known;
}

KnownFPClass KnownFPClass::canonicalize(const KnownFPClass &KnownSrc,
                                        DenormalMode DenormMode) {
  KnownFPClass Known;

  // This is essentially a stronger form of
  // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
  // actually have an IR canonicalization guarantee.

  // Canonicalize may flush denormals to zero, so we have to consider the
  // denormal mode to preserve known-not-0 knowledge.
  Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;

  // Stronger version of propagateNaN
  // Canonicalize is guaranteed to quiet signaling nans.
  if (KnownSrc.isKnownNeverNaN())
    Known.knownNot(fcNan);
  else
    Known.knownNot(fcSNan);

  // FIXME: Missing check of IEEE like types.

  // If the parent function flushes denormals, the canonical output cannot be a
  // denormal.
  if (DenormMode == DenormalMode::getIEEE()) {
    if (KnownSrc.isKnownNever(fcPosZero))
      Known.knownNot(fcPosZero);
    if (KnownSrc.isKnownNever(fcNegZero))
      Known.knownNot(fcNegZero);
    return Known;
  }

  if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
    Known.knownNot(fcSubnormal);

  if (DenormMode == DenormalMode::getPreserveSign()) {
    if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
      Known.knownNot(fcPosZero);
    if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
      Known.knownNot(fcNegZero);
    return Known;
  }

  if (DenormMode.Input == DenormalMode::PositiveZero ||
      (DenormMode.Output == DenormalMode::PositiveZero &&
       DenormMode.Input == DenormalMode::IEEE))
    Known.knownNot(fcNegZero);

  return Known;
}

KnownFPClass KnownFPClass::bitcast(const fltSemantics &FltSemantics,
                                   const KnownBits &Bits) {
  assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
         "Bitcast operand has incorrect bit width");
  KnownFPClass Known;

  // Transfer information from the sign bit.
  if (Bits.isNonNegative())
    Known.signBitMustBeZero();
  else if (Bits.isNegative())
    Known.signBitMustBeOne();

  if (APFloat::isIEEELikeFP(FltSemantics)) {
    // IEEE floats are NaN when all bits of the exponent plus at least one of
    // the fraction bits are 1. This means:
    //   - If we assume unknown bits are 0 and the value is NaN, it will
    //     always be NaN
    //   - If we assume unknown bits are 1 and the value is not NaN, it can
    //     never be NaN
    // Note: They do not hold for x86_fp80 format.
    if (APFloat(FltSemantics, Bits.One).isNaN())
      Known.KnownFPClasses = fcNan;
    else if (!APFloat(FltSemantics, ~Bits.Zero).isNaN())
      Known.knownNot(fcNan);

    // Build KnownBits representing Inf and check if it must be equal or
    // unequal to this value.
    auto InfKB =
        KnownBits::makeConstant(APFloat::getInf(FltSemantics).bitcastToAPInt());
    InfKB.Zero.clearSignBit();
    if (const auto InfResult = KnownBits::eq(Bits, InfKB)) {
      assert(!InfResult.value());
      Known.knownNot(fcInf);
    } else if (Bits == InfKB) {
      Known.KnownFPClasses = fcInf;
    }

    // Build KnownBits representing Zero and check if it must be equal or
    // unequal to this value.
    auto ZeroKB = KnownBits::makeConstant(
        APFloat::getZero(FltSemantics).bitcastToAPInt());
    ZeroKB.Zero.clearSignBit();
    if (const auto ZeroResult = KnownBits::eq(Bits, ZeroKB)) {
      assert(!ZeroResult.value());
      Known.knownNot(fcZero);
    } else if (Bits == ZeroKB) {
      Known.KnownFPClasses = fcZero;
    }
  }

  return Known;
}

// Handle known sign bit and nan cases for fadd.
static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
                              const KnownFPClass &KnownRHS, DenormalMode Mode) {
  KnownFPClass Known;

  // Adding positive and negative infinity produces NaN, but only if both
  // opposite-sign infinity combinations are possible.
  if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
      (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
      (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
    Known.knownNot(fcNan);

  if (KnownLHS.cannotBeOrderedLessThanZero() &&
      KnownRHS.cannotBeOrderedLessThanZero()) {
    Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);

    // This can't underflow if one of the operands is known normal.
    if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
        KnownRHS.isKnownNever(fcZero | fcPosSubnormal))
      Known.knownNot(fcZero | fcPosSubnormal);
  }

  if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
      KnownRHS.cannotBeOrderedGreaterThanZero()) {
    Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);

    // This can't underflow if one of the operands is known normal.
    if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
        KnownRHS.isKnownNever(fcZero | fcNegSubnormal))
      Known.knownNot(fcZero | fcNegSubnormal);
  }

  return Known;
}

KnownFPClass KnownFPClass::fadd(const KnownFPClass &KnownLHS,
                                const KnownFPClass &KnownRHS,
                                DenormalMode Mode) {
  KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);

  // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
  if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
       KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
      // Make sure output negative denormal can't flush to -0
      (Mode.Output == DenormalMode::IEEE ||
       Mode.Output == DenormalMode::PositiveZero))
    Known.knownNot(fcNegZero);

  return Known;
}

KnownFPClass KnownFPClass::fadd_self(const KnownFPClass &KnownSrc,
                                     DenormalMode Mode) {
  KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);

  // Doubling 0 will give the same 0.
  if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
      (Mode.Output == DenormalMode::IEEE ||
       (Mode.Output == DenormalMode::PreserveSign &&
        KnownSrc.isKnownNeverPosSubnormal()) ||
       (Mode.Output == DenormalMode::PositiveZero &&
        KnownSrc.isKnownNeverSubnormal())))
    Known.knownNot(fcPosZero);

  return Known;
}

KnownFPClass KnownFPClass::fsub(const KnownFPClass &KnownLHS,
                                const KnownFPClass &KnownRHS,
                                DenormalMode Mode) {
  return fadd(KnownLHS, fneg(KnownRHS), Mode);
}

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

  // +X * +Y or -X * -Y => +Q
  // +X * -Y or -X * +Y => -Q
  Known.propagateXorSign(KnownLHS, KnownRHS);

  // Inf * Y => Inf or NaN
  if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
      KnownRHS.isKnownAlways(fcInf | fcNan))
    Known.knownNot(fcNormal | fcSubnormal | fcZero);

  // 0 * Y => 0 or NaN
  if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
      KnownLHS.isKnownAlways(fcZero | fcNan))
    Known.knownNot(fcNormal | fcSubnormal | fcInf);

  if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
    return Known;

  // 0 * +/-inf => NaN
  if ((KnownRHS.isKnownNeverInfinity() ||
       KnownLHS.isKnownNeverLogicalZero(Mode)) &&
      (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);
  }

  //  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
  if (KnownLHS.isKnownAlways(fcZero))
    Known.knownNot(fcSubnormal | fcNormal | fcInf);

  // X / 0 => NaN or Inf
  if (KnownRHS.isKnownAlways(fcZero))
    Known.knownNot(fcFinite);

  return Known;
}

KnownFPClass KnownFPClass::fdiv_self(const KnownFPClass &KnownSrc,
                                     DenormalMode Mode) {
  // X / X is always exactly 1.0 or a NaN.
  KnownFPClass Known(fcNan | fcPosNormal);

  if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
    Known.knownNot(fcNan);
  else if (KnownSrc.isKnownNever(fcSNan))
    Known.knownNot(fcSNan);

  return Known;
}
KnownFPClass KnownFPClass::frem_self(const KnownFPClass &KnownSrc,
                                     DenormalMode Mode) {
  // X % X is always exactly [+-]0.0 or a NaN.
  KnownFPClass Known(fcNan | fcZero);

  if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
    Known.knownNot(fcNan);
  else if (KnownSrc.isKnownNever(fcSNan))
    Known.knownNot(fcSNan);

  return Known;
}

KnownFPClass KnownFPClass::fma(const KnownFPClass &KnownLHS,
                               const KnownFPClass &KnownRHS,
                               const KnownFPClass &KnownAddend,
                               DenormalMode Mode) {
  KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);

  // FMA differs from the base fmul + fadd handling only in the treatment of -0
  // results.
  //
  // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
  // unlike for a separate fadd.
  return fadd_impl(Mul, KnownAddend, Mode);
}

KnownFPClass KnownFPClass::fma_square(const KnownFPClass &KnownSquared,
                                      const KnownFPClass &KnownAddend,
                                      DenormalMode Mode) {
  KnownFPClass Squared = square(KnownSquared, Mode);
  KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);

  // Since we know the squared input must be positive, the add of opposite sign
  // infinities nan hazard only applies for negative inf.
  //
  // TODO: Alternatively to proving addend is not -inf, we could know Squared is
  // not pinf. Other than the degenerate always-subnormal input case, we can't
  // prove that without a known range.
  if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
    Known.knownNot(fcNan);

  return Known;
}

KnownFPClass KnownFPClass::exp(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;
  Known.knownNot(fcNegative);

  Known.propagateNaN(KnownSrc);

  if (KnownSrc.cannotBeOrderedLessThanZero()) {
    // If the source is positive this cannot underflow.
    Known.knownNot(fcPosZero);

    // Cannot introduce denormal values.
    Known.knownNot(fcPosSubnormal);
  }

  // If the source is negative, this cannot overflow to infinity.
  if (KnownSrc.cannotBeOrderedGreaterThanZero())
    Known.knownNot(fcPosInf);

  return Known;
}

void KnownFPClass::propagateCanonicalizingSrc(const KnownFPClass &Src,
                                              DenormalMode Mode) {
  propagateDenormal(Src, Mode);
  propagateNaN(Src, /*PreserveSign=*/true);
}

KnownFPClass KnownFPClass::log(const KnownFPClass &KnownSrc,
                               DenormalMode Mode) {
  KnownFPClass Known;
  Known.knownNot(fcNegZero | fcSubnormal);

  if (KnownSrc.isKnownNeverPosInfinity())
    Known.knownNot(fcPosInf);

  if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
    Known.knownNot(fcNan);

  if (KnownSrc.isKnownNeverLogicalZero(Mode))
    Known.knownNot(fcNegInf);

  return Known;
}

KnownFPClass KnownFPClass::sqrt(const KnownFPClass &KnownSrc,
                                DenormalMode Mode) {
  KnownFPClass Known;
  Known.knownNot(fcPosSubnormal);

  if (KnownSrc.isKnownNeverPosInfinity())
    Known.knownNot(fcPosInf);
  if (KnownSrc.isKnownNever(fcSNan))
    Known.knownNot(fcSNan);

  // Any negative value besides -0 returns a nan.
  if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
    Known.knownNot(fcNan);

  // The only negative value that can be returned is -0 for -0 inputs.
  Known.knownNot(fcNegInf | fcNegSubnormal | fcNegNormal);

  // If the input denormal mode could be PreserveSign, a negative
  // subnormal input could produce a negative zero output.
  if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
    Known.knownNot(fcNegZero);

  return Known;
}

KnownFPClass KnownFPClass::sin(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // Return NaN on infinite inputs.
  Known.knownNot(fcInf);
  if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
    Known.knownNot(fcNan);

  return Known;
}

KnownFPClass KnownFPClass::cos(const KnownFPClass &KnownSrc) {
  return sin(KnownSrc);
}

KnownFPClass KnownFPClass::tan(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
  Known.knownNot(fcInf);

  // NaN propagates. tan(+-Inf) is NaN.
  if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
    Known.knownNot(fcNan);

  return Known;
}

KnownFPClass KnownFPClass::sinh(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);

  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::cosh(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative.
  Known.knownNot(fcNegative);

  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::tanh(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // tanh is bounded to (-1, 1), never Inf.
  Known.knownNot(fcInf);

  // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);

  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::asin(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // asin is bounded to [-pi/2, pi/2], never Inf.
  Known.knownNot(fcInf);

  // asin is sign-preserving.
  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);

  // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
  // out NaN without knowing the source is in [-1, 1].
  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::acos(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // acos is bounded to [0, pi], never Inf or negative.
  Known.knownNot(fcInf);
  Known.knownNot(fcNegative);

  // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
  // out NaN without knowing the source is in [-1, 1].
  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::atan(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
  Known.knownNot(fcInf);

  // atan is sign-preserving: atan(x) < 0 iff x < 0.
  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);

  Known.propagateNaN(KnownSrc);

  return Known;
}

KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownLHS,
                                 const KnownFPClass &KnownRHS) {
  KnownFPClass Known;

  // atan2 result is in (-pi, pi], never Inf.
  Known.knownNot(fcInf);

  // NaN if either operand is NaN.
  if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN())
    Known.knownNot(fcNan);

  return Known;
}

KnownFPClass KnownFPClass::fpext(const KnownFPClass &KnownSrc,
                                 const fltSemantics &DstTy,
                                 const fltSemantics &SrcTy) {
  // Infinity, nan and zero propagate from source.
  KnownFPClass Known = KnownSrc;

  // All subnormal inputs should be in the normal range in the result type.
  if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
    if (Known.KnownFPClasses & fcPosSubnormal)
      Known.KnownFPClasses |= fcPosNormal;
    if (Known.KnownFPClasses & fcNegSubnormal)
      Known.KnownFPClasses |= fcNegNormal;
    Known.knownNot(fcSubnormal);
  }

  // Sign bit of a nan isn't guaranteed.
  if (!Known.isKnownNeverNaN())
    Known.SignBit = std::nullopt;

  return Known;
}

KnownFPClass KnownFPClass::fptrunc(const KnownFPClass &KnownSrc) {
  KnownFPClass Known;

  // Sign should be preserved
  // TODO: Handle cannot be ordered greater than zero
  if (KnownSrc.cannotBeOrderedLessThanZero())
    Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);

  Known.propagateNaN(KnownSrc, true);

  // Infinity needs a range check.
  return Known;
}

KnownFPClass KnownFPClass::roundToIntegral(const KnownFPClass &KnownSrc,
                                           bool IsTrunc,
                                           bool IsMultiUnitFPType) {
  KnownFPClass Known;

  // Integer results cannot be subnormal.
  Known.knownNot(fcSubnormal);

  Known.propagateNaN(KnownSrc, true);

  // Pass through infinities, except PPC_FP128 is a special case for
  // intrinsics other than trunc.
  if (IsTrunc || !IsMultiUnitFPType) {
    if (KnownSrc.isKnownNeverPosInfinity())
      Known.knownNot(fcPosInf);
    if (KnownSrc.isKnownNeverNegInfinity())
      Known.knownNot(fcNegInf);
  }

  // Negative round ups to 0 produce -0
  if (KnownSrc.isKnownNever(fcPosFinite))
    Known.knownNot(fcPosFinite);
  if (KnownSrc.isKnownNever(fcNegFinite))
    Known.knownNot(fcNegFinite);

  return Known;
}

KnownFPClass KnownFPClass::frexp_mant(const KnownFPClass &KnownSrc,
                                      DenormalMode Mode) {
  KnownFPClass Known;
  Known.knownNot(fcSubnormal);

  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);
  else {
    if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
      Known.knownNot(fcNegZero);
    if (KnownSrc.isKnownNever(fcNegInf))
      Known.knownNot(fcNegInf);
  }

  if (KnownSrc.isKnownNever(fcPositive))
    Known.knownNot(fcPositive);
  else {
    if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
      Known.knownNot(fcPosZero);
    if (KnownSrc.isKnownNever(fcPosInf))
      Known.knownNot(fcPosInf);
  }

  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;
}

KnownFPClass KnownFPClass::powi(const KnownFPClass &KnownSrc,
                                const KnownBits &ExponentKnownBits) {
  KnownFPClass Known;
  Known.propagateNaN(KnownSrc);

  if (ExponentKnownBits.isZero()) {
    // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
    // return 1.0 or a NaN.
    if (KnownSrc.isKnownNever(fcSNan)) {
      Known.knownNot(~fcPosNormal);
      return Known;
    }

    Known.knownNot(~(fcPosNormal | fcNan));
    return Known;
  }

  // powi(x, exp) --> inf
  // when:
  //   * powi(inf, exp), exp > 0
  //   * powi(+/-0, exp), exp < 0
  //   * powi(finite, exp), |exp| > 1
  //   * powi(subnormal, -1)
  // TODO:
  //   1. This simple all or nothing approach. We can do better
  //      and cover sign/parity and exp > 1 vs exp < -1 separately.
  //   2. powi(0/nan, exp), exp > 0 can be refinable
  //      to fcNan | fcZero | fcPosNormal.
  {
    APInt MinExp = ExponentKnownBits.getSignedMinValue();
    APInt MaxExp = ExponentKnownBits.getSignedMaxValue();

    // powi(inf, exp), exp > 0
    bool MayInfSrc =
        !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();

    // powi(+/-0, exp), exp < 0
    bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();

    // powi(finite, exp), |exp| > 1
    bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
    bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
    bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;

    // powi(subnormal, -1)
    bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
    bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;

    if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
      Known.knownNot(fcInf);
  }

  if (ExponentKnownBits.isEven()) {
    Known.knownNot(fcNegative);
    return Known;
  }

  // Given that exp is an integer, here are the
  // ways that pow can return a negative value:
  //
  //   pow(-x, exp)   --> negative if exp is odd and x is negative.
  //   pow(-0, exp)   --> -inf if exp is negative odd.
  //   pow(-0, exp)   --> -0 if exp is positive odd.
  //   pow(-inf, exp) --> -0 if exp is negative odd.
  //   pow(-inf, exp) --> -inf if exp is positive odd.
  if (KnownSrc.isKnownNever(fcNegative))
    Known.knownNot(fcNegative);

  return Known;
}
