//===- 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 (KnownLHS.isKnownNeverNaN())
      Known.knownNot(orderedStrictlyLess(KnownLHS.KnownFPClasses));
    if (KnownRHS.isKnownNeverNaN())
      Known.knownNot(orderedStrictlyLess(KnownRHS.KnownFPClasses));
  } else if (Kind == MinMaxKind::maximum) {
    Known.knownNot(orderedStrictlyLess(KnownLHS.KnownFPClasses) |
                   orderedStrictlyLess(KnownRHS.KnownFPClasses));
  } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
    if (KnownLHS.isKnownNeverNaN())
      Known.knownNot(orderedStrictlyGreater(KnownLHS.KnownFPClasses));
    if (KnownRHS.isKnownNeverNaN())
      Known.knownNot(orderedStrictlyGreater(KnownRHS.KnownFPClasses));
  } else if (Kind == MinMaxKind::minimum) {
    Known.knownNot(orderedStrictlyGreater(KnownLHS.KnownFPClasses) |
                   orderedStrictlyGreater(KnownRHS.KnownFPClasses));
  } 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)) {
    // -0.0 is not a subnormal and should not be flushed.
    if (KnownSrc.isKnownNever(fcNegZero))
      Known.knownNot(fcNegZero);

    if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
      Known.knownNot(fcPosZero);
  }

  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 APInt &ConstantRangeExpMin,
                                 const APInt &ConstantRangeExpMax,
                                 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 (ConstantRangeExpMin.sge(MantissaBits))
    Known.knownNot(fcSubnormal);

  if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
    // ldexp(x, 0) -> x, so propagate everything.
    Known.propagateCanonicalizingSrc(KnownSrc, Mode);
  } else if (ConstantRangeExpMax.isNonPositive()) {
    // 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 (ConstantRangeExpMin.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::ldexp(const KnownFPClass &KnownSrc,
                                 const KnownBits &ExpBits,
                                 const fltSemantics &Flt, DenormalMode Mode) {
  return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
               ExpBits.getSignedMaxValue(), Flt, Mode);
}

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