//===--- ExpandIRInsts.cpp - Expand IR instructions -----------------------===//
//
// 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 pass expands certain instructions at the IR level.
//
// The following expansions are implemented:
// - Expansion of ‘fptoui .. to’, ‘fptosi .. to’, ‘uitofp ..  to’, ‘sitofp
// .. to’ instructions with a bitwidth above a threshold.  This is
// useful for targets like x86_64 that cannot lower fp convertions
// with more than 128 bits.
//
// - Expansion of ‘frem‘ for types MVT::f16, MVT::bf16, MVT::f32, and MVT::f64
// for targets which use "Expand" as the legalization action for the
// corresponding type.
//
// - Expansion of ‘udiv‘, ‘sdiv‘, ‘urem‘, and ‘srem‘ instructions with
// a bitwidth above a threshold into a call to auto-generated
// functions.  This is useful for targets like x86_64 that cannot
// lower divisions with more than 128 bits or targets like x86_32 that
// cannot lower divisions with more than 64 bits.
//
// Instructions with vector types are scalarized first if their scalar
// types can be expanded. Scalable vector types are not supported.
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/ExpandIRInsts.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/SimplifyQuery.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/IntegerDivision.h"
#include <optional>

#define DEBUG_TYPE "expand-ir-insts"

using namespace llvm;

namespace llvm {
extern cl::opt<bool> ProfcheckDisableMetadataFixes;
}

static cl::opt<unsigned>
    ExpandFpConvertBits("expand-fp-convert-bits", cl::Hidden,
                        cl::init(IntegerType::MAX_INT_BITS),
                        cl::desc("fp convert instructions on integers with "
                                 "more than <N> bits are expanded."));

static cl::opt<unsigned>
    ExpandDivRemBits("expand-div-rem-bits", cl::Hidden,
                     cl::init(IntegerType::MAX_INT_BITS),
                     cl::desc("div and rem instructions on integers with "
                              "more than <N> bits are expanded."));

static bool isConstantPowerOfTwo(Value *V, bool SignedOp) {
  auto *C = dyn_cast<ConstantInt>(V);
  if (!C)
    return false;

  APInt Val = C->getValue();
  if (SignedOp && Val.isNegative())
    Val = -Val;
  return Val.isPowerOf2();
}

static bool isSigned(unsigned Opcode) {
  return Opcode == Instruction::SDiv || Opcode == Instruction::SRem;
}

/// For signed div/rem by a power of 2, compute the bias-adjusted dividend:
///   Sign = ashr X, (BitWidth - 1)          -- 0 or -1
///   Bias = lshr Sign, (BitWidth - ShiftAmt) -- 0 or 2^ShiftAmt - 1
///   Adjusted = add X, Bias
/// The bias adds (2^ShiftAmt - 1) for negative X, correcting rounding towards
/// zero (instead of towards -inf that a plain ashr would give).
/// The lshr form is used instead of 'and' to avoid large immediate constants.
static Value *addSignedBias(IRBuilder<> &Builder, Value *X, unsigned BitWidth,
                            unsigned ShiftAmt) {
  assert(ShiftAmt > 0 && ShiftAmt < BitWidth &&
         "ShiftAmt out of range; callers should handle ShiftAmt == 0");
  Value *Sign = Builder.CreateAShr(X, BitWidth - 1, "sign");
  Value *Bias = Builder.CreateLShr(Sign, BitWidth - ShiftAmt, "bias");
  return Builder.CreateAdd(X, Bias, "adjusted");
}

/// Expand division or remainder by a power-of-2 constant.
/// Division (let C = log2(|divisor|)):
///   udiv X, 2^C  ->  lshr X, C
///   sdiv X, 2^C  ->  ashr (add X, Bias), C  (Bias corrects rounding)
///   sdiv exact X, 2^C  ->  ashr exact X, C  (no bias needed)
///   For negative power-of-2 divisors, the division result is negated.
/// Remainder (let C = log2(|divisor|)):
///   urem X, 2^C  ->  and X, (2^C - 1)
///   srem X, 2^C  ->  sub X, (shl (ashr (add X, Bias), C), C)
static void expandPow2DivRem(BinaryOperator *BO) {
  LLVM_DEBUG(dbgs() << "Expanding instruction: " << *BO << '\n');

  unsigned Opcode = BO->getOpcode();
  bool IsDiv = (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv);
  bool IsSigned = isSigned(Opcode);
  // isExact() is only valid for div.
  bool IsExact = IsDiv && BO->isExact();

  assert(isConstantPowerOfTwo(BO->getOperand(1), IsSigned) &&
         "Expected power-of-2 constant divisor");

  Value *X = BO->getOperand(0);
  auto *C = cast<ConstantInt>(BO->getOperand(1));
  Type *Ty = BO->getType();
  unsigned BitWidth = Ty->getIntegerBitWidth();

  APInt DivisorVal = C->getValue();
  bool IsNegativeDivisor = IsSigned && DivisorVal.isNegative();
  // Use countr_zero() to get the shift amount directly from the bit pattern.
  // This works correctly for both positive and negative powers of 2, including
  // INT_MIN, without needing to negate the value first.
  unsigned ShiftAmt = DivisorVal.countr_zero();

  IRBuilder<> Builder(BO);
  Value *Result;

  if (ShiftAmt == 0) {
    // Div by 1/-1: X / 1 = X, X / -1 = -X.
    // Rem by 1/-1: always 0.
    if (IsDiv)
      Result = IsNegativeDivisor ? Builder.CreateNeg(X) : X;
    else
      Result = ConstantInt::get(Ty, 0);
  } else if (IsSigned) {
    // The signed expansion uses X multiple times (bias computation, shift,
    // and sub for remainder). Freeze X to ensure consistent behavior if it is
    // undef/poison. For exact division, no bias is needed and X is used only
    // once, so freeze is unnecessary.
    if (!IsExact && !isGuaranteedNotToBeUndefOrPoison(X))
      X = Builder.CreateFreeze(X, X->getName() + ".fr");
    // For exact division, no bias is needed since there's no rounding.
    Value *Dividend =
        IsExact ? X : addSignedBias(Builder, X, BitWidth, ShiftAmt);
    Value *Quotient = Builder.CreateAShr(
        Dividend, ShiftAmt, IsDiv && IsNegativeDivisor ? "pre.neg" : "shifted",
        IsExact);
    if (IsDiv) {
      Result = IsNegativeDivisor ? Builder.CreateNeg(Quotient) : Quotient;
    } else {
      // Rem = X - (Quotient << ShiftAmt):
      // clear lower ShiftAmt bits via round-trip shift, then subtract.
      Value *Truncated = Builder.CreateShl(Quotient, ShiftAmt, "truncated");
      Result = Builder.CreateSub(X, Truncated);
    }
  } else {
    if (IsDiv) {
      Result = Builder.CreateLShr(X, ShiftAmt, "", IsExact);
    } else {
      APInt Mask = APInt::getLowBitsSet(BitWidth, ShiftAmt);
      Result = Builder.CreateAnd(X, ConstantInt::get(Ty, Mask));
    }
  }

  BO->replaceAllUsesWith(Result);
  if (Result != X)
    if (auto *RI = dyn_cast<Instruction>(Result))
      RI->takeName(BO);
  BO->dropAllReferences();
  BO->eraseFromParent();
}

/// This class implements a precise expansion of the frem instruction.
/// The generated code is based on the fmod implementation in the AMD device
/// libs.
namespace {
class FRemExpander {
  /// The IRBuilder to use for the expansion.
  IRBuilder<> &B;

  /// Floating point type of the return value and the arguments of the FRem
  /// instructions that should be expanded.
  Type *FremTy;

  /// Floating point type to use for the computation.  This may be
  /// wider than the \p FremTy.
  Type *ComputeFpTy;

  /// Integer type used to hold the exponents returned by frexp.
  Type *ExTy;

  /// How many bits of the quotient to compute per iteration of the
  /// algorithm, stored as a value of type \p ExTy.
  Value *Bits;

  /// Constant 1 of type \p ExTy.
  Value *One;

  /// The frem argument/return types that can be expanded by this class.
  // TODO: The expansion could work for other floating point types
  // as well, but this would require additional testing.
  static constexpr std::array<MVT, 4> ExpandableTypes{MVT::f16, MVT::bf16,
                                                      MVT::f32, MVT::f64};

public:
  static bool canExpandType(Type *Ty) {
    EVT VT = EVT::getEVT(Ty);
    assert(VT.isSimple() && "Can expand only simple types");

    return is_contained(ExpandableTypes, VT.getSimpleVT());
  }

  static bool shouldExpandFremType(const TargetLowering &TLI,
                                   const LibcallLoweringInfo &Libcalls,
                                   EVT VT) {
    assert(!VT.isVector() && "Cannot handle vector type; must scalarize first");
    switch (TLI.getOperationAction(ISD::FREM, VT)) {
    case TargetLowering::LegalizeAction::Expand:
      return true;
    case TargetLowering::LegalizeAction::LibCall:
      // The target expects a libcall, but expand inline for the supported
      // types when that libcall is unavailable.
      return VT.isSimple() && is_contained(ExpandableTypes, VT.getSimpleVT()) &&
             Libcalls.getLibcallImpl(RTLIB::getREM(VT)) == RTLIB::Unsupported;
    default:
      return false;
    }
  }

  static bool shouldExpandFremType(const TargetLowering &TLI,
                                   const LibcallLoweringInfo &Libcalls,
                                   Type *Ty) {
    // Consider scalar type for simplicity.  It seems unlikely that a
    // vector type can be legalized without expansion if the scalar
    // type cannot.
    return shouldExpandFremType(TLI, Libcalls,
                                EVT::getEVT(Ty->getScalarType()));
  }

  /// Return true if the pass should expand frem instructions of any type
  /// for the target represented by \p TLI.
  static bool shouldExpandAnyFremType(const TargetLowering &TLI,
                                      const LibcallLoweringInfo &Libcalls) {
    return any_of(ExpandableTypes, [&](MVT V) {
      return shouldExpandFremType(TLI, Libcalls, EVT(V));
    });
  }

  static FRemExpander create(IRBuilder<> &B, Type *Ty) {
    assert(canExpandType(Ty) && "Expected supported floating point type");

    // The type to use for the computation of the remainder. This may be
    // wider than the input/result type which affects the ...
    Type *ComputeTy = Ty;
    // ... maximum number of iterations of the remainder computation loop
    // to use. This value is for the case in which the computation
    // uses the same input/result type.
    unsigned MaxIter = 2;

    if (Ty->is16bitFPTy()) {
      // Use the wider type and less iterations.
      ComputeTy = B.getFloatTy();
      MaxIter = 1;
    }

    unsigned Precision = APFloat::semanticsPrecision(Ty->getFltSemantics());
    return FRemExpander{B, Ty, Precision / MaxIter, ComputeTy};
  }

  /// Build the FRem expansion for the numerator \p X and the
  /// denumerator \p Y.  The type of X and Y must match \p FremTy. The
  /// code will be generated at the insertion point of \p B and the
  /// insertion point will be reset at exit.
  Value *buildFRem(Value *X, Value *Y, std::optional<SimplifyQuery> &SQ) const;

  /// Build an approximate FRem expansion for the numerator \p X and
  /// the denumerator \p Y at the insertion point of builder \p B.
  /// The type of X and Y must match \p FremTy.
  Value *buildApproxFRem(Value *X, Value *Y) const;

private:
  FRemExpander(IRBuilder<> &B, Type *FremTy, unsigned Bits, Type *ComputeFpTy)
      : B(B), FremTy(FremTy), ComputeFpTy(ComputeFpTy), ExTy(B.getInt32Ty()),
        Bits(ConstantInt::get(ExTy, Bits)), One(ConstantInt::get(ExTy, 1)) {}

  Value *createRcp(Value *V, const Twine &Name) const {
    // Leave it to later optimizations to turn this into an rcp
    // instruction if available.
    return B.CreateFDiv(ConstantFP::get(ComputeFpTy, 1.0), V, Name);
  }

  // Helper function to build the UPDATE_AX code which is common to the
  // loop body and the "final iteration".
  Value *buildUpdateAx(Value *Ax, Value *Ay, Value *Ayinv) const {
    // Build:
    //   float q = rint(ax * ayinv);
    //   ax = fma(-q, ay, ax);
    //   int clt = ax < 0.0f;
    //   float axp = ax + ay;
    //   ax = clt ? axp : ax;
    Value *Q = B.CreateUnaryIntrinsic(Intrinsic::rint, B.CreateFMul(Ax, Ayinv),
                                      {}, "q");
    Value *AxUpdate = B.CreateFMA(B.CreateFNeg(Q), Ay, Ax, {}, "ax");
    Value *Clt = B.CreateFCmp(CmpInst::FCMP_OLT, AxUpdate,
                              ConstantFP::getZero(ComputeFpTy), "clt");
    Value *Axp = B.CreateFAdd(AxUpdate, Ay, "axp");
    return B.CreateSelect(Clt, Axp, AxUpdate, "ax");
  }

  /// Build code to extract the exponent and mantissa of \p Src.
  /// Return the exponent minus one for use as a loop bound and
  /// the mantissa taken to the given \p NewExp power.
  std::pair<Value *, Value *> buildExpAndPower(Value *Src, Value *NewExp,
                                               const Twine &ExName,
                                               const Twine &PowName) const {
    // Build:
    //   ExName = frexp_exp(Src) - 1;
    //   PowName = fldexp(frexp_mant(ExName), NewExp);
    Type *Ty = Src->getType();
    Type *ExTy = B.getInt32Ty();
    Value *Frexp = B.CreateIntrinsic(Intrinsic::frexp, {Ty, ExTy}, Src);
    Value *Mant = B.CreateExtractValue(Frexp, {0});
    Value *Exp = B.CreateExtractValue(Frexp, {1});

    Exp = B.CreateSub(Exp, One, ExName);
    Value *Pow = B.CreateLdexp(Mant, NewExp, {}, PowName);

    return {Pow, Exp};
  }

  /// Build the main computation of the remainder for the case in which
  /// Ax > Ay, where Ax = |X|, Ay = |Y|, and X is the numerator and Y the
  /// denumerator. Add the incoming edge from the computation result
  /// to \p RetPhi.
  void buildRemainderComputation(Value *AxInitial, Value *AyInitial, Value *X,
                                 PHINode *RetPhi, FastMathFlags FMF) const {
    IRBuilder<>::FastMathFlagGuard Guard(B);
    B.setFastMathFlags(FMF);

    // Build:
    // ex = frexp_exp(ax) - 1;
    // ax = fldexp(frexp_mant(ax), bits);
    // ey = frexp_exp(ay) - 1;
    // ay = fledxp(frexp_mant(ay), 1);
    auto [Ax, Ex] = buildExpAndPower(AxInitial, Bits, "ex", "ax");
    auto [Ay, Ey] = buildExpAndPower(AyInitial, One, "ey", "ay");

    // Build:
    //   int nb = ex - ey;
    //   float ayinv = 1.0/ay;
    Value *Nb = B.CreateSub(Ex, Ey, "nb");
    Value *Ayinv = createRcp(Ay, "ayinv");

    // Build: while (nb > bits)
    BasicBlock *PreheaderBB = B.GetInsertBlock();
    Function *Fun = PreheaderBB->getParent();
    auto *LoopBB = BasicBlock::Create(B.getContext(), "frem.loop_body", Fun);
    auto *ExitBB = BasicBlock::Create(B.getContext(), "frem.loop_exit", Fun);

    B.CreateCondBr(B.CreateICmp(CmpInst::ICMP_SGT, Nb, Bits), LoopBB, ExitBB);

    // Build loop body:
    //   UPDATE_AX
    //   ax = fldexp(ax, bits);
    //   nb -= bits;
    // One iteration of the loop is factored out.  The code shared by
    // the loop and this "iteration" is denoted by UPDATE_AX.
    B.SetInsertPoint(LoopBB);
    PHINode *NbIv = B.CreatePHI(Nb->getType(), 2, "nb_iv");
    NbIv->addIncoming(Nb, PreheaderBB);

    auto *AxPhi = B.CreatePHI(ComputeFpTy, 2, "ax_loop_phi");
    AxPhi->addIncoming(Ax, PreheaderBB);

    Value *AxPhiUpdate = buildUpdateAx(AxPhi, Ay, Ayinv);
    AxPhiUpdate = B.CreateLdexp(AxPhiUpdate, Bits, {}, "ax_update");
    AxPhi->addIncoming(AxPhiUpdate, LoopBB);
    NbIv->addIncoming(B.CreateSub(NbIv, Bits, "nb_update"), LoopBB);

    B.CreateCondBr(B.CreateICmp(CmpInst::ICMP_SGT, NbIv, Bits), LoopBB, ExitBB);

    // Build final iteration
    //   ax = fldexp(ax, nb - bits + 1);
    //   UPDATE_AX
    B.SetInsertPoint(ExitBB);

    auto *AxPhiExit = B.CreatePHI(ComputeFpTy, 2, "ax_exit_phi");
    AxPhiExit->addIncoming(Ax, PreheaderBB);
    AxPhiExit->addIncoming(AxPhi, LoopBB);
    auto *NbExitPhi = B.CreatePHI(Nb->getType(), 2, "nb_exit_phi");
    NbExitPhi->addIncoming(NbIv, LoopBB);
    NbExitPhi->addIncoming(Nb, PreheaderBB);

    Value *AxFinal = B.CreateLdexp(
        AxPhiExit, B.CreateAdd(B.CreateSub(NbExitPhi, Bits), One), {}, "ax");
    AxFinal = buildUpdateAx(AxFinal, Ay, Ayinv);

    // Build:
    //    ax = fldexp(ax, ey);
    //    ret = copysign(ax,x);
    AxFinal = B.CreateLdexp(AxFinal, Ey, {}, "ax");
    if (ComputeFpTy != FremTy)
      AxFinal = B.CreateFPTrunc(AxFinal, FremTy);
    Value *Ret = B.CreateCopySign(AxFinal, X);

    RetPhi->addIncoming(Ret, ExitBB);
  }

  /// Build the else-branch of the conditional in the FRem
  /// expansion, i.e. the case in wich Ax <= Ay, where Ax = |X|, Ay
  /// = |Y|, and X is the numerator and Y the denumerator. Add the
  /// incoming edge from the result to \p RetPhi.
  void buildElseBranch(Value *Ax, Value *Ay, Value *X, PHINode *RetPhi) const {
    // Build:
    // ret = ax == ay ? copysign(0.0f, x) : x;
    Value *ZeroWithXSign = B.CreateCopySign(ConstantFP::getZero(FremTy), X);
    Value *Ret = B.CreateSelect(B.CreateFCmpOEQ(Ax, Ay), ZeroWithXSign, X);

    RetPhi->addIncoming(Ret, B.GetInsertBlock());
  }

  /// Return a value that is NaN if one of the corner cases concerning
  /// the inputs \p X and \p Y is detected, and \p Ret otherwise.
  Value *handleInputCornerCases(Value *Ret, Value *X, Value *Y,
                                std::optional<SimplifyQuery> &SQ,
                                bool NoInfs) const {
    // Build:
    //   ret = (y == 0.0f || isnan(y)) ? QNAN : ret;
    //   ret = isfinite(x) ? ret : QNAN;
    Value *Nan = ConstantFP::getQNaN(FremTy);
    Ret = B.CreateSelect(B.CreateFCmpUEQ(Y, ConstantFP::getZero(FremTy)), Nan,
                         Ret);
    Value *XFinite =
        NoInfs || (SQ && isKnownNeverInfinity(X, *SQ))
            ? B.getTrue()
            : B.CreateFCmpULT(B.CreateFAbs(X), ConstantFP::getInfinity(FremTy));
    Ret = B.CreateSelect(XFinite, Ret, Nan);

    return Ret;
  }
};
} // namespace

Value *FRemExpander::buildApproxFRem(Value *X, Value *Y) const {
  IRBuilder<>::FastMathFlagGuard Guard(B);
  // Propagating the approximate functions flag to the
  // division leads to an unacceptable drop in precision
  // on AMDGPU.
  // TODO Find out if any flags might be worth propagating.
  B.clearFastMathFlags();

  Value *Quot = B.CreateFDiv(X, Y);
  Value *Trunc = B.CreateUnaryIntrinsic(Intrinsic::trunc, Quot, {});
  Value *Neg = B.CreateFNeg(Trunc);

  return B.CreateFMA(Neg, Y, X);
}

Value *FRemExpander::buildFRem(Value *X, Value *Y,
                               std::optional<SimplifyQuery> &SQ) const {
  assert(X->getType() == FremTy && Y->getType() == FremTy);

  FastMathFlags FMF = B.getFastMathFlags();

  // This function generates the following code structure:
  //   if (abs(x) > abs(y))
  //   { ret = compute remainder }
  //   else
  //   { ret = x or 0 with sign of x }
  //   Adjust ret to NaN/inf in input
  //   return ret
  Value *Ax = B.CreateFAbs(X, {}, "ax");
  Value *Ay = B.CreateFAbs(Y, {}, "ay");
  if (ComputeFpTy != X->getType()) {
    Ax = B.CreateFPExt(Ax, ComputeFpTy, "ax");
    Ay = B.CreateFPExt(Ay, ComputeFpTy, "ay");
  }
  Value *AxAyCmp = B.CreateFCmpOGT(Ax, Ay);

  PHINode *RetPhi = B.CreatePHI(FremTy, 2, "ret");
  Value *Ret = RetPhi;

  // We would return NaN in all corner cases handled here.
  // Hence, if NaNs are excluded, keep the result as it is.
  if (!FMF.noNaNs())
    Ret = handleInputCornerCases(Ret, X, Y, SQ, FMF.noInfs());

  Function *Fun = B.GetInsertBlock()->getParent();
  auto *ThenBB = BasicBlock::Create(B.getContext(), "frem.compute", Fun);
  auto *ElseBB = BasicBlock::Create(B.getContext(), "frem.else", Fun);
  SplitBlockAndInsertIfThenElse(AxAyCmp, RetPhi, &ThenBB, &ElseBB);

  auto SavedInsertPt = B.GetInsertPoint();

  // Build remainder computation for "then" branch
  //
  // The ordered comparison ensures that ax and ay are not NaNs
  // in the then-branch. Furthermore, y cannot be an infinity and the
  // check at the end of the function ensures that the result will not
  // be used if x is an infinity.
  FastMathFlags ComputeFMF = FMF;
  ComputeFMF.setNoInfs();
  ComputeFMF.setNoNaNs();

  B.SetInsertPoint(ThenBB);
  buildRemainderComputation(Ax, Ay, X, RetPhi, FMF);
  B.CreateBr(RetPhi->getParent());

  // Build "else"-branch
  B.SetInsertPoint(ElseBB);
  buildElseBranch(Ax, Ay, X, RetPhi);
  B.CreateBr(RetPhi->getParent());

  B.SetInsertPoint(SavedInsertPt);

  return Ret;
}

static bool expandFRem(BinaryOperator &I, std::optional<SimplifyQuery> &SQ) {
  LLVM_DEBUG(dbgs() << "Expanding instruction: " << I << '\n');

  Type *Ty = I.getType();
  assert(FRemExpander::canExpandType(Ty) &&
         "Expected supported floating point type");

  FastMathFlags FMF = I.getFastMathFlags();
  // TODO Make use of those flags for optimization?
  FMF.setAllowReciprocal(false);
  FMF.setAllowContract(false);

  IRBuilder<> B(&I);
  B.setFastMathFlags(FMF);
  B.SetCurrentDebugLocation(I.getDebugLoc());

  const FRemExpander Expander = FRemExpander::create(B, Ty);
  Value *Ret = FMF.approxFunc()
                   ? Expander.buildApproxFRem(I.getOperand(0), I.getOperand(1))
                   : Expander.buildFRem(I.getOperand(0), I.getOperand(1), SQ);

  I.replaceAllUsesWith(Ret);
  Ret->takeName(&I);
  I.eraseFromParent();

  return true;
}
// clang-format off: preserve formatting of the following example

/// Generate code to convert a fp number to integer, replacing FPToS(U)I with
/// the generated code. This currently generates code similarly to compiler-rt's
/// implementations.
///
/// An example IR generated from compiler-rt/fixsfdi.c looks like below:
/// define dso_local i64 @foo(float noundef %a) local_unnamed_addr #0 {
/// entry:
///   %0 = bitcast float %a to i32
///   %conv.i = zext i32 %0 to i64
///   %tobool.not = icmp sgt i32 %0, -1
///   %conv = select i1 %tobool.not, i64 1, i64 -1
///   %and = lshr i64 %conv.i, 23
///   %shr = and i64 %and, 255
///   %and2 = and i64 %conv.i, 8388607
///   %or = or i64 %and2, 8388608
///   %cmp = icmp ult i64 %shr, 127
///   br i1 %cmp, label %cleanup, label %if.end
///
/// if.end:                                           ; preds = %entry
///   %sub = add nuw nsw i64 %shr, 4294967169
///   %conv5 = and i64 %sub, 4294967232
///   %cmp6.not = icmp eq i64 %conv5, 0
///   br i1 %cmp6.not, label %if.end12, label %if.then8
///
/// if.then8:                                         ; preds = %if.end
///   %cond11 = select i1 %tobool.not, i64 9223372036854775807, i64
///   -9223372036854775808 br label %cleanup
///
/// if.end12:                                         ; preds = %if.end
///   %cmp13 = icmp ult i64 %shr, 150
///   br i1 %cmp13, label %if.then15, label %if.else
///
/// if.then15:                                        ; preds = %if.end12
///   %sub16 = sub nuw nsw i64 150, %shr
///   %shr17 = lshr i64 %or, %sub16
///   %mul = mul nsw i64 %shr17, %conv
///   br label %cleanup
///
/// if.else:                                          ; preds = %if.end12
///   %sub18 = add nsw i64 %shr, -150
///   %shl = shl i64 %or, %sub18
///   %mul19 = mul nsw i64 %shl, %conv
///   br label %cleanup
///
/// cleanup:                                          ; preds = %entry,
/// %if.else, %if.then15, %if.then8
///   %retval.0 = phi i64 [ %cond11, %if.then8 ], [ %mul, %if.then15 ], [
///   %mul19, %if.else ], [ 0, %entry ] ret i64 %retval.0
/// }
///
/// Replace fp to integer with generated code.
static void expandFPToI(Instruction *FPToI, bool IsSaturating, bool IsSigned) {
  // clang-format on
  IRBuilder<> Builder(FPToI);
  auto *FloatVal = FPToI->getOperand(0);
  IntegerType *IntTy = cast<IntegerType>(FPToI->getType());

  unsigned BitWidth = FPToI->getType()->getIntegerBitWidth();
  unsigned FPMantissaWidth = FloatVal->getType()->getFPMantissaWidth() - 1;

  // FIXME: fp16's range is covered by i32. So `fptoi half` can convert
  // to i32 first following a sext/zext to target integer type.
  Value *A1 = nullptr;
  if (FloatVal->getType()->isHalfTy() && BitWidth >= 32) {
    if (FPToI->getOpcode() == Instruction::FPToUI) {
      Value *A0 = Builder.CreateFPToUI(FloatVal, Builder.getInt32Ty());
      A1 = Builder.CreateZExt(A0, IntTy);
    } else { // FPToSI
      Value *A0 = Builder.CreateFPToSI(FloatVal, Builder.getInt32Ty());
      A1 = Builder.CreateSExt(A0, IntTy);
    }
    FPToI->replaceAllUsesWith(A1);
    FPToI->dropAllReferences();
    FPToI->eraseFromParent();
    return;
  }

  // fp80 conversion is implemented by fpext to fp128 first then do the
  // conversion.
  FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
  unsigned FloatWidth =
      PowerOf2Ceil(FloatVal->getType()->getScalarSizeInBits());
  unsigned ExponentWidth = FloatWidth - FPMantissaWidth - 1;
  unsigned ExponentBias = (1 << (ExponentWidth - 1)) - 1;
  IntegerType *FloatIntTy = Builder.getIntNTy(FloatWidth);
  Value *ImplicitBit = ConstantInt::get(
      FloatIntTy, APInt::getOneBitSet(FloatWidth, FPMantissaWidth));
  Value *SignificandMask = ConstantInt::get(
      FloatIntTy, APInt::getLowBitsSet(FloatWidth, FPMantissaWidth));

  BasicBlock *Entry = Builder.GetInsertBlock();
  Function *F = Entry->getParent();
  Entry->setName(Twine(Entry->getName(), "fp-to-i-entry"));
  BasicBlock *CheckSaturateBB, *SaturateBB;
  BasicBlock *End =
      Entry->splitBasicBlock(Builder.GetInsertPoint(), "fp-to-i-cleanup");
  if (IsSaturating) {
    CheckSaturateBB = BasicBlock::Create(Builder.getContext(),
                                         "fp-to-i-if-check.saturate", F, End);
    SaturateBB =
        BasicBlock::Create(Builder.getContext(), "fp-to-i-if-saturate", F, End);
  }
  BasicBlock *CheckExpSizeBB = BasicBlock::Create(
      Builder.getContext(), "fp-to-i-if-check.exp.size", F, End);
  BasicBlock *ExpSmallBB =
      BasicBlock::Create(Builder.getContext(), "fp-to-i-if-exp.small", F, End);
  BasicBlock *ExpLargeBB =
      BasicBlock::Create(Builder.getContext(), "fp-to-i-if-exp.large", F, End);

  Entry->getTerminator()->eraseFromParent();

  // entry:
  Builder.SetInsertPoint(Entry);
  // We're going to introduce branches on the value, so freeze it.
  if (!isGuaranteedNotToBeUndefOrPoison(FloatVal))
    FloatVal = Builder.CreateFreeze(FloatVal);
  // fp80 conversion is implemented by fpext to fp128 first then do the
  // conversion.
  if (FloatVal->getType()->isX86_FP80Ty())
    FloatVal =
        Builder.CreateFPExt(FloatVal, Type::getFP128Ty(Builder.getContext()));
  Value *ARep = Builder.CreateBitCast(FloatVal, FloatIntTy);
  Value *PosOrNeg, *Sign;
  if (IsSigned) {
    PosOrNeg =
        Builder.CreateICmpSGT(ARep, ConstantInt::getSigned(FloatIntTy, -1));
    Sign = Builder.CreateSelectWithUnknownProfile(
        PosOrNeg, ConstantInt::getSigned(IntTy, 1),
        ConstantInt::getSigned(IntTy, -1), "sign");
  }
  Value *And =
      Builder.CreateLShr(ARep, Builder.getIntN(FloatWidth, FPMantissaWidth));
  Value *BiasedExp = Builder.CreateAnd(
      And, Builder.getIntN(FloatWidth, (1 << ExponentWidth) - 1), "biased.exp");
  Value *Abs = Builder.CreateAnd(ARep, SignificandMask);
  Value *Significand = Builder.CreateOr(Abs, ImplicitBit, "significand");
  Value *ZeroResultCond = Builder.CreateICmpULT(
      BiasedExp, Builder.getIntN(FloatWidth, ExponentBias), "exp.is.negative");
  if (IsSaturating) {
    Value *IsNaN = Builder.CreateFCmpUNO(FloatVal, FloatVal, "is.nan");
    ZeroResultCond = Builder.CreateOr(ZeroResultCond, IsNaN);
    if (!IsSigned) {
      Value *IsNeg = Builder.CreateIsNeg(ARep);
      ZeroResultCond = Builder.CreateOr(ZeroResultCond, IsNeg);
    }
  }
  Instruction *CondBr = Builder.CreateCondBr(
      ZeroResultCond, End, IsSaturating ? CheckSaturateBB : CheckExpSizeBB);
  // We do not have any information on the value of the exponent, so mark the
  // branch weights as unkown.
  setExplicitlyUnknownBranchWeightsIfProfiled(*CondBr, DEBUG_TYPE, F);

  Value *Saturated;
  if (IsSaturating) {
    // check.saturate:
    Builder.SetInsertPoint(CheckSaturateBB);
    uint64_t SaturatingBiasedExp =
        static_cast<uint64_t>(ExponentBias) + BitWidth - IsSigned;
    // Clamp to the all-ones (inf/NaN) exponent. Without this, when the integer
    // is wide enough to hold every finite float the threshold exceeds any
    // possible biased exponent, so +/-inf would never saturate.
    uint64_t MaxBiasedExp = (1ULL << ExponentWidth) - 1;
    if (SaturatingBiasedExp > MaxBiasedExp)
      SaturatingBiasedExp = MaxBiasedExp;
    Value *Cmp3 = Builder.CreateICmpUGE(
        BiasedExp, ConstantInt::get(FloatIntTy, SaturatingBiasedExp));
    Value *CondBrSat = Builder.CreateCondBr(Cmp3, SaturateBB, CheckExpSizeBB);
    // Saturation is considered an unlikely event.
    applyProfMetadataIfEnabled(CondBrSat, [&](Instruction *Inst) {
      Inst->setMetadata(
          LLVMContext::MD_prof,
          MDBuilder(Inst->getContext()).createUnlikelyBranchWeights());
    });

    // saturate:
    Builder.SetInsertPoint(SaturateBB);
    if (IsSigned) {
      Value *SignedMax =
          ConstantInt::get(IntTy, APInt::getSignedMaxValue(BitWidth));
      Value *SignedMin =
          ConstantInt::get(IntTy, APInt::getSignedMinValue(BitWidth));
      // Select between the signed max and min values for saturation.
      Saturated = Builder.CreateSelectWithUnknownProfile(
          PosOrNeg, SignedMax, SignedMin, "saturated");
    } else {
      Saturated = ConstantInt::getAllOnesValue(IntTy);
    }
    Builder.CreateBr(End);
  }

  // if.end9:
  Builder.SetInsertPoint(CheckExpSizeBB);
  Value *ExpSmallerMantissaWidth = Builder.CreateICmpULT(
      BiasedExp, Builder.getIntN(FloatWidth, ExponentBias + FPMantissaWidth),
      "exp.smaller.mantissa.width");
  // We cannot determine whether this is a left shift or a right shift,
  // so we mark the branch weights as unknown.
  Value *CondBr2 =
      Builder.CreateCondBr(ExpSmallerMantissaWidth, ExpSmallBB, ExpLargeBB);
  applyProfMetadataIfEnabled(CondBr2, [&](Instruction *Inst) {
    setExplicitlyUnknownBranchWeightsIfProfiled(*Inst, DEBUG_TYPE, F);
  });

  // exp.small:
  Builder.SetInsertPoint(ExpSmallBB);
  Value *Sub13 = Builder.CreateSub(
      Builder.getIntN(FloatWidth, ExponentBias + FPMantissaWidth), BiasedExp);
  Value *ExpSmallRes =
      Builder.CreateZExtOrTrunc(Builder.CreateLShr(Significand, Sub13), IntTy);
  if (IsSigned)
    ExpSmallRes = Builder.CreateMul(ExpSmallRes, Sign);
  Builder.CreateBr(End);

  // exp.large:
  Builder.SetInsertPoint(ExpLargeBB);
  Value *Sub15 = Builder.CreateAdd(
      BiasedExp,
      ConstantInt::getSigned(
          FloatIntTy, -static_cast<int64_t>(ExponentBias + FPMantissaWidth)));
  Value *SignificandCast = Builder.CreateZExtOrTrunc(Significand, IntTy);
  Value *ExpLargeRes = Builder.CreateShl(
      SignificandCast, Builder.CreateZExtOrTrunc(Sub15, IntTy));
  if (IsSigned)
    ExpLargeRes = Builder.CreateMul(ExpLargeRes, Sign);
  Builder.CreateBr(End);

  // cleanup:
  Builder.SetInsertPoint(End->begin());
  PHINode *Retval0 = Builder.CreatePHI(FPToI->getType(), 3 + IsSaturating);

  if (IsSaturating)
    Retval0->addIncoming(Saturated, SaturateBB);
  Retval0->addIncoming(ExpSmallRes, ExpSmallBB);
  Retval0->addIncoming(ExpLargeRes, ExpLargeBB);
  Retval0->addIncoming(Builder.getIntN(BitWidth, 0), Entry);

  FPToI->replaceAllUsesWith(Retval0);
  FPToI->dropAllReferences();
  FPToI->eraseFromParent();
}

// clang-format off: preserve formatting of the following example

/// Generate code to convert a fp number to integer, replacing S(U)IToFP with
/// the generated code. This currently generates code similarly to compiler-rt's
/// implementations. This implementation has an implicit assumption that integer
/// width is larger than fp.
///
/// An example IR generated from compiler-rt/floatdisf.c looks like below:
/// define dso_local float @__floatdisf(i64 noundef %a) local_unnamed_addr #0 {
/// entry:
///   %cmp = icmp eq i64 %a, 0
///   br i1 %cmp, label %return, label %if.end
///
/// if.end:                                           ; preds = %entry
///   %shr = ashr i64 %a, 63
///   %xor = xor i64 %shr, %a
///   %sub = sub nsw i64 %xor, %shr
///   %0 = tail call i64 @llvm.ctlz.i64(i64 %sub, i1 true), !range !5
///   %cast = trunc i64 %0 to i32
///   %sub1 = sub nuw nsw i32 64, %cast
///   %sub2 = xor i32 %cast, 63
///   %cmp3 = icmp ult i32 %cast, 40
///   br i1 %cmp3, label %if.then4, label %if.else
///
/// if.then4:                                         ; preds = %if.end
///   switch i32 %sub1, label %sw.default [
///     i32 25, label %sw.bb
///     i32 26, label %sw.epilog
///   ]
///
/// sw.bb:                                            ; preds = %if.then4
///   %shl = shl i64 %sub, 1
///   br label %sw.epilog
///
/// sw.default:                                       ; preds = %if.then4
///   %sub5 = sub nsw i64 38, %0
///   %sh_prom = and i64 %sub5, 4294967295
///   %shr6 = lshr i64 %sub, %sh_prom
///   %shr9 = lshr i64 274877906943, %0
///   %and = and i64 %shr9, %sub
///   %cmp10 = icmp ne i64 %and, 0
///   %conv11 = zext i1 %cmp10 to i64
///   %or = or i64 %shr6, %conv11
///   br label %sw.epilog
///
/// sw.epilog:                                        ; preds = %sw.default,
/// %if.then4, %sw.bb
///   %a.addr.0 = phi i64 [ %or, %sw.default ], [ %sub, %if.then4 ], [ %shl,
///   %sw.bb ] %1 = lshr i64 %a.addr.0, 2 %2 = and i64 %1, 1 %or16 = or i64 %2,
///   %a.addr.0 %inc = add nsw i64 %or16, 1 %3 = and i64 %inc, 67108864
///   %tobool.not = icmp eq i64 %3, 0
///   %spec.select.v = select i1 %tobool.not, i64 2, i64 3
///   %spec.select = ashr i64 %inc, %spec.select.v
///   %spec.select56 = select i1 %tobool.not, i32 %sub2, i32 %sub1
///   br label %if.end26
///
/// if.else:                                          ; preds = %if.end
///   %sub23 = add nuw nsw i64 %0, 4294967256
///   %sh_prom24 = and i64 %sub23, 4294967295
///   %shl25 = shl i64 %sub, %sh_prom24
///   br label %if.end26
///
/// if.end26:                                         ; preds = %sw.epilog,
/// %if.else
///   %a.addr.1 = phi i64 [ %shl25, %if.else ], [ %spec.select, %sw.epilog ]
///   %e.0 = phi i32 [ %sub2, %if.else ], [ %spec.select56, %sw.epilog ]
///   %conv27 = trunc i64 %shr to i32
///   %and28 = and i32 %conv27, -2147483648
///   %add = shl nuw nsw i32 %e.0, 23
///   %shl29 = add nuw nsw i32 %add, 1065353216
///   %conv31 = trunc i64 %a.addr.1 to i32
///   %and32 = and i32 %conv31, 8388607
///   %or30 = or i32 %and32, %and28
///   %or33 = or i32 %or30, %shl29
///   %4 = bitcast i32 %or33 to float
///   br label %return
///
/// return:                                           ; preds = %entry,
/// %if.end26
///   %retval.0 = phi float [ %4, %if.end26 ], [ 0.000000e+00, %entry ]
///   ret float %retval.0
/// }
///
/// Replace integer to fp with generated code.
static void expandIToFP(Instruction *IToFP) {
  // clang-format on
  IRBuilder<> Builder(IToFP);
  auto *IntVal = IToFP->getOperand(0);
  IntegerType *IntTy = cast<IntegerType>(IntVal->getType());

  unsigned BitWidth = IntVal->getType()->getIntegerBitWidth();
  unsigned FPMantissaWidth = IToFP->getType()->getFPMantissaWidth() - 1;
  // fp80 conversion is implemented by conversion tp fp128 first following
  // a fptrunc to fp80.
  FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
  // FIXME: As there is no related builtins added in compliler-rt,
  // here currently utilized the fp32 <-> fp16 lib calls to implement.
  FPMantissaWidth = FPMantissaWidth == 10 ? 23 : FPMantissaWidth;
  FPMantissaWidth = FPMantissaWidth == 7 ? 23 : FPMantissaWidth;
  unsigned FloatWidth = PowerOf2Ceil(FPMantissaWidth);
  bool IsSigned = IToFP->getOpcode() == Instruction::SIToFP;

  // We're going to introduce branches on the value, so freeze it.
  if (!isGuaranteedNotToBeUndefOrPoison(IntVal))
    IntVal = Builder.CreateFreeze(IntVal);

  // The expansion below assumes that int width >= float width. Zero or sign
  // extend the integer accordingly.
  if (BitWidth < FloatWidth) {
    BitWidth = FloatWidth;
    IntTy = Builder.getIntNTy(BitWidth);
    IntVal = Builder.CreateIntCast(IntVal, IntTy, IsSigned);
  }

  Value *Temp1 =
      Builder.CreateShl(Builder.getIntN(BitWidth, 1),
                        Builder.getIntN(BitWidth, FPMantissaWidth + 3));

  BasicBlock *Entry = Builder.GetInsertBlock();
  Function *F = Entry->getParent();
  Entry->setName(Twine(Entry->getName(), "itofp-entry"));
  BasicBlock *End =
      Entry->splitBasicBlock(Builder.GetInsertPoint(), "itofp-return");
  BasicBlock *IfEnd =
      BasicBlock::Create(Builder.getContext(), "itofp-if-end", F, End);
  BasicBlock *IfThen4 =
      BasicBlock::Create(Builder.getContext(), "itofp-if-then4", F, End);
  BasicBlock *SwBB =
      BasicBlock::Create(Builder.getContext(), "itofp-sw-bb", F, End);
  BasicBlock *SwDefault =
      BasicBlock::Create(Builder.getContext(), "itofp-sw-default", F, End);
  BasicBlock *SwEpilog =
      BasicBlock::Create(Builder.getContext(), "itofp-sw-epilog", F, End);
  BasicBlock *IfThen20 =
      BasicBlock::Create(Builder.getContext(), "itofp-if-then20", F, End);
  BasicBlock *IfElse =
      BasicBlock::Create(Builder.getContext(), "itofp-if-else", F, End);
  BasicBlock *IfEnd26 =
      BasicBlock::Create(Builder.getContext(), "itofp-if-end26", F, End);

  Entry->getTerminator()->eraseFromParent();

  Function *CTLZ =
      Intrinsic::getOrInsertDeclaration(F->getParent(), Intrinsic::ctlz, IntTy);
  ConstantInt *True = Builder.getTrue();

  // entry:
  Builder.SetInsertPoint(Entry);
  // We assume that the zero is an unlikely input case, so the branch to 'End'
  // is the unlikely path.
  Value *Cmp = Builder.CreateICmpEQ(IntVal, ConstantInt::getSigned(IntTy, 0));
  Value *CondBrEntry = Builder.CreateCondBr(Cmp, End, IfEnd);
  applyProfMetadataIfEnabled(CondBrEntry, [&](Instruction *Inst) {
    Inst->setMetadata(
        LLVMContext::MD_prof,
        MDBuilder(Inst->getContext()).createUnlikelyBranchWeights());
  });

  // if.end:
  Builder.SetInsertPoint(IfEnd);
  Value *Shr =
      Builder.CreateAShr(IntVal, Builder.getIntN(BitWidth, BitWidth - 1));
  Value *Xor = Builder.CreateXor(Shr, IntVal);
  Value *Sub = Builder.CreateSub(Xor, Shr);
  Value *Call = Builder.CreateCall(CTLZ, {IsSigned ? Sub : IntVal, True});
  Value *Cast = Builder.CreateTrunc(Call, Builder.getInt32Ty());
  int BitWidthNew = FloatWidth == 128 ? BitWidth : 32;
  Value *Sub1 = Builder.CreateSub(Builder.getIntN(BitWidthNew, BitWidth),
                                  FloatWidth == 128 ? Call : Cast);
  Value *Sub2 = Builder.CreateSub(Builder.getIntN(BitWidthNew, BitWidth - 1),
                                  FloatWidth == 128 ? Call : Cast);
  Value *Cmp3 = Builder.CreateICmpSGT(
      Sub1, Builder.getIntN(BitWidthNew, FPMantissaWidth + 1));
  // This branch handles the rare case where rounding the mantissa causes a
  // carry-out at the most significant bit, necessitating an increment of the
  // exponent. This is rare case, so the True path is mared as likely.
  Value *CondBrIfEnd = Builder.CreateCondBr(Cmp3, IfThen4, IfElse);
  applyProfMetadataIfEnabled(CondBrIfEnd, [&](Instruction *Inst) {
    Inst->setMetadata(
        LLVMContext::MD_prof,
        MDBuilder(Inst->getContext()).createLikelyBranchWeights());
  });

  // if.then4:
  Builder.SetInsertPoint(IfThen4);
  SwitchInst *SI = Builder.CreateSwitch(Sub1, SwDefault);
  SI->addCase(Builder.getIntN(BitWidthNew, FPMantissaWidth + 2), SwBB);
  SI->addCase(Builder.getIntN(BitWidthNew, FPMantissaWidth + 3), SwEpilog);
  // Add branch weights to the SwitchInst. The weights are provided for the
  // default case first (SwDefault), followed by each explicit case in the
  // order they were added (SwBB, then SwEpilog). Because the following cases
  // are rare, the defalut case is given a likely weight.
  if (!ProfcheckDisableMetadataFixes) {
    SI->setMetadata(
        LLVMContext::MD_prof,
        MDBuilder(SI->getContext())
            .createBranchWeights({llvm::MDBuilder::kLikelyBranchWeight,
                                  llvm::MDBuilder::kUnlikelyBranchWeight,
                                  llvm::MDBuilder::kUnlikelyBranchWeight}));
  }

  // sw.bb:
  Builder.SetInsertPoint(SwBB);
  Value *Shl =
      Builder.CreateShl(IsSigned ? Sub : IntVal, Builder.getIntN(BitWidth, 1));
  Builder.CreateBr(SwEpilog);

  // sw.default:
  Builder.SetInsertPoint(SwDefault);
  Value *Sub5 = Builder.CreateSub(
      Builder.getIntN(BitWidthNew, BitWidth - FPMantissaWidth - 3),
      FloatWidth == 128 ? Call : Cast);
  Value *ShProm = Builder.CreateZExt(Sub5, IntTy);
  Value *Shr6 = Builder.CreateLShr(IsSigned ? Sub : IntVal,
                                   FloatWidth == 128 ? Sub5 : ShProm);
  Value *Sub8 =
      Builder.CreateAdd(FloatWidth == 128 ? Call : Cast,
                        Builder.getIntN(BitWidthNew, FPMantissaWidth + 3));
  Value *ShProm9 = Builder.CreateZExt(Sub8, IntTy);
  Value *Shr9 = Builder.CreateLShr(ConstantInt::getSigned(IntTy, -1),
                                   FloatWidth == 128 ? Sub8 : ShProm9);
  Value *And = Builder.CreateAnd(Shr9, IsSigned ? Sub : IntVal);
  Value *Cmp10 = Builder.CreateICmpNE(And, Builder.getIntN(BitWidth, 0));
  Value *Conv11 = Builder.CreateZExt(Cmp10, IntTy);
  Value *Or = Builder.CreateOr(Shr6, Conv11);
  Builder.CreateBr(SwEpilog);

  // sw.epilog:
  Builder.SetInsertPoint(SwEpilog);
  PHINode *AAddr0 = Builder.CreatePHI(IntTy, 3);
  AAddr0->addIncoming(Or, SwDefault);
  AAddr0->addIncoming(IsSigned ? Sub : IntVal, IfThen4);
  AAddr0->addIncoming(Shl, SwBB);
  Value *A0 = Builder.CreateTrunc(AAddr0, Builder.getInt32Ty());
  Value *A1 = Builder.CreateLShr(A0, Builder.getInt32(2));
  Value *A2 = Builder.CreateAnd(A1, Builder.getInt32(1));
  Value *Conv16 = Builder.CreateZExt(A2, IntTy);
  Value *Or17 = Builder.CreateOr(AAddr0, Conv16);
  Value *Inc = Builder.CreateAdd(Or17, Builder.getIntN(BitWidth, 1));
  Value *Shr18 = nullptr;
  if (IsSigned)
    Shr18 = Builder.CreateAShr(Inc, Builder.getIntN(BitWidth, 2));
  else
    Shr18 = Builder.CreateLShr(Inc, Builder.getIntN(BitWidth, 2));
  Value *A3 = Builder.CreateAnd(Inc, Temp1, "a3");
  Value *PosOrNeg = Builder.CreateICmpEQ(A3, Builder.getIntN(BitWidth, 0));
  Value *ExtractT60 = Builder.CreateTrunc(Shr18, Builder.getIntNTy(FloatWidth));
  Value *Extract63 = Builder.CreateLShr(Shr18, Builder.getIntN(BitWidth, 32));
  Value *ExtractT64 = nullptr;
  if (FloatWidth > 80)
    ExtractT64 = Builder.CreateTrunc(Sub2, Builder.getInt64Ty());
  else
    ExtractT64 = Builder.CreateTrunc(Extract63, Builder.getInt32Ty());
  // Rounding usually keeps the exponent within its current magnitude and
  // overflow is rare. The False path is unlikely to be taken.
  Value *CondBrSwEpilog = Builder.CreateCondBr(PosOrNeg, IfEnd26, IfThen20);
  applyProfMetadataIfEnabled(CondBrSwEpilog, [&](Instruction *Inst) {
    Inst->setMetadata(
        LLVMContext::MD_prof,
        MDBuilder(Inst->getContext()).createLikelyBranchWeights());
  });

  // if.then20
  Builder.SetInsertPoint(IfThen20);
  Value *Shr21 = nullptr;
  if (IsSigned)
    Shr21 = Builder.CreateAShr(Inc, Builder.getIntN(BitWidth, 3));
  else
    Shr21 = Builder.CreateLShr(Inc, Builder.getIntN(BitWidth, 3));
  Value *ExtractT = Builder.CreateTrunc(Shr21, Builder.getIntNTy(FloatWidth));
  Value *Extract = Builder.CreateLShr(Shr21, Builder.getIntN(BitWidth, 32));
  Value *ExtractT62 = nullptr;
  if (FloatWidth > 80)
    ExtractT62 = Builder.CreateTrunc(Sub1, Builder.getInt64Ty());
  else
    ExtractT62 = Builder.CreateTrunc(Extract, Builder.getInt32Ty());
  Builder.CreateBr(IfEnd26);

  // if.else:
  Builder.SetInsertPoint(IfElse);
  Value *Sub24 = Builder.CreateAdd(
      FloatWidth == 128 ? Call : Cast,
      ConstantInt::getSigned(Builder.getIntNTy(BitWidthNew),
                             -(int)(BitWidth - FPMantissaWidth - 1)));
  Value *ShProm25 = Builder.CreateZExt(Sub24, IntTy);
  Value *Shl26 = Builder.CreateShl(IsSigned ? Sub : IntVal,
                                   FloatWidth == 128 ? Sub24 : ShProm25);
  Value *ExtractT61 = Builder.CreateTrunc(Shl26, Builder.getIntNTy(FloatWidth));
  Value *Extract65 = Builder.CreateLShr(Shl26, Builder.getIntN(BitWidth, 32));
  Value *ExtractT66 = nullptr;
  if (FloatWidth > 80)
    ExtractT66 = Builder.CreateTrunc(Sub2, Builder.getInt64Ty());
  else
    ExtractT66 = Builder.CreateTrunc(Extract65, Builder.getInt32Ty());
  Builder.CreateBr(IfEnd26);

  // if.end26:
  Builder.SetInsertPoint(IfEnd26);
  PHINode *AAddr1Off0 = Builder.CreatePHI(Builder.getIntNTy(FloatWidth), 3);
  AAddr1Off0->addIncoming(ExtractT, IfThen20);
  AAddr1Off0->addIncoming(ExtractT60, SwEpilog);
  AAddr1Off0->addIncoming(ExtractT61, IfElse);
  PHINode *AAddr1Off32 = nullptr;
  if (FloatWidth > 32) {
    AAddr1Off32 =
        Builder.CreatePHI(Builder.getIntNTy(FloatWidth > 80 ? 64 : 32), 3);
    AAddr1Off32->addIncoming(ExtractT62, IfThen20);
    AAddr1Off32->addIncoming(ExtractT64, SwEpilog);
    AAddr1Off32->addIncoming(ExtractT66, IfElse);
  }
  PHINode *E0 = nullptr;
  if (FloatWidth <= 80) {
    E0 = Builder.CreatePHI(Builder.getIntNTy(BitWidthNew), 3);
    E0->addIncoming(Sub1, IfThen20);
    E0->addIncoming(Sub2, SwEpilog);
    E0->addIncoming(Sub2, IfElse);
  }
  Value *And29 = nullptr;
  if (FloatWidth > 80) {
    Value *Temp2 = Builder.CreateShl(Builder.getIntN(BitWidth, 1),
                                     Builder.getIntN(BitWidth, 63));
    And29 = Builder.CreateAnd(Shr, Temp2, "and29");
  } else {
    Value *Conv28 = Builder.CreateTrunc(Shr, Builder.getInt32Ty());
    And29 = Builder.CreateAnd(
        Conv28, ConstantInt::get(Builder.getContext(), APInt::getSignMask(32)));
  }
  unsigned TempMod = FPMantissaWidth % 32;
  Value *And34 = nullptr;
  Value *Shl30 = nullptr;
  if (FloatWidth > 80) {
    TempMod += 32;
    Value *Add = Builder.CreateShl(AAddr1Off32, Builder.getInt64(TempMod));
    Shl30 = Builder.CreateAdd(
        Add, Builder.getInt64(((1ull << (62ull - TempMod)) - 1ull) << TempMod));
    And34 = Builder.CreateZExt(Shl30, Builder.getInt128Ty());
  } else {
    Value *Add = Builder.CreateShl(E0, Builder.getInt32(TempMod));
    Shl30 = Builder.CreateAdd(
        Add, Builder.getInt32(((1 << (30 - TempMod)) - 1) << TempMod));
    And34 = Builder.CreateAnd(FloatWidth > 32 ? AAddr1Off32 : AAddr1Off0,
                              Builder.getInt32((1 << TempMod) - 1));
  }
  Value *Or35 = nullptr;
  if (FloatWidth > 80) {
    Value *And29Trunc = Builder.CreateTrunc(And29, Builder.getInt128Ty());
    Value *Or31 = Builder.CreateOr(And29Trunc, And34);
    Value *Or34 = Builder.CreateShl(Or31, Builder.getIntN(128, 64));
    Value *Temp3 = Builder.CreateShl(Builder.getIntN(128, 1),
                                     Builder.getIntN(128, FPMantissaWidth));
    Value *Temp4 = Builder.CreateSub(Temp3, Builder.getIntN(128, 1));
    Value *A6 = Builder.CreateAnd(AAddr1Off0, Temp4);
    Or35 = Builder.CreateOr(Or34, A6);
  } else {
    Value *Or31 = Builder.CreateOr(And34, And29);
    Or35 = Builder.CreateOr(IsSigned ? Or31 : And34, Shl30);
  }
  Value *A4 = nullptr;
  if (IToFP->getType()->isDoubleTy()) {
    Value *ZExt1 = Builder.CreateZExt(Or35, Builder.getIntNTy(FloatWidth));
    Value *Shl1 = Builder.CreateShl(ZExt1, Builder.getIntN(FloatWidth, 32));
    Value *And1 =
        Builder.CreateAnd(AAddr1Off0, Builder.getIntN(FloatWidth, 0xFFFFFFFF));
    Value *Or1 = Builder.CreateOr(Shl1, And1);
    A4 = Builder.CreateBitCast(Or1, IToFP->getType());
  } else if (IToFP->getType()->isX86_FP80Ty()) {
    Value *A40 =
        Builder.CreateBitCast(Or35, Type::getFP128Ty(Builder.getContext()));
    A4 = Builder.CreateFPTrunc(A40, IToFP->getType());
  } else if (IToFP->getType()->isHalfTy() || IToFP->getType()->isBFloatTy()) {
    // Deal with "half" situation. This is a workaround since we don't have
    // floattihf.c currently as referring.
    Value *A40 =
        Builder.CreateBitCast(Or35, Type::getFloatTy(Builder.getContext()));
    A4 = Builder.CreateFPTrunc(A40, IToFP->getType());
  } else // float type
    A4 = Builder.CreateBitCast(Or35, IToFP->getType());

  // Sub2 is the unbiased exponent (the index of the top set bit in the input).
  // The exponent arithmetic above wraps to garbage instead of inf once it
  // overflows the exponent field, so saturate to a correctly-signed infinity
  // when Sub2 reaches 1 << (ExponentWidth - 1). Sub2 is at most BitWidth - 1,
  // so skip the check entirely when even that can't reach the threshold.
  // (Values that round *up* into inf, e.g. 2^n - 1, keep Sub2 = BitWidth - 1;
  // these are handled by the conversion's own rounding, not by this
  // saturation.)
  unsigned ExponentWidth = FloatWidth - FPMantissaWidth - 1;
  uint64_t MinInfExp = 1ULL << (ExponentWidth - 1);
  if (BitWidth - 1 >= MinInfExp) {
    Value *MinInfExpVal = Builder.getIntN(BitWidthNew, MinInfExp);
    Value *Overflow = Builder.CreateICmpUGE(Sub2, MinInfExpVal);
    Value *Inf = ConstantFP::getInfinity(IToFP->getType(), /*Negative=*/false);
    if (IsSigned) {
      Value *NegInf =
          ConstantFP::getInfinity(IToFP->getType(), /*Negative=*/true);
      Value *IsNeg =
          Builder.CreateICmpSLT(IntVal, ConstantInt::getNullValue(IntTy));
      Inf = Builder.CreateSelectWithUnknownProfile(IsNeg, NegInf, Inf,
                                                   DEBUG_TYPE);
    }
    A4 = Builder.CreateSelect(Overflow, Inf, A4);
    // We consider overflow to be an unlikely case.
    applyProfMetadataIfEnabled(A4, [&](Instruction *Inst) {
      Inst->setMetadata(
          LLVMContext::MD_prof,
          MDBuilder(Inst->getContext()).createUnlikelyBranchWeights());
    });
  }
  Builder.CreateBr(End);

  // return:
  Builder.SetInsertPoint(End->begin());
  PHINode *Retval0 = Builder.CreatePHI(IToFP->getType(), 2);
  Retval0->addIncoming(A4, IfEnd26);
  Retval0->addIncoming(ConstantFP::getZero(IToFP->getType(), false), Entry);

  IToFP->replaceAllUsesWith(Retval0);
  IToFP->dropAllReferences();
  IToFP->eraseFromParent();
}

static void scalarize(Instruction *I,
                      SmallVectorImpl<Instruction *> &Worklist) {
  VectorType *VTy = cast<FixedVectorType>(I->getType());

  IRBuilder<> Builder(I);

  unsigned NumElements = VTy->getElementCount().getFixedValue();
  Value *Result = PoisonValue::get(VTy);
  for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
    Value *Ext = Builder.CreateExtractElement(I->getOperand(0), Idx);

    Value *NewOp = nullptr;
    if (auto *BinOp = dyn_cast<BinaryOperator>(I))
      NewOp = Builder.CreateBinOp(
          BinOp->getOpcode(), Ext,
          Builder.CreateExtractElement(I->getOperand(1), Idx));
    else if (auto *CastI = dyn_cast<CastInst>(I))
      NewOp = Builder.CreateCast(CastI->getOpcode(), Ext,
                                 I->getType()->getScalarType());
    else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
      assert(II->getIntrinsicID() == Intrinsic::fptoui_sat ||
             II->getIntrinsicID() == Intrinsic::fptosi_sat);
      NewOp = Builder.CreateIntrinsic(I->getType()->getScalarType(),
                                      II->getIntrinsicID(), {Ext});
    } else
      llvm_unreachable("Unsupported instruction type");

    Result = Builder.CreateInsertElement(Result, NewOp, Idx);
    if (auto *ScalarizedI = dyn_cast<Instruction>(NewOp)) {
      ScalarizedI->copyIRFlags(I, true);
      Worklist.push_back(ScalarizedI);
    }
  }

  I->replaceAllUsesWith(Result);
  I->dropAllReferences();
  I->eraseFromParent();
}

static void addToWorklist(Instruction &I,
                          SmallVector<Instruction *, 4> &Worklist) {
  if (I.getOperand(0)->getType()->isVectorTy())
    scalarize(&I, Worklist);
  else
    Worklist.push_back(&I);
}

static bool runImpl(Function &F, const TargetLowering &TLI,
                    const LibcallLoweringInfo &Libcalls, AssumptionCache *AC) {
  SmallVector<Instruction *, 4> Worklist;

  unsigned MaxLegalFpConvertBitWidth =
      TLI.getMaxLargeFPConvertBitWidthSupported();
  if (ExpandFpConvertBits != IntegerType::MAX_INT_BITS)
    MaxLegalFpConvertBitWidth = ExpandFpConvertBits;

  unsigned MaxLegalDivRemBitWidth = TLI.getMaxDivRemBitWidthSupported();
  if (ExpandDivRemBits != IntegerType::MAX_INT_BITS)
    MaxLegalDivRemBitWidth = ExpandDivRemBits;

  bool DisableExpandLargeFp =
      MaxLegalFpConvertBitWidth >= IntegerType::MAX_INT_BITS;
  bool DisableExpandLargeDivRem =
      MaxLegalDivRemBitWidth >= IntegerType::MAX_INT_BITS;
  bool DisableFrem = !FRemExpander::shouldExpandAnyFremType(TLI, Libcalls);

  if (DisableExpandLargeFp && DisableFrem && DisableExpandLargeDivRem)
    return false;

  auto ShouldHandleInst = [&](Instruction &I) {
    Type *Ty = I.getType();
    // TODO: This pass doesn't handle scalable vectors.
    if (Ty->isScalableTy())
      return false;

    switch (I.getOpcode()) {
    case Instruction::FRem:
      return !DisableFrem &&
             FRemExpander::shouldExpandFremType(TLI, Libcalls, Ty);
    case Instruction::FPToUI:
    case Instruction::FPToSI:
      return !DisableExpandLargeFp &&
             cast<IntegerType>(Ty->getScalarType())->getIntegerBitWidth() >
                 MaxLegalFpConvertBitWidth;
    case Instruction::UIToFP:
    case Instruction::SIToFP:
      return !DisableExpandLargeFp &&
             cast<IntegerType>(I.getOperand(0)->getType()->getScalarType())
                     ->getIntegerBitWidth() > MaxLegalFpConvertBitWidth;
    case Instruction::UDiv:
    case Instruction::SDiv:
    case Instruction::URem:
    case Instruction::SRem:
      // Power-of-2 divisors are handled inside the expansion (via efficient
      // shift/mask sequences) rather than being excluded here, so that
      // backends that cannot lower wide div/rem even for powers of two
      // (e.g. when DAGCombiner is disabled) still get valid lowered code.
      return !DisableExpandLargeDivRem &&
             cast<IntegerType>(Ty->getScalarType())->getIntegerBitWidth() >
                 MaxLegalDivRemBitWidth;
    case Instruction::Call: {
      auto *II = dyn_cast<IntrinsicInst>(&I);
      if (II && (II->getIntrinsicID() == Intrinsic::fptoui_sat ||
                 II->getIntrinsicID() == Intrinsic::fptosi_sat)) {
        return !DisableExpandLargeFp &&
               cast<IntegerType>(Ty->getScalarType())->getIntegerBitWidth() >
                   MaxLegalFpConvertBitWidth;
      }
      return false;
    }
    }

    return false;
  };

  bool Modified = false;
  for (auto It = inst_begin(&F), End = inst_end(F); It != End;) {
    Instruction &I = *It++;
    if (!ShouldHandleInst(I))
      continue;

    addToWorklist(I, Worklist);
    Modified = true;
  }

  while (!Worklist.empty()) {
    Instruction *I = Worklist.pop_back_val();

    switch (I->getOpcode()) {
    case Instruction::FRem: {
      auto SQ = [&]() -> std::optional<SimplifyQuery> {
        if (AC) {
          auto Res = std::make_optional<SimplifyQuery>(I->getDataLayout(), I);
          Res->AC = AC;
          return Res;
        }
        return {};
      }();

      expandFRem(cast<BinaryOperator>(*I), SQ);
      break;
    }

    case Instruction::FPToUI:
      expandFPToI(I, /*IsSaturating=*/false, /*IsSigned=*/false);
      break;
    case Instruction::FPToSI:
      expandFPToI(I, /*IsSaturating=*/false, /*IsSigned=*/true);
      break;

    case Instruction::UIToFP:
    case Instruction::SIToFP:
      expandIToFP(I);
      break;

    case Instruction::UDiv:
    case Instruction::SDiv:
    case Instruction::URem:
    case Instruction::SRem: {
      auto *BO = cast<BinaryOperator>(I);
      // TODO: isConstantPowerOfTwo does not handle vector constants, so
      // vector div/rem by a power-of-2 splat goes through the generic path.
      if (isConstantPowerOfTwo(BO->getOperand(1), isSigned(BO->getOpcode()))) {
        expandPow2DivRem(BO);
      } else {
        unsigned Opc = BO->getOpcode();
        if (Opc == Instruction::UDiv || Opc == Instruction::SDiv)
          expandDivision(BO);
        else
          expandRemainder(BO);
      }
      break;
    }
    case Instruction::Call: {
      auto *II = cast<IntrinsicInst>(I);
      assert(II->getIntrinsicID() == Intrinsic::fptoui_sat ||
             II->getIntrinsicID() == Intrinsic::fptosi_sat);
      expandFPToI(I, /*IsSaturating=*/true,
                  /*IsSigned=*/II->getIntrinsicID() == Intrinsic::fptosi_sat);
      break;
    }
    }
  }

  return Modified;
}

namespace {
class ExpandIRInstsLegacyPass : public FunctionPass {
  CodeGenOptLevel OptLevel;

public:
  static char ID;

  ExpandIRInstsLegacyPass(CodeGenOptLevel OptLevel)
      : FunctionPass(ID), OptLevel(OptLevel) {}

  ExpandIRInstsLegacyPass() : ExpandIRInstsLegacyPass(CodeGenOptLevel::None) {}

  bool runOnFunction(Function &F) override {
    auto *TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
    const TargetSubtargetInfo *Subtarget = TM->getSubtargetImpl(F);
    auto *TLI = Subtarget->getTargetLowering();
    AssumptionCache *AC = nullptr;

    const LibcallLoweringInfo &Libcalls =
        getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
            *F.getParent(), *Subtarget);

    if (OptLevel != CodeGenOptLevel::None && !F.hasOptNone())
      AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
    return runImpl(F, *TLI, Libcalls, AC);
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<LibcallLoweringInfoWrapper>();
    AU.addRequired<TargetPassConfig>();
    if (OptLevel != CodeGenOptLevel::None)
      AU.addRequired<AssumptionCacheTracker>();
    AU.addPreserved<AAResultsWrapperPass>();
    AU.addPreserved<GlobalsAAWrapperPass>();
    AU.addRequired<LibcallLoweringInfoWrapper>();
  }
};
} // namespace

ExpandIRInstsPass::ExpandIRInstsPass(const TargetMachine &TM,
                                     CodeGenOptLevel OptLevel)
    : TM(&TM), OptLevel(OptLevel) {}

void ExpandIRInstsPass::printPipeline(
    raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
  static_cast<PassInfoMixin<ExpandIRInstsPass> *>(this)->printPipeline(
      OS, MapClassName2PassName);
  OS << '<';
  OS << "O" << (int)OptLevel;
  OS << '>';
}

PreservedAnalyses ExpandIRInstsPass::run(Function &F,
                                         FunctionAnalysisManager &FAM) {
  const TargetSubtargetInfo *STI = TM->getSubtargetImpl(F);
  auto &TLI = *STI->getTargetLowering();
  AssumptionCache *AC = nullptr;
  if (OptLevel != CodeGenOptLevel::None)
    AC = &FAM.getResult<AssumptionAnalysis>(F);

  auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);

  const ModuleLibcallLoweringInfo *LibcallLowering =
      MAMProxy.getCachedResult<LibcallLoweringModuleAnalysis>(*F.getParent());

  if (!LibcallLowering) {
    F.getContext().emitError("'" + LibcallLoweringModuleAnalysis::name() +
                             "' analysis required");
    return PreservedAnalyses::all();
  }

  const LibcallLoweringInfo &Libcalls =
      getLibcallLowering(*LibcallLowering, *STI);

  return runImpl(F, TLI, Libcalls, AC) ? PreservedAnalyses::none()
                                       : PreservedAnalyses::all();
}

char ExpandIRInstsLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(ExpandIRInstsLegacyPass, "expand-ir-insts",
                      "Expand certain fp instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(LibcallLoweringInfoWrapper)
INITIALIZE_PASS_END(ExpandIRInstsLegacyPass, "expand-ir-insts",
                    "Expand IR instructions", false, false)

FunctionPass *llvm::createExpandIRInstsPass(CodeGenOptLevel OptLevel) {
  return new ExpandIRInstsLegacyPass(OptLevel);
}
