//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
//
// 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 implements float type expansion and softening for LegalizeTypes.
// Softening is the act of turning a computation in an illegal floating point
// type into a computation in an integer type of the same size; also known as
// "soft float".  For example, turning f32 arithmetic into operations using i32.
// The resulting integer value is the same as what you would get by performing
// the floating point operation and bitcasting the result to the integer type.
// Expansion is the act of changing a computation in an illegal type to be a
// computation in two identical registers of a smaller type.  For example,
// implementing ppcf128 arithmetic in two f64 registers.
//
//===----------------------------------------------------------------------===//

#include "LegalizeTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "legalize-types"

/// GetFPLibCall - Return the right libcall for the given floating point type.
static RTLIB::Libcall GetFPLibCall(EVT VT,
                                   RTLIB::Libcall Call_F32,
                                   RTLIB::Libcall Call_F64,
                                   RTLIB::Libcall Call_F80,
                                   RTLIB::Libcall Call_F128,
                                   RTLIB::Libcall Call_PPCF128) {
  return
    VT == MVT::f32 ? Call_F32 :
    VT == MVT::f64 ? Call_F64 :
    VT == MVT::f80 ? Call_F80 :
    VT == MVT::f128 ? Call_F128 :
    VT == MVT::ppcf128 ? Call_PPCF128 :
    RTLIB::UNKNOWN_LIBCALL;
}

//===----------------------------------------------------------------------===//
//  Convert Float Results to Integer
//===----------------------------------------------------------------------===//

void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
  LLVM_DEBUG(dbgs() << "Soften float result " << ResNo << ": "; N->dump(&DAG);
             dbgs() << "\n");
  SDValue R = SDValue();

  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "SoftenFloatResult #" << ResNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
#endif
    llvm_unreachable("Do not know how to soften the result of this operator!");

    case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break;
    case ISD::BITCAST:     R = SoftenFloatRes_BITCAST(N); break;
    case ISD::BUILD_PAIR:  R = SoftenFloatRes_BUILD_PAIR(N); break;
    case ISD::ConstantFP:  R = SoftenFloatRes_ConstantFP(N); break;
    case ISD::EXTRACT_VECTOR_ELT:
      R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break;
    case ISD::FABS:        R = SoftenFloatRes_FABS(N); break;
    case ISD::STRICT_FMINNUM:
    case ISD::FMINNUM:     R = SoftenFloatRes_FMINNUM(N); break;
    case ISD::STRICT_FMAXNUM:
    case ISD::FMAXNUM:     R = SoftenFloatRes_FMAXNUM(N); break;
    case ISD::STRICT_FADD:
    case ISD::FADD:        R = SoftenFloatRes_FADD(N); break;
    case ISD::FCBRT:       R = SoftenFloatRes_FCBRT(N); break;
    case ISD::STRICT_FCEIL:
    case ISD::FCEIL:       R = SoftenFloatRes_FCEIL(N); break;
    case ISD::FCOPYSIGN:   R = SoftenFloatRes_FCOPYSIGN(N); break;
    case ISD::STRICT_FCOS:
    case ISD::FCOS:        R = SoftenFloatRes_FCOS(N); break;
    case ISD::STRICT_FDIV:
    case ISD::FDIV:        R = SoftenFloatRes_FDIV(N); break;
    case ISD::STRICT_FEXP:
    case ISD::FEXP:        R = SoftenFloatRes_FEXP(N); break;
    case ISD::STRICT_FEXP2:
    case ISD::FEXP2:       R = SoftenFloatRes_FEXP2(N); break;
    case ISD::STRICT_FFLOOR:
    case ISD::FFLOOR:      R = SoftenFloatRes_FFLOOR(N); break;
    case ISD::STRICT_FLOG:
    case ISD::FLOG:        R = SoftenFloatRes_FLOG(N); break;
    case ISD::STRICT_FLOG2:
    case ISD::FLOG2:       R = SoftenFloatRes_FLOG2(N); break;
    case ISD::STRICT_FLOG10:
    case ISD::FLOG10:      R = SoftenFloatRes_FLOG10(N); break;
    case ISD::STRICT_FMA:
    case ISD::FMA:         R = SoftenFloatRes_FMA(N); break;
    case ISD::STRICT_FMUL:
    case ISD::FMUL:        R = SoftenFloatRes_FMUL(N); break;
    case ISD::STRICT_FNEARBYINT:
    case ISD::FNEARBYINT:  R = SoftenFloatRes_FNEARBYINT(N); break;
    case ISD::FNEG:        R = SoftenFloatRes_FNEG(N); break;
    case ISD::STRICT_FP_EXTEND:
    case ISD::FP_EXTEND:   R = SoftenFloatRes_FP_EXTEND(N); break;
    case ISD::STRICT_FP_ROUND:
    case ISD::FP_ROUND:    R = SoftenFloatRes_FP_ROUND(N); break;
    case ISD::FP16_TO_FP:  R = SoftenFloatRes_FP16_TO_FP(N); break;
    case ISD::STRICT_FPOW:
    case ISD::FPOW:        R = SoftenFloatRes_FPOW(N); break;
    case ISD::STRICT_FPOWI:
    case ISD::FPOWI:       R = SoftenFloatRes_FPOWI(N); break;
    case ISD::STRICT_FREM:
    case ISD::FREM:        R = SoftenFloatRes_FREM(N); break;
    case ISD::STRICT_FRINT:
    case ISD::FRINT:       R = SoftenFloatRes_FRINT(N); break;
    case ISD::STRICT_FROUND:
    case ISD::FROUND:      R = SoftenFloatRes_FROUND(N); break;
    case ISD::STRICT_FROUNDEVEN:
    case ISD::FROUNDEVEN:  R = SoftenFloatRes_FROUNDEVEN(N); break;
    case ISD::STRICT_FSIN:
    case ISD::FSIN:        R = SoftenFloatRes_FSIN(N); break;
    case ISD::STRICT_FSQRT:
    case ISD::FSQRT:       R = SoftenFloatRes_FSQRT(N); break;
    case ISD::STRICT_FSUB:
    case ISD::FSUB:        R = SoftenFloatRes_FSUB(N); break;
    case ISD::STRICT_FTRUNC:
    case ISD::FTRUNC:      R = SoftenFloatRes_FTRUNC(N); break;
    case ISD::LOAD:        R = SoftenFloatRes_LOAD(N); break;
    case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
    case ISD::SELECT:      R = SoftenFloatRes_SELECT(N); break;
    case ISD::SELECT_CC:   R = SoftenFloatRes_SELECT_CC(N); break;
    case ISD::FREEZE:      R = SoftenFloatRes_FREEZE(N); break;
    case ISD::STRICT_SINT_TO_FP:
    case ISD::STRICT_UINT_TO_FP:
    case ISD::SINT_TO_FP:
    case ISD::UINT_TO_FP:  R = SoftenFloatRes_XINT_TO_FP(N); break;
    case ISD::UNDEF:       R = SoftenFloatRes_UNDEF(N); break;
    case ISD::VAARG:       R = SoftenFloatRes_VAARG(N); break;
    case ISD::VECREDUCE_FADD:
    case ISD::VECREDUCE_FMUL:
    case ISD::VECREDUCE_FMIN:
    case ISD::VECREDUCE_FMAX:
      R = SoftenFloatRes_VECREDUCE(N);
      break;
    case ISD::VECREDUCE_SEQ_FADD:
    case ISD::VECREDUCE_SEQ_FMUL:
      R = SoftenFloatRes_VECREDUCE_SEQ(N);
      break;
  }

  // If R is null, the sub-method took care of registering the result.
  if (R.getNode()) {
    assert(R.getNode() != N);
    SetSoftenedFloat(SDValue(N, ResNo), R);
  }
}

SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC) {
  bool IsStrict = N->isStrictFPOpcode();
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  unsigned Offset = IsStrict ? 1 : 0;
  assert(N->getNumOperands() == (1 + Offset) &&
         "Unexpected number of operands!");
  SDValue Op = GetSoftenedFloat(N->getOperand(0 + Offset));
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpVT = N->getOperand(0 + Offset).getValueType();
  CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC) {
  bool IsStrict = N->isStrictFPOpcode();
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  unsigned Offset = IsStrict ? 1 : 0;
  assert(N->getNumOperands() == (2 + Offset) &&
         "Unexpected number of operands!");
  SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
                     GetSoftenedFloat(N->getOperand(1 + Offset)) };
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
                   N->getOperand(1 + Offset).getValueType() };
  CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N) {
  return BitConvertToInteger(N->getOperand(0));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FREEZE(SDNode *N) {
  EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  return DAG.getNode(ISD::FREEZE, SDLoc(N), Ty,
                     GetSoftenedFloat(N->getOperand(0)));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_MERGE_VALUES(SDNode *N,
                                                      unsigned ResNo) {
  SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
  return BitConvertToInteger(Op);
}

SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
  // Convert the inputs to integers, and build a new pair out of them.
  return DAG.getNode(ISD::BUILD_PAIR, SDLoc(N),
                     TLI.getTypeToTransformTo(*DAG.getContext(),
                                              N->getValueType(0)),
                     BitConvertToInteger(N->getOperand(0)),
                     BitConvertToInteger(N->getOperand(1)));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
  ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
  // In ppcf128, the high 64 bits are always first in memory regardless
  // of Endianness. LLVM's APFloat representation is not Endian sensitive,
  // and so always converts into a 128-bit APInt in a non-Endian-sensitive
  // way. However, APInt's are serialized in an Endian-sensitive fashion,
  // so on big-Endian targets, the two doubles are output in the wrong
  // order. Fix this by manually flipping the order of the high 64 bits
  // and the low 64 bits here.
  if (DAG.getDataLayout().isBigEndian() &&
      CN->getValueType(0).getSimpleVT() == llvm::MVT::ppcf128) {
    uint64_t words[2] = { CN->getValueAPF().bitcastToAPInt().getRawData()[1],
                          CN->getValueAPF().bitcastToAPInt().getRawData()[0] };
    APInt Val(128, words);
    return DAG.getConstant(Val, SDLoc(CN),
                           TLI.getTypeToTransformTo(*DAG.getContext(),
                                                    CN->getValueType(0)));
  } else {
    return DAG.getConstant(CN->getValueAPF().bitcastToAPInt(), SDLoc(CN),
                           TLI.getTypeToTransformTo(*DAG.getContext(),
                                                    CN->getValueType(0)));
  }
}

SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
  SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
                     NewOp.getValueType().getVectorElementType(),
                     NewOp, N->getOperand(1));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  unsigned Size = NVT.getSizeInBits();

  // Mask = ~(1 << (Size-1))
  APInt API = APInt::getAllOnesValue(Size);
  API.clearBit(Size - 1);
  SDValue Mask = DAG.getConstant(API, SDLoc(N), NVT);
  SDValue Op = GetSoftenedFloat(N->getOperand(0));
  return DAG.getNode(ISD::AND, SDLoc(N), NVT, Op, Mask);
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FMINNUM(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::FMIN_F32,
                                               RTLIB::FMIN_F64,
                                               RTLIB::FMIN_F80,
                                               RTLIB::FMIN_F128,
                                               RTLIB::FMIN_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FMAXNUM(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::FMAX_F32,
                                               RTLIB::FMAX_F64,
                                               RTLIB::FMAX_F80,
                                               RTLIB::FMAX_F128,
                                               RTLIB::FMAX_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::ADD_F32,
                                               RTLIB::ADD_F64,
                                               RTLIB::ADD_F80,
                                               RTLIB::ADD_F128,
                                               RTLIB::ADD_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FCBRT(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                           RTLIB::CBRT_F32,
                                           RTLIB::CBRT_F64,
                                           RTLIB::CBRT_F80,
                                           RTLIB::CBRT_F128,
                                           RTLIB::CBRT_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::CEIL_F32,
                                              RTLIB::CEIL_F64,
                                              RTLIB::CEIL_F80,
                                              RTLIB::CEIL_F128,
                                              RTLIB::CEIL_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
  SDValue LHS = GetSoftenedFloat(N->getOperand(0));
  SDValue RHS = BitConvertToInteger(N->getOperand(1));
  SDLoc dl(N);

  EVT LVT = LHS.getValueType();
  EVT RVT = RHS.getValueType();

  unsigned LSize = LVT.getSizeInBits();
  unsigned RSize = RVT.getSizeInBits();

  // First get the sign bit of second operand.
  SDValue SignBit = DAG.getNode(
      ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
      DAG.getConstant(RSize - 1, dl,
                      TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
  SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit);

  // Shift right or sign-extend it if the two operands have different types.
  int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
  if (SizeDiff > 0) {
    SignBit =
        DAG.getNode(ISD::SRL, dl, RVT, SignBit,
                    DAG.getConstant(SizeDiff, dl,
                                    TLI.getShiftAmountTy(SignBit.getValueType(),
                                                         DAG.getDataLayout())));
    SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit);
  } else if (SizeDiff < 0) {
    SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit);
    SignBit =
        DAG.getNode(ISD::SHL, dl, LVT, SignBit,
                    DAG.getConstant(-SizeDiff, dl,
                                    TLI.getShiftAmountTy(SignBit.getValueType(),
                                                         DAG.getDataLayout())));
  }

  // Clear the sign bit of the first operand.
  SDValue Mask = DAG.getNode(
      ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
      DAG.getConstant(LSize - 1, dl,
                      TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
  Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
  LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask);

  // Or the value with the sign bit.
  return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::COS_F32,
                                              RTLIB::COS_F64,
                                              RTLIB::COS_F80,
                                              RTLIB::COS_F128,
                                              RTLIB::COS_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::DIV_F32,
                                               RTLIB::DIV_F64,
                                               RTLIB::DIV_F80,
                                               RTLIB::DIV_F128,
                                               RTLIB::DIV_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::EXP_F32,
                                              RTLIB::EXP_F64,
                                              RTLIB::EXP_F80,
                                              RTLIB::EXP_F128,
                                              RTLIB::EXP_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::EXP2_F32,
                                              RTLIB::EXP2_F64,
                                              RTLIB::EXP2_F80,
                                              RTLIB::EXP2_F128,
                                              RTLIB::EXP2_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::FLOOR_F32,
                                              RTLIB::FLOOR_F64,
                                              RTLIB::FLOOR_F80,
                                              RTLIB::FLOOR_F128,
                                              RTLIB::FLOOR_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::LOG_F32,
                                              RTLIB::LOG_F64,
                                              RTLIB::LOG_F80,
                                              RTLIB::LOG_F128,
                                              RTLIB::LOG_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::LOG2_F32,
                                              RTLIB::LOG2_F64,
                                              RTLIB::LOG2_F80,
                                              RTLIB::LOG2_F128,
                                              RTLIB::LOG2_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::LOG10_F32,
                                              RTLIB::LOG10_F64,
                                              RTLIB::LOG10_F80,
                                              RTLIB::LOG10_F128,
                                              RTLIB::LOG10_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  unsigned Offset = IsStrict ? 1 : 0;
  SDValue Ops[3] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
                     GetSoftenedFloat(N->getOperand(1 + Offset)),
                     GetSoftenedFloat(N->getOperand(2 + Offset)) };
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpsVT[3] = { N->getOperand(0 + Offset).getValueType(),
                   N->getOperand(1 + Offset).getValueType(),
                   N->getOperand(2 + Offset).getValueType() };
  CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
                                                    GetFPLibCall(N->getValueType(0),
                                                                 RTLIB::FMA_F32,
                                                                 RTLIB::FMA_F64,
                                                                 RTLIB::FMA_F80,
                                                                 RTLIB::FMA_F128,
                                                                 RTLIB::FMA_PPCF128),
                         NVT, Ops, CallOptions, SDLoc(N), Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::MUL_F32,
                                               RTLIB::MUL_F64,
                                               RTLIB::MUL_F80,
                                               RTLIB::MUL_F128,
                                               RTLIB::MUL_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::NEARBYINT_F32,
                                              RTLIB::NEARBYINT_F64,
                                              RTLIB::NEARBYINT_F80,
                                              RTLIB::NEARBYINT_F128,
                                              RTLIB::NEARBYINT_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDLoc dl(N);

  // Expand Y = FNEG(X) -> Y = X ^ sign mask
  APInt SignMask = APInt::getSignMask(NVT.getSizeInBits());
  return DAG.getNode(ISD::XOR, dl, NVT, GetSoftenedFloat(N->getOperand(0)),
                     DAG.getConstant(SignMask, dl, NVT));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op = N->getOperand(IsStrict ? 1 : 0);

  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();

  if (getTypeAction(Op.getValueType()) == TargetLowering::TypePromoteFloat) {
    Op = GetPromotedFloat(Op);
    // If the promotion did the FP_EXTEND to the destination type for us,
    // there's nothing left to do here.
    if (Op.getValueType() == N->getValueType(0))
      return BitConvertToInteger(Op);
  }

  // There's only a libcall for f16 -> f32, so proceed in two stages. Also, it's
  // entirely possible for both f16 and f32 to be legal, so use the fully
  // hard-float FP_EXTEND rather than FP16_TO_FP.
  if (Op.getValueType() == MVT::f16 && N->getValueType(0) != MVT::f32) {
    if (IsStrict) {
      Op = DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N),
                       { MVT::f32, MVT::Other }, { Chain, Op });
      Chain = Op.getValue(1);
    } else {
      Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(N), MVT::f32, Op);
    }
  }

  RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
  CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

// FIXME: Should we just use 'normal' FP_EXTEND / FP_TRUNC instead of special
// nodes?
SDValue DAGTypeLegalizer::SoftenFloatRes_FP16_TO_FP(SDNode *N) {
  EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
  SDValue Op = N->getOperand(0);
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpsVT[1] = { N->getOperand(0).getValueType() };
  CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
  SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT, Op,
                                  CallOptions, SDLoc(N)).first;
  if (N->getValueType(0) == MVT::f32)
    return Res32;

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  RTLIB::Libcall LC = RTLIB::getFPEXT(MVT::f32, N->getValueType(0));
  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
  return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(N)).first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op = N->getOperand(IsStrict ? 1 : 0);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
  CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::POW_F32,
                                               RTLIB::POW_F64,
                                               RTLIB::POW_F80,
                                               RTLIB::POW_F128,
                                               RTLIB::POW_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  assert(N->getOperand(1 + Offset).getValueType() == MVT::i32 &&
         "Unsupported power type!");
  RTLIB::Libcall LC = GetFPLibCall(N->getValueType(0),
                                   RTLIB::POWI_F32,
                                   RTLIB::POWI_F64,
                                   RTLIB::POWI_F80,
                                   RTLIB::POWI_F128,
                                   RTLIB::POWI_PPCF128);
  if (!TLI.getLibcallName(LC)) {
    // Some targets don't have a powi libcall; use pow instead.
    // FIXME: Implement this if some target needs it.
    DAG.getContext()->emitError("Don't know how to soften fpowi to fpow");
    return DAG.getUNDEF(N->getValueType(0));
  }

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0 + Offset)),
                     N->getOperand(1 + Offset) };
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpsVT[2] = { N->getOperand(0 + Offset).getValueType(),
                   N->getOperand(1 + Offset).getValueType() };
  CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Ops,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::REM_F32,
                                               RTLIB::REM_F64,
                                               RTLIB::REM_F80,
                                               RTLIB::REM_F128,
                                               RTLIB::REM_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::RINT_F32,
                                              RTLIB::RINT_F64,
                                              RTLIB::RINT_F80,
                                              RTLIB::RINT_F128,
                                              RTLIB::RINT_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FROUND(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::ROUND_F32,
                                              RTLIB::ROUND_F64,
                                              RTLIB::ROUND_F80,
                                              RTLIB::ROUND_F128,
                                              RTLIB::ROUND_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FROUNDEVEN(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::ROUNDEVEN_F32,
                                              RTLIB::ROUNDEVEN_F64,
                                              RTLIB::ROUNDEVEN_F80,
                                              RTLIB::ROUNDEVEN_F128,
                                              RTLIB::ROUNDEVEN_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::SIN_F32,
                                              RTLIB::SIN_F64,
                                              RTLIB::SIN_F80,
                                              RTLIB::SIN_F128,
                                              RTLIB::SIN_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::SQRT_F32,
                                              RTLIB::SQRT_F64,
                                              RTLIB::SQRT_F80,
                                              RTLIB::SQRT_F128,
                                              RTLIB::SQRT_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
  return SoftenFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                               RTLIB::SUB_F32,
                                               RTLIB::SUB_F64,
                                               RTLIB::SUB_F80,
                                               RTLIB::SUB_F128,
                                               RTLIB::SUB_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
  return SoftenFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                              RTLIB::TRUNC_F32,
                                              RTLIB::TRUNC_F64,
                                              RTLIB::TRUNC_F80,
                                              RTLIB::TRUNC_F128,
                                              RTLIB::TRUNC_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
  LoadSDNode *L = cast<LoadSDNode>(N);
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDLoc dl(N);

  auto MMOFlags =
      L->getMemOperand()->getFlags() &
      ~(MachineMemOperand::MOInvariant | MachineMemOperand::MODereferenceable);
  SDValue NewL;
  if (L->getExtensionType() == ISD::NON_EXTLOAD) {
    NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), NVT, dl,
                       L->getChain(), L->getBasePtr(), L->getOffset(),
                       L->getPointerInfo(), NVT, L->getOriginalAlign(),
                       MMOFlags, L->getAAInfo());
    // Legalized the chain result - switch anything that used the old chain to
    // use the new one.
    ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
    return NewL;
  }

  // Do a non-extending load followed by FP_EXTEND.
  NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, L->getMemoryVT(),
                     dl, L->getChain(), L->getBasePtr(), L->getOffset(),
                     L->getPointerInfo(), L->getMemoryVT(),
                     L->getOriginalAlign(), MMOFlags, L->getAAInfo());
  // Legalized the chain result - switch anything that used the old chain to
  // use the new one.
  ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
  auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL);
  return BitConvertToInteger(ExtendNode);
}

SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
  SDValue LHS = GetSoftenedFloat(N->getOperand(1));
  SDValue RHS = GetSoftenedFloat(N->getOperand(2));
  return DAG.getSelect(SDLoc(N),
                       LHS.getValueType(), N->getOperand(0), LHS, RHS);
}

SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
  SDValue LHS = GetSoftenedFloat(N->getOperand(2));
  SDValue RHS = GetSoftenedFloat(N->getOperand(3));
  return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
                     LHS.getValueType(), N->getOperand(0),
                     N->getOperand(1), LHS, RHS, N->getOperand(4));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode *N) {
  return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
                                               N->getValueType(0)));
}

SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) {
  SDValue Chain = N->getOperand(0); // Get the chain.
  SDValue Ptr = N->getOperand(1); // Get the pointer.
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDLoc dl(N);

  SDValue NewVAARG;
  NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2),
                          N->getConstantOperandVal(3));

  // Legalized the chain result - switch anything that used the old chain to
  // use the new one.
  if (N != NewVAARG.getValue(1).getNode())
    ReplaceValueWith(SDValue(N, 1), NewVAARG.getValue(1));
  return NewVAARG;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  bool Signed = N->getOpcode() == ISD::SINT_TO_FP ||
                N->getOpcode() == ISD::STRICT_SINT_TO_FP;
  EVT SVT = N->getOperand(IsStrict ? 1 : 0).getValueType();
  EVT RVT = N->getValueType(0);
  EVT NVT = EVT();
  SDLoc dl(N);

  // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
  // a larger type, eg: i8 -> fp.  Even if it is legal, no libcall may exactly
  // match.  Look for an appropriate libcall.
  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
  for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
       t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
    NVT = (MVT::SimpleValueType)t;
    // The source needs to big enough to hold the operand.
    if (NVT.bitsGE(SVT))
      LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT);
  }
  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");

  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  // Sign/zero extend the argument if the libcall takes a larger type.
  SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
                           NVT, N->getOperand(IsStrict ? 1 : 0));
  TargetLowering::MakeLibCallOptions CallOptions;
  CallOptions.setSExt(Signed);
  CallOptions.setTypeListBeforeSoften(SVT, RVT, true);
  std::pair<SDValue, SDValue> Tmp =
      TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
                      Op, CallOptions, dl, Chain);

  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE(SDNode *N) {
  // Expand and soften recursively.
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
  return SDValue();
}

SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(SDNode *N) {
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
  return SDValue();
}

//===----------------------------------------------------------------------===//
//  Convert Float Operand to Integer
//===----------------------------------------------------------------------===//

bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
  LLVM_DEBUG(dbgs() << "Soften float operand " << OpNo << ": "; N->dump(&DAG);
             dbgs() << "\n");
  SDValue Res = SDValue();

  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "SoftenFloatOperand Op #" << OpNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
#endif
    llvm_unreachable("Do not know how to soften this operator's operand!");

  case ISD::BITCAST:     Res = SoftenFloatOp_BITCAST(N); break;
  case ISD::BR_CC:       Res = SoftenFloatOp_BR_CC(N); break;
  case ISD::FP_TO_FP16:  // Same as FP_ROUND for softening purposes
  case ISD::STRICT_FP_ROUND:
  case ISD::FP_ROUND:    Res = SoftenFloatOp_FP_ROUND(N); break;
  case ISD::STRICT_FP_TO_SINT:
  case ISD::STRICT_FP_TO_UINT:
  case ISD::FP_TO_SINT:
  case ISD::FP_TO_UINT:  Res = SoftenFloatOp_FP_TO_XINT(N); break;
  case ISD::FP_TO_SINT_SAT:
  case ISD::FP_TO_UINT_SAT:
                         Res = SoftenFloatOp_FP_TO_XINT_SAT(N); break;
  case ISD::STRICT_LROUND:
  case ISD::LROUND:      Res = SoftenFloatOp_LROUND(N); break;
  case ISD::STRICT_LLROUND:
  case ISD::LLROUND:     Res = SoftenFloatOp_LLROUND(N); break;
  case ISD::STRICT_LRINT:
  case ISD::LRINT:       Res = SoftenFloatOp_LRINT(N); break;
  case ISD::STRICT_LLRINT:
  case ISD::LLRINT:      Res = SoftenFloatOp_LLRINT(N); break;
  case ISD::SELECT_CC:   Res = SoftenFloatOp_SELECT_CC(N); break;
  case ISD::STRICT_FSETCC:
  case ISD::STRICT_FSETCCS:
  case ISD::SETCC:       Res = SoftenFloatOp_SETCC(N); break;
  case ISD::STORE:       Res = SoftenFloatOp_STORE(N, OpNo); break;
  case ISD::FCOPYSIGN:   Res = SoftenFloatOp_FCOPYSIGN(N); break;
  }

  // If the result is null, the sub-method took care of registering results etc.
  if (!Res.getNode()) return false;

  // If the result is N, the sub-method updated N in place.  Tell the legalizer
  // core about this to re-analyze.
  if (Res.getNode() == N)
    return true;

  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
         "Invalid operand softening");

  ReplaceValueWith(SDValue(N, 0), Res);
  return false;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_BITCAST(SDNode *N) {
  SDValue Op0 = GetSoftenedFloat(N->getOperand(0));

  return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op0);
}

SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
  // We actually deal with the partially-softened FP_TO_FP16 node too, which
  // returns an i16 so doesn't meet the constraints necessary for FP_ROUND.
  assert(N->getOpcode() == ISD::FP_ROUND || N->getOpcode() == ISD::FP_TO_FP16 ||
         N->getOpcode() == ISD::STRICT_FP_ROUND);

  bool IsStrict = N->isStrictFPOpcode();
  SDValue Op = N->getOperand(IsStrict ? 1 : 0);
  EVT SVT = Op.getValueType();
  EVT RVT = N->getValueType(0);
  EVT FloatRVT = N->getOpcode() == ISD::FP_TO_FP16 ? MVT::f16 : RVT;

  RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, FloatRVT);
  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");

  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  Op = GetSoftenedFloat(Op);
  TargetLowering::MakeLibCallOptions CallOptions;
  CallOptions.setTypeListBeforeSoften(SVT, RVT, true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT, Op,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict) {
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
    ReplaceValueWith(SDValue(N, 0), Tmp.first);
    return SDValue();
  }
  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();

  EVT VT = NewLHS.getValueType();
  NewLHS = GetSoftenedFloat(NewLHS);
  NewRHS = GetSoftenedFloat(NewRHS);
  TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N),
                          N->getOperand(2), N->getOperand(3));

  // If softenSetCCOperands returned a scalar, we need to compare the result
  // against zero to select between true and false values.
  if (!NewRHS.getNode()) {
    NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
    CCCode = ISD::SETNE;
  }

  // Update N to have the operands specified.
  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
                                N->getOperand(4)),
                 0);
}

// Even if the result type is legal, no libcall may exactly match. (e.g. We
// don't have FP-i8 conversions) This helper method looks for an appropriate
// promoted libcall.
static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted,
                                         bool Signed) {
  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
  for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
       IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
       ++IntVT) {
    Promoted = (MVT::SimpleValueType)IntVT;
    // The type needs to big enough to hold the result.
    if (Promoted.bitsGE(RetVT))
      LC = Signed ? RTLIB::getFPTOSINT(SrcVT, Promoted)
                  : RTLIB::getFPTOUINT(SrcVT, Promoted);
  }
  return LC;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
                N->getOpcode() == ISD::STRICT_FP_TO_SINT;

  SDValue Op = N->getOperand(IsStrict ? 1 : 0);
  EVT SVT = Op.getValueType();
  EVT RVT = N->getValueType(0);
  EVT NVT = EVT();
  SDLoc dl(N);

  // If the result is not legal, eg: fp -> i1, then it needs to be promoted to
  // a larger type, eg: fp -> i32. Even if it is legal, no libcall may exactly
  // match, eg. we don't have fp -> i8 conversions.
  // Look for an appropriate libcall.
  RTLIB::Libcall LC = findFPToIntLibcall(SVT, RVT, NVT, Signed);
  assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
         "Unsupported FP_TO_XINT!");

  Op = GetSoftenedFloat(Op);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  CallOptions.setTypeListBeforeSoften(SVT, RVT, true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
                                                    CallOptions, dl, Chain);

  // Truncate the result if the libcall returns a larger type.
  SDValue Res = DAG.getNode(ISD::TRUNCATE, dl, RVT, Tmp.first);

  if (!IsStrict)
    return Res;

  ReplaceValueWith(SDValue(N, 1), Tmp.second);
  ReplaceValueWith(SDValue(N, 0), Res);
  return SDValue();
}

SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N) {
  SDValue Res = TLI.expandFP_TO_INT_SAT(N, DAG);
  return Res;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();

  EVT VT = NewLHS.getValueType();
  NewLHS = GetSoftenedFloat(NewLHS);
  NewRHS = GetSoftenedFloat(NewRHS);
  TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N),
                          N->getOperand(0), N->getOperand(1));

  // If softenSetCCOperands returned a scalar, we need to compare the result
  // against zero to select between true and false values.
  if (!NewRHS.getNode()) {
    NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
    CCCode = ISD::SETNE;
  }

  // Update N to have the operands specified.
  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
                                N->getOperand(2), N->getOperand(3),
                                DAG.getCondCode(CCCode)),
                 0);
}

SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  SDValue Op0 = N->getOperand(IsStrict ? 1 : 0);
  SDValue Op1 = N->getOperand(IsStrict ? 2 : 1);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  ISD::CondCode CCCode =
      cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();

  EVT VT = Op0.getValueType();
  SDValue NewLHS = GetSoftenedFloat(Op0);
  SDValue NewRHS = GetSoftenedFloat(Op1);
  TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(N), Op0, Op1,
                          Chain, N->getOpcode() == ISD::STRICT_FSETCCS);

  // Update N to have the operands specified.
  if (NewRHS.getNode()) {
    if (IsStrict)
      NewLHS = DAG.getNode(ISD::SETCC, SDLoc(N), N->getValueType(0), NewLHS,
                           NewRHS, DAG.getCondCode(CCCode));
    else
      return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
                                            DAG.getCondCode(CCCode)), 0);
  }

  // Otherwise, softenSetCCOperands returned a scalar, use it.
  assert((NewRHS.getNode() || NewLHS.getValueType() == N->getValueType(0)) &&
         "Unexpected setcc expansion!");

  if (IsStrict) {
    ReplaceValueWith(SDValue(N, 0), NewLHS);
    ReplaceValueWith(SDValue(N, 1), Chain);
    return SDValue();
  }
  return NewLHS;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
  assert(OpNo == 1 && "Can only soften the stored value!");
  StoreSDNode *ST = cast<StoreSDNode>(N);
  SDValue Val = ST->getValue();
  SDLoc dl(N);

  if (ST->isTruncatingStore())
    // Do an FP_ROUND followed by a non-truncating store.
    Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(),
                                          Val, DAG.getIntPtrConstant(0, dl)));
  else
    Val = GetSoftenedFloat(Val);

  return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
                      ST->getMemOperand());
}

SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) {
  SDValue LHS = N->getOperand(0);
  SDValue RHS = BitConvertToInteger(N->getOperand(1));
  SDLoc dl(N);

  EVT LVT = LHS.getValueType();
  EVT ILVT = EVT::getIntegerVT(*DAG.getContext(), LVT.getSizeInBits());
  EVT RVT = RHS.getValueType();

  unsigned LSize = LVT.getSizeInBits();
  unsigned RSize = RVT.getSizeInBits();

  // Shift right or sign-extend it if the two operands have different types.
  int SizeDiff = RSize - LSize;
  if (SizeDiff > 0) {
    RHS =
        DAG.getNode(ISD::SRL, dl, RVT, RHS,
                    DAG.getConstant(SizeDiff, dl,
                                    TLI.getShiftAmountTy(RHS.getValueType(),
                                                         DAG.getDataLayout())));
    RHS = DAG.getNode(ISD::TRUNCATE, dl, ILVT, RHS);
  } else if (SizeDiff < 0) {
    RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, RHS);
    RHS =
        DAG.getNode(ISD::SHL, dl, ILVT, RHS,
                    DAG.getConstant(-SizeDiff, dl,
                                    TLI.getShiftAmountTy(RHS.getValueType(),
                                                         DAG.getDataLayout())));
  }

  RHS = DAG.getBitcast(LVT, RHS);
  return DAG.getNode(ISD::FCOPYSIGN, dl, LVT, LHS, RHS);
}

SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(SDNode *N, RTLIB::Libcall LC) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  bool IsStrict = N->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  SDValue Op = GetSoftenedFloat(N->getOperand(0 + Offset));
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  EVT OpVT = N->getOperand(0 + Offset).getValueType();
  CallOptions.setTypeListBeforeSoften(OpVT, N->getValueType(0), true);
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT, Op,
                                                    CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict) {
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
    ReplaceValueWith(SDValue(N, 0), Tmp.first);
    return SDValue();
  }

  return Tmp.first;
}

SDValue DAGTypeLegalizer::SoftenFloatOp_LROUND(SDNode *N) {
  EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
  return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
                                             RTLIB::LROUND_F32,
                                             RTLIB::LROUND_F64,
                                             RTLIB::LROUND_F80,
                                             RTLIB::LROUND_F128,
                                             RTLIB::LROUND_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatOp_LLROUND(SDNode *N) {
  EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
  return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
                                             RTLIB::LLROUND_F32,
                                             RTLIB::LLROUND_F64,
                                             RTLIB::LLROUND_F80,
                                             RTLIB::LLROUND_F128,
                                             RTLIB::LLROUND_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatOp_LRINT(SDNode *N) {
  EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
  return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
                                             RTLIB::LRINT_F32,
                                             RTLIB::LRINT_F64,
                                             RTLIB::LRINT_F80,
                                             RTLIB::LRINT_F128,
                                             RTLIB::LRINT_PPCF128));
}

SDValue DAGTypeLegalizer::SoftenFloatOp_LLRINT(SDNode *N) {
  EVT OpVT = N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType();
  return SoftenFloatOp_Unary(N, GetFPLibCall(OpVT,
                                             RTLIB::LLRINT_F32,
                                             RTLIB::LLRINT_F64,
                                             RTLIB::LLRINT_F80,
                                             RTLIB::LLRINT_F128,
                                             RTLIB::LLRINT_PPCF128));
}

//===----------------------------------------------------------------------===//
//  Float Result Expansion
//===----------------------------------------------------------------------===//

/// ExpandFloatResult - This method is called when the specified result of the
/// specified node is found to need expansion.  At this point, the node may also
/// have invalid operands or may have other results that need promotion, we just
/// know that (at least) one result needs expansion.
void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
  LLVM_DEBUG(dbgs() << "Expand float result: "; N->dump(&DAG); dbgs() << "\n");
  SDValue Lo, Hi;
  Lo = Hi = SDValue();

  // See if the target wants to custom expand this node.
  if (CustomLowerNode(N, N->getValueType(ResNo), true))
    return;

  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "ExpandFloatResult #" << ResNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
#endif
    llvm_unreachable("Do not know how to expand the result of this operator!");

  case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
  case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
  case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;

  case ISD::MERGE_VALUES:       ExpandRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
  case ISD::BITCAST:            ExpandRes_BITCAST(N, Lo, Hi); break;
  case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
  case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
  case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
  case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;

  case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break;
  case ISD::FABS:       ExpandFloatRes_FABS(N, Lo, Hi); break;
  case ISD::STRICT_FMINNUM:
  case ISD::FMINNUM:    ExpandFloatRes_FMINNUM(N, Lo, Hi); break;
  case ISD::STRICT_FMAXNUM:
  case ISD::FMAXNUM:    ExpandFloatRes_FMAXNUM(N, Lo, Hi); break;
  case ISD::STRICT_FADD:
  case ISD::FADD:       ExpandFloatRes_FADD(N, Lo, Hi); break;
  case ISD::FCBRT:      ExpandFloatRes_FCBRT(N, Lo, Hi); break;
  case ISD::STRICT_FCEIL:
  case ISD::FCEIL:      ExpandFloatRes_FCEIL(N, Lo, Hi); break;
  case ISD::FCOPYSIGN:  ExpandFloatRes_FCOPYSIGN(N, Lo, Hi); break;
  case ISD::STRICT_FCOS:
  case ISD::FCOS:       ExpandFloatRes_FCOS(N, Lo, Hi); break;
  case ISD::STRICT_FDIV:
  case ISD::FDIV:       ExpandFloatRes_FDIV(N, Lo, Hi); break;
  case ISD::STRICT_FEXP:
  case ISD::FEXP:       ExpandFloatRes_FEXP(N, Lo, Hi); break;
  case ISD::STRICT_FEXP2:
  case ISD::FEXP2:      ExpandFloatRes_FEXP2(N, Lo, Hi); break;
  case ISD::STRICT_FFLOOR:
  case ISD::FFLOOR:     ExpandFloatRes_FFLOOR(N, Lo, Hi); break;
  case ISD::STRICT_FLOG:
  case ISD::FLOG:       ExpandFloatRes_FLOG(N, Lo, Hi); break;
  case ISD::STRICT_FLOG2:
  case ISD::FLOG2:      ExpandFloatRes_FLOG2(N, Lo, Hi); break;
  case ISD::STRICT_FLOG10:
  case ISD::FLOG10:     ExpandFloatRes_FLOG10(N, Lo, Hi); break;
  case ISD::STRICT_FMA:
  case ISD::FMA:        ExpandFloatRes_FMA(N, Lo, Hi); break;
  case ISD::STRICT_FMUL:
  case ISD::FMUL:       ExpandFloatRes_FMUL(N, Lo, Hi); break;
  case ISD::STRICT_FNEARBYINT:
  case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break;
  case ISD::FNEG:       ExpandFloatRes_FNEG(N, Lo, Hi); break;
  case ISD::STRICT_FP_EXTEND:
  case ISD::FP_EXTEND:  ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
  case ISD::STRICT_FPOW:
  case ISD::FPOW:       ExpandFloatRes_FPOW(N, Lo, Hi); break;
  case ISD::STRICT_FPOWI:
  case ISD::FPOWI:      ExpandFloatRes_FPOWI(N, Lo, Hi); break;
  case ISD::FREEZE:     ExpandFloatRes_FREEZE(N, Lo, Hi); break;
  case ISD::STRICT_FRINT:
  case ISD::FRINT:      ExpandFloatRes_FRINT(N, Lo, Hi); break;
  case ISD::STRICT_FROUND:
  case ISD::FROUND:     ExpandFloatRes_FROUND(N, Lo, Hi); break;
  case ISD::STRICT_FROUNDEVEN:
  case ISD::FROUNDEVEN: ExpandFloatRes_FROUNDEVEN(N, Lo, Hi); break;
  case ISD::STRICT_FSIN:
  case ISD::FSIN:       ExpandFloatRes_FSIN(N, Lo, Hi); break;
  case ISD::STRICT_FSQRT:
  case ISD::FSQRT:      ExpandFloatRes_FSQRT(N, Lo, Hi); break;
  case ISD::STRICT_FSUB:
  case ISD::FSUB:       ExpandFloatRes_FSUB(N, Lo, Hi); break;
  case ISD::STRICT_FTRUNC:
  case ISD::FTRUNC:     ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
  case ISD::LOAD:       ExpandFloatRes_LOAD(N, Lo, Hi); break;
  case ISD::STRICT_SINT_TO_FP:
  case ISD::STRICT_UINT_TO_FP:
  case ISD::SINT_TO_FP:
  case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
  case ISD::STRICT_FREM:
  case ISD::FREM:       ExpandFloatRes_FREM(N, Lo, Hi); break;
  }

  // If Lo/Hi is null, the sub-method took care of registering results etc.
  if (Lo.getNode())
    SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
                                                 SDValue &Hi) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  assert(NVT.getSizeInBits() == 64 &&
         "Do not know how to expand this float constant!");
  APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
  SDLoc dl(N);
  Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                 APInt(64, C.getRawData()[1])),
                         dl, NVT);
  Hi = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                 APInt(64, C.getRawData()[0])),
                         dl, NVT);
}

void DAGTypeLegalizer::ExpandFloatRes_Unary(SDNode *N, RTLIB::Libcall LC,
                                            SDValue &Lo, SDValue &Hi) {
  bool IsStrict = N->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  SDValue Op = N->getOperand(0 + Offset);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
                                                    Op, CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  GetPairElements(Tmp.first, Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC,
                                             SDValue &Lo, SDValue &Hi) {
  bool IsStrict = N->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  SDValue Ops[] = { N->getOperand(0 + Offset), N->getOperand(1 + Offset) };
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
                                                    Ops, CallOptions, SDLoc(N),
                                                    Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  GetPairElements(Tmp.first, Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  assert(N->getValueType(0) == MVT::ppcf128 &&
         "Logic only correct for ppcf128!");
  SDLoc dl(N);
  SDValue Tmp;
  GetExpandedFloat(N->getOperand(0), Lo, Tmp);
  Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp);
  // Lo = Hi==fabs(Hi) ? Lo : -Lo;
  Lo = DAG.getSelectCC(dl, Tmp, Hi, Lo,
                   DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo),
                   ISD::SETEQ);
}

void DAGTypeLegalizer::ExpandFloatRes_FMINNUM(SDNode *N, SDValue &Lo,
                                              SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::FMIN_F32, RTLIB::FMIN_F64,
                                       RTLIB::FMIN_F80, RTLIB::FMIN_F128,
                                       RTLIB::FMIN_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FMAXNUM(SDNode *N, SDValue &Lo,
                                              SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::FMAX_F32, RTLIB::FMAX_F64,
                                        RTLIB::FMAX_F80, RTLIB::FMAX_F128,
                                        RTLIB::FMAX_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::ADD_F32, RTLIB::ADD_F64,
                                        RTLIB::ADD_F80, RTLIB::ADD_F128,
                                        RTLIB::ADD_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FCBRT(SDNode *N, SDValue &Lo,
                                            SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0), RTLIB::CBRT_F32,
                                       RTLIB::CBRT_F64, RTLIB::CBRT_F80,
                                       RTLIB::CBRT_F128,
                                       RTLIB::CBRT_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::CEIL_F32, RTLIB::CEIL_F64,
                                       RTLIB::CEIL_F80, RTLIB::CEIL_F128,
                                       RTLIB::CEIL_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(SDNode *N,
                                                SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::COPYSIGN_F32,
                                        RTLIB::COPYSIGN_F64,
                                        RTLIB::COPYSIGN_F80,
                                        RTLIB::COPYSIGN_F128,
                                        RTLIB::COPYSIGN_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::COS_F32, RTLIB::COS_F64,
                                       RTLIB::COS_F80, RTLIB::COS_F128,
                                       RTLIB::COS_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::DIV_F32,
                                        RTLIB::DIV_F64,
                                        RTLIB::DIV_F80,
                                        RTLIB::DIV_F128,
                                        RTLIB::DIV_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::EXP_F32, RTLIB::EXP_F64,
                                       RTLIB::EXP_F80, RTLIB::EXP_F128,
                                       RTLIB::EXP_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::EXP2_F32, RTLIB::EXP2_F64,
                                       RTLIB::EXP2_F80, RTLIB::EXP2_F128,
                                       RTLIB::EXP2_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
                                       RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
                                       RTLIB::FLOOR_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::LOG_F32, RTLIB::LOG_F64,
                                       RTLIB::LOG_F80, RTLIB::LOG_F128,
                                       RTLIB::LOG_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::LOG2_F32, RTLIB::LOG2_F64,
                                       RTLIB::LOG2_F80, RTLIB::LOG2_F128,
                                       RTLIB::LOG2_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::LOG10_F32, RTLIB::LOG10_F64,
                                       RTLIB::LOG10_F80, RTLIB::LOG10_F128,
                                       RTLIB::LOG10_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode *N, SDValue &Lo,
                                          SDValue &Hi) {
  bool IsStrict = N->isStrictFPOpcode();
  unsigned Offset = IsStrict ? 1 : 0;
  SDValue Ops[3] = { N->getOperand(0 + Offset), N->getOperand(1 + Offset),
                     N->getOperand(2 + Offset) };
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  TargetLowering::MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, GetFPLibCall(N->getValueType(0),
                                                   RTLIB::FMA_F32,
                                                   RTLIB::FMA_F64,
                                                   RTLIB::FMA_F80,
                                                   RTLIB::FMA_F128,
                                                   RTLIB::FMA_PPCF128),
                                 N->getValueType(0), Ops, CallOptions,
                                 SDLoc(N), Chain);
  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Tmp.second);
  GetPairElements(Tmp.first, Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                                   RTLIB::MUL_F32,
                                                   RTLIB::MUL_F64,
                                                   RTLIB::MUL_F80,
                                                   RTLIB::MUL_F128,
                                                   RTLIB::MUL_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
                                                 SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::NEARBYINT_F32,
                                       RTLIB::NEARBYINT_F64,
                                       RTLIB::NEARBYINT_F80,
                                       RTLIB::NEARBYINT_F128,
                                       RTLIB::NEARBYINT_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  SDLoc dl(N);
  GetExpandedFloat(N->getOperand(0), Lo, Hi);
  Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo);
  Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
                                                SDValue &Hi) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDLoc dl(N);
  bool IsStrict = N->isStrictFPOpcode();

  SDValue Chain;
  if (IsStrict) {
    // If the expanded type is the same as the input type, just bypass the node.
    if (NVT == N->getOperand(1).getValueType()) {
      Hi = N->getOperand(1);
      Chain = N->getOperand(0);
    } else {
      // Other we need to extend.
      Hi = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, { NVT, MVT::Other },
                       { N->getOperand(0), N->getOperand(1) });
      Chain = Hi.getValue(1);
    }
  } else {
    Hi = DAG.getNode(ISD::FP_EXTEND, dl, NVT, N->getOperand(0));
  }

  Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                 APInt(NVT.getSizeInBits(), 0)), dl, NVT);

  if (IsStrict)
    ReplaceValueWith(SDValue(N, 1), Chain);
}

void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::POW_F32, RTLIB::POW_F64,
                                        RTLIB::POW_F80, RTLIB::POW_F128,
                                        RTLIB::POW_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::POWI_F32, RTLIB::POWI_F64,
                                        RTLIB::POWI_F80, RTLIB::POWI_F128,
                                        RTLIB::POWI_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FREEZE(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  assert(N->getValueType(0) == MVT::ppcf128 &&
         "Logic only correct for ppcf128!");

  SDLoc dl(N);
  GetExpandedFloat(N->getOperand(0), Lo, Hi);
  Lo = DAG.getNode(ISD::FREEZE, dl, Lo.getValueType(), Lo);
  Hi = DAG.getNode(ISD::FREEZE, dl, Hi.getValueType(), Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FREM(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::REM_F32, RTLIB::REM_F64,
                                        RTLIB::REM_F80, RTLIB::REM_F128,
                                        RTLIB::REM_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::RINT_F32, RTLIB::RINT_F64,
                                       RTLIB::RINT_F80, RTLIB::RINT_F128,
                                       RTLIB::RINT_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FROUND(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::ROUND_F32,
                                       RTLIB::ROUND_F64,
                                       RTLIB::ROUND_F80,
                                       RTLIB::ROUND_F128,
                                       RTLIB::ROUND_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::ROUNDEVEN_F32,
                                       RTLIB::ROUNDEVEN_F64,
                                       RTLIB::ROUNDEVEN_F80,
                                       RTLIB::ROUNDEVEN_F128,
                                       RTLIB::ROUNDEVEN_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N,
                                           SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::SIN_F32, RTLIB::SIN_F64,
                                       RTLIB::SIN_F80, RTLIB::SIN_F128,
                                       RTLIB::SIN_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N,
                                            SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::SQRT_F32, RTLIB::SQRT_F64,
                                       RTLIB::SQRT_F80, RTLIB::SQRT_F128,
                                       RTLIB::SQRT_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  ExpandFloatRes_Binary(N, GetFPLibCall(N->getValueType(0),
                                        RTLIB::SUB_F32,
                                        RTLIB::SUB_F64,
                                        RTLIB::SUB_F80,
                                        RTLIB::SUB_F128,
                                        RTLIB::SUB_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N,
                                             SDValue &Lo, SDValue &Hi) {
  ExpandFloatRes_Unary(N, GetFPLibCall(N->getValueType(0),
                                       RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
                                       RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
                                       RTLIB::TRUNC_PPCF128), Lo, Hi);
}

void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
                                           SDValue &Hi) {
  if (ISD::isNormalLoad(N)) {
    ExpandRes_NormalLoad(N, Lo, Hi);
    return;
  }

  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
  LoadSDNode *LD = cast<LoadSDNode>(N);
  SDValue Chain = LD->getChain();
  SDValue Ptr = LD->getBasePtr();
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
  assert(NVT.isByteSized() && "Expanded type not byte sized!");
  assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");

  Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
                      LD->getMemoryVT(), LD->getMemOperand());

  // Remember the chain.
  Chain = Hi.getValue(1);

  // The low part is zero.
  Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                 APInt(NVT.getSizeInBits(), 0)), dl, NVT);

  // Modified the chain - switch anything that used the old chain to use the
  // new one.
  ReplaceValueWith(SDValue(LD, 1), Chain);
}

void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
                                                 SDValue &Hi) {
  assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  bool Strict = N->isStrictFPOpcode();
  SDValue Src = N->getOperand(Strict ? 1 : 0);
  EVT SrcVT = Src.getValueType();
  bool isSigned = N->getOpcode() == ISD::SINT_TO_FP ||
                  N->getOpcode() == ISD::STRICT_SINT_TO_FP;
  SDLoc dl(N);
  SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();

  // TODO: Any other flags to propagate?
  SDNodeFlags Flags;
  Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());

  // First do an SINT_TO_FP, whether the original was signed or unsigned.
  // When promoting partial word types to i32 we must honor the signedness,
  // though.
  if (SrcVT.bitsLE(MVT::i32)) {
    // The integer can be represented exactly in an f64.
    Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
                                   APInt(NVT.getSizeInBits(), 0)), dl, NVT);
    if (Strict) {
      Hi = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
                       {Chain, Src}, Flags);
      Chain = Hi.getValue(1);
    } else
      Hi = DAG.getNode(N->getOpcode(), dl, NVT, Src);
  } else {
    RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
    if (SrcVT.bitsLE(MVT::i64)) {
      Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
                        MVT::i64, Src);
      LC = RTLIB::SINTTOFP_I64_PPCF128;
    } else if (SrcVT.bitsLE(MVT::i128)) {
      Src = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i128, Src);
      LC = RTLIB::SINTTOFP_I128_PPCF128;
    }
    assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");

    TargetLowering::MakeLibCallOptions CallOptions;
    CallOptions.setSExt(true);
    std::pair<SDValue, SDValue> Tmp =
        TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
    if (Strict)
      Chain = Tmp.second;
    GetPairElements(Tmp.first, Lo, Hi);
  }

  // No need to complement for unsigned 32-bit integers
  if (isSigned || SrcVT.bitsLE(MVT::i32)) {
    if (Strict)
      ReplaceValueWith(SDValue(N, 1), Chain);

    return;
  }

  // Unsigned - fix up the SINT_TO_FP value just calculated.
  // FIXME: For unsigned i128 to ppc_fp128 conversion, we need to carefully
  // keep semantics correctness if the integer is not exactly representable
  // here. See ExpandLegalINT_TO_FP.
  Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
  SrcVT = Src.getValueType();

  // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
  static const uint64_t TwoE32[]  = { 0x41f0000000000000LL, 0 };
  static const uint64_t TwoE64[]  = { 0x43f0000000000000LL, 0 };
  static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
  ArrayRef<uint64_t> Parts;

  switch (SrcVT.getSimpleVT().SimpleTy) {
  default:
    llvm_unreachable("Unsupported UINT_TO_FP!");
  case MVT::i32:
    Parts = TwoE32;
    break;
  case MVT::i64:
    Parts = TwoE64;
    break;
  case MVT::i128:
    Parts = TwoE128;
    break;
  }

  // TODO: Are there other fast-math-flags to propagate to this FADD?
  SDValue NewLo = DAG.getConstantFP(
      APFloat(APFloat::PPCDoubleDouble(), APInt(128, Parts)), dl, MVT::ppcf128);
  if (Strict) {
    Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
                     {Chain, Hi, NewLo}, Flags);
    Chain = Lo.getValue(1);
    ReplaceValueWith(SDValue(N, 1), Chain);
  } else
    Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, NewLo);
  Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
                       Lo, Hi, ISD::SETLT);
  GetPairElements(Lo, Lo, Hi);
}


//===----------------------------------------------------------------------===//
//  Float Operand Expansion
//===----------------------------------------------------------------------===//

/// ExpandFloatOperand - This method is called when the specified operand of the
/// specified node is found to need expansion.  At this point, all of the result
/// types of the node are known to be legal, but other operands of the node may
/// need promotion or expansion as well as the specified one.
bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
  LLVM_DEBUG(dbgs() << "Expand float operand: "; N->dump(&DAG); dbgs() << "\n");
  SDValue Res = SDValue();

  // See if the target wants to custom expand this node.
  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
    return false;

  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "ExpandFloatOperand Op #" << OpNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
#endif
    llvm_unreachable("Do not know how to expand this operator's operand!");

  case ISD::BITCAST:         Res = ExpandOp_BITCAST(N); break;
  case ISD::BUILD_VECTOR:    Res = ExpandOp_BUILD_VECTOR(N); break;
  case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;

  case ISD::BR_CC:      Res = ExpandFloatOp_BR_CC(N); break;
  case ISD::FCOPYSIGN:  Res = ExpandFloatOp_FCOPYSIGN(N); break;
  case ISD::STRICT_FP_ROUND:
  case ISD::FP_ROUND:   Res = ExpandFloatOp_FP_ROUND(N); break;
  case ISD::STRICT_FP_TO_SINT:
  case ISD::STRICT_FP_TO_UINT:
  case ISD::FP_TO_SINT:
  case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_XINT(N); break;
  case ISD::LROUND:     Res = ExpandFloatOp_LROUND(N); break;
  case ISD::LLROUND:    Res = ExpandFloatOp_LLROUND(N); break;
  case ISD::LRINT:      Res = ExpandFloatOp_LRINT(N); break;
  case ISD::LLRINT:     Res = ExpandFloatOp_LLRINT(N); break;
  case ISD::SELECT_CC:  Res = ExpandFloatOp_SELECT_CC(N); break;
  case ISD::STRICT_FSETCC:
  case ISD::STRICT_FSETCCS:
  case ISD::SETCC:      Res = ExpandFloatOp_SETCC(N); break;
  case ISD::STORE:      Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
                                                  OpNo); break;
  }

  // If the result is null, the sub-method took care of registering results etc.
  if (!Res.getNode()) return false;

  // If the result is N, the sub-method updated N in place.  Tell the legalizer
  // core about this.
  if (Res.getNode() == N)
    return true;

  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
         "Invalid operand expansion");

  ReplaceValueWith(SDValue(N, 0), Res);
  return false;
}

/// FloatExpandSetCCOperands - Expand the operands of a comparison.  This code
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
                                                SDValue &NewRHS,
                                                ISD::CondCode &CCCode,
                                                const SDLoc &dl, SDValue &Chain,
                                                bool IsSignaling) {
  SDValue LHSLo, LHSHi, RHSLo, RHSHi;
  GetExpandedFloat(NewLHS, LHSLo, LHSHi);
  GetExpandedFloat(NewRHS, RHSLo, RHSHi);

  assert(NewLHS.getValueType() == MVT::ppcf128 && "Unsupported setcc type!");

  // FIXME:  This generated code sucks.  We want to generate
  //         FCMPU crN, hi1, hi2
  //         BNE crN, L:
  //         FCMPU crN, lo1, lo2
  // The following can be improved, but not that much.
  SDValue Tmp1, Tmp2, Tmp3, OutputChain;
  Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
                      RHSHi, ISD::SETOEQ, Chain, IsSignaling);
  OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
  Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.getValueType()), LHSLo,
                      RHSLo, CCCode, OutputChain, IsSignaling);
  OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
  Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
  Tmp1 =
      DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,
                   ISD::SETUNE, OutputChain, IsSignaling);
  OutputChain = Tmp1->getNumValues() > 1 ? Tmp1.getValue(1) : SDValue();
  Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.getValueType()), LHSHi,
                      RHSHi, CCCode, OutputChain, IsSignaling);
  OutputChain = Tmp2->getNumValues() > 1 ? Tmp2.getValue(1) : SDValue();
  Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
  NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
  NewRHS = SDValue();   // LHS is the result, not a compare.
  Chain = OutputChain;
}

SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
  SDValue Chain;
  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);

  // If ExpandSetCCOperands returned a scalar, we need to compare the result
  // against zero to select between true and false values.
  if (!NewRHS.getNode()) {
    NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
    CCCode = ISD::SETNE;
  }

  // Update N to have the operands specified.
  return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0),
                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
                                N->getOperand(4)), 0);
}

SDValue DAGTypeLegalizer::ExpandFloatOp_FCOPYSIGN(SDNode *N) {
  assert(N->getOperand(1).getValueType() == MVT::ppcf128 &&
         "Logic only correct for ppcf128!");
  SDValue Lo, Hi;
  GetExpandedFloat(N->getOperand(1), Lo, Hi);
  // The ppcf128 value is providing only the sign; take it from the
  // higher-order double (which must have the larger magnitude).
  return DAG.getNode(ISD::FCOPYSIGN, SDLoc(N),
                     N->getValueType(0), N->getOperand(0), Hi);
}

SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  assert(N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
         "Logic only correct for ppcf128!");
  SDValue Lo, Hi;
  GetExpandedFloat(N->getOperand(IsStrict ? 1 : 0), Lo, Hi);

  if (!IsStrict)
    // Round it the rest of the way (e.g. to f32) if needed.
    return DAG.getNode(ISD::FP_ROUND, SDLoc(N),
                       N->getValueType(0), Hi, N->getOperand(1));

  // Eliminate the node if the input float type is the same as the output float
  // type.
  if (Hi.getValueType() == N->getValueType(0)) {
    // Connect the output chain to the input chain, unlinking the node.
    ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
    ReplaceValueWith(SDValue(N, 0), Hi);
    return SDValue();
  }

  SDValue Expansion = DAG.getNode(ISD::STRICT_FP_ROUND, SDLoc(N),
                                  {N->getValueType(0), MVT::Other},
                                  {N->getOperand(0), Hi, N->getOperand(2)});
  ReplaceValueWith(SDValue(N, 1), Expansion.getValue(1));
  ReplaceValueWith(SDValue(N, 0), Expansion);
  return SDValue();
}

SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
  EVT RVT = N->getValueType(0);
  SDLoc dl(N);

  bool IsStrict = N->isStrictFPOpcode();
  bool Signed = N->getOpcode() == ISD::FP_TO_SINT ||
                N->getOpcode() == ISD::STRICT_FP_TO_SINT;
  SDValue Op = N->getOperand(IsStrict ? 1 : 0);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();

  EVT NVT;
  RTLIB::Libcall LC = findFPToIntLibcall(Op.getValueType(), RVT, NVT, Signed);
  assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
         "Unsupported FP_TO_XINT!");
  TargetLowering::MakeLibCallOptions CallOptions;
  std::pair<SDValue, SDValue> Tmp =
      TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
  if (!IsStrict)
    return Tmp.first;

  ReplaceValueWith(SDValue(N, 1), Tmp.second);
  ReplaceValueWith(SDValue(N, 0), Tmp.first);
  return SDValue();
}

SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
  SDValue Chain;
  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain);

  // If ExpandSetCCOperands returned a scalar, we need to compare the result
  // against zero to select between true and false values.
  if (!NewRHS.getNode()) {
    NewRHS = DAG.getConstant(0, SDLoc(N), NewLHS.getValueType());
    CCCode = ISD::SETNE;
  }

  // Update N to have the operands specified.
  return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS,
                                N->getOperand(2), N->getOperand(3),
                                DAG.getCondCode(CCCode)), 0);
}

SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  SDValue NewLHS = N->getOperand(IsStrict ? 1 : 0);
  SDValue NewRHS = N->getOperand(IsStrict ? 2 : 1);
  SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
  ISD::CondCode CCCode =
      cast<CondCodeSDNode>(N->getOperand(IsStrict ? 3 : 2))->get();
  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(N), Chain,
                           N->getOpcode() == ISD::STRICT_FSETCCS);

  // FloatExpandSetCCOperands always returned a scalar.
  assert(!NewRHS.getNode() && "Expect to return scalar");
  assert(NewLHS.getValueType() == N->getValueType(0) &&
         "Unexpected setcc expansion!");
  if (Chain) {
    ReplaceValueWith(SDValue(N, 0), NewLHS);
    ReplaceValueWith(SDValue(N, 1), Chain);
    return SDValue();
  }
  return NewLHS;
}

SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
  if (ISD::isNormalStore(N))
    return ExpandOp_NormalStore(N, OpNo);

  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
  assert(OpNo == 1 && "Can only expand the stored value so far");
  StoreSDNode *ST = cast<StoreSDNode>(N);

  SDValue Chain = ST->getChain();
  SDValue Ptr = ST->getBasePtr();

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
                                     ST->getValue().getValueType());
  assert(NVT.isByteSized() && "Expanded type not byte sized!");
  assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
  (void)NVT;

  SDValue Lo, Hi;
  GetExpandedOp(ST->getValue(), Lo, Hi);

  return DAG.getTruncStore(Chain, SDLoc(N), Hi, Ptr,
                           ST->getMemoryVT(), ST->getMemOperand());
}

SDValue DAGTypeLegalizer::ExpandFloatOp_LROUND(SDNode *N) {
  EVT RVT = N->getValueType(0);
  EVT RetVT = N->getOperand(0).getValueType();
  TargetLowering::MakeLibCallOptions CallOptions;
  return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
                                           RTLIB::LROUND_F32,
                                           RTLIB::LROUND_F64,
                                           RTLIB::LROUND_F80,
                                           RTLIB::LROUND_F128,
                                           RTLIB::LROUND_PPCF128),
                         RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
}

SDValue DAGTypeLegalizer::ExpandFloatOp_LLROUND(SDNode *N) {
  EVT RVT = N->getValueType(0);
  EVT RetVT = N->getOperand(0).getValueType();
  TargetLowering::MakeLibCallOptions CallOptions;
  return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
                                           RTLIB::LLROUND_F32,
                                           RTLIB::LLROUND_F64,
                                           RTLIB::LLROUND_F80,
                                           RTLIB::LLROUND_F128,
                                           RTLIB::LLROUND_PPCF128),
                         RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
}

SDValue DAGTypeLegalizer::ExpandFloatOp_LRINT(SDNode *N) {
  EVT RVT = N->getValueType(0);
  EVT RetVT = N->getOperand(0).getValueType();
  TargetLowering::MakeLibCallOptions CallOptions;
  return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
                                           RTLIB::LRINT_F32,
                                           RTLIB::LRINT_F64,
                                           RTLIB::LRINT_F80,
                                           RTLIB::LRINT_F128,
                                           RTLIB::LRINT_PPCF128),
                         RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
}

SDValue DAGTypeLegalizer::ExpandFloatOp_LLRINT(SDNode *N) {
  EVT RVT = N->getValueType(0);
  EVT RetVT = N->getOperand(0).getValueType();
  TargetLowering::MakeLibCallOptions CallOptions;
  return TLI.makeLibCall(DAG, GetFPLibCall(RetVT,
                                           RTLIB::LLRINT_F32,
                                           RTLIB::LLRINT_F64,
                                           RTLIB::LLRINT_F80,
                                           RTLIB::LLRINT_F128,
                                           RTLIB::LLRINT_PPCF128),
                         RVT, N->getOperand(0), CallOptions, SDLoc(N)).first;
}

//===----------------------------------------------------------------------===//
//  Float Operand Promotion
//===----------------------------------------------------------------------===//
//

static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT) {
  if (OpVT == MVT::f16) {
      return ISD::FP16_TO_FP;
  } else if (RetVT == MVT::f16) {
      return ISD::FP_TO_FP16;
  }

  report_fatal_error("Attempt at an invalid promotion-related conversion");
}

bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
  LLVM_DEBUG(dbgs() << "Promote float operand " << OpNo << ": "; N->dump(&DAG);
             dbgs() << "\n");
  SDValue R = SDValue();

  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
    LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
    return false;
  }

  // Nodes that use a promotion-requiring floating point operand, but doesn't
  // produce a promotion-requiring floating point result, need to be legalized
  // to use the promoted float operand.  Nodes that produce at least one
  // promotion-requiring floating point result have their operands legalized as
  // a part of PromoteFloatResult.
  switch (N->getOpcode()) {
    default:
  #ifndef NDEBUG
      dbgs() << "PromoteFloatOperand Op #" << OpNo << ": ";
      N->dump(&DAG); dbgs() << "\n";
  #endif
      llvm_unreachable("Do not know how to promote this operator's operand!");

    case ISD::BITCAST:    R = PromoteFloatOp_BITCAST(N, OpNo); break;
    case ISD::FCOPYSIGN:  R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break;
    case ISD::FP_TO_SINT:
    case ISD::FP_TO_UINT: R = PromoteFloatOp_FP_TO_XINT(N, OpNo); break;
    case ISD::FP_TO_SINT_SAT:
    case ISD::FP_TO_UINT_SAT:
                          R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break;
    case ISD::FP_EXTEND:  R = PromoteFloatOp_FP_EXTEND(N, OpNo); break;
    case ISD::SELECT_CC:  R = PromoteFloatOp_SELECT_CC(N, OpNo); break;
    case ISD::SETCC:      R = PromoteFloatOp_SETCC(N, OpNo); break;
    case ISD::STORE:      R = PromoteFloatOp_STORE(N, OpNo); break;
  }

  if (R.getNode())
    ReplaceValueWith(SDValue(N, 0), R);
  return false;
}

SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(SDNode *N, unsigned OpNo) {
  SDValue Op = N->getOperand(0);
  EVT OpVT = Op->getValueType(0);

  SDValue Promoted = GetPromotedFloat(N->getOperand(0));
  EVT PromotedVT = Promoted->getValueType(0);

  // Convert the promoted float value to the desired IVT.
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), OpVT.getSizeInBits());
  SDValue Convert = DAG.getNode(GetPromotionOpcode(PromotedVT, OpVT), SDLoc(N),
                                IVT, Promoted);
  // The final result type might not be an scalar so we need a bitcast. The
  // bitcast will be further legalized if needed.
  return DAG.getBitcast(N->getValueType(0), Convert);
}

// Promote Operand 1 of FCOPYSIGN.  Operand 0 ought to be handled by
// PromoteFloatRes_FCOPYSIGN.
SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo) {
  assert (OpNo == 1 && "Only Operand 1 must need promotion here");
  SDValue Op1 = GetPromotedFloat(N->getOperand(1));

  return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0),
                     N->getOperand(0), Op1);
}

// Convert the promoted float value to the desired integer type
SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT(SDNode *N, unsigned OpNo) {
  SDValue Op = GetPromotedFloat(N->getOperand(0));
  return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op);
}

SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N,
                                                        unsigned OpNo) {
  SDValue Op = GetPromotedFloat(N->getOperand(0));
  return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op,
                     N->getOperand(1));
}

SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) {
  SDValue Op = GetPromotedFloat(N->getOperand(0));
  EVT VT = N->getValueType(0);

  // Desired VT is same as promoted type.  Use promoted float directly.
  if (VT == Op->getValueType(0))
    return Op;

  // Else, extend the promoted float value to the desired VT.
  return DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Op);
}

// Promote the float operands used for comparison.  The true- and false-
// operands have the same type as the result and are promoted, if needed, by
// PromoteFloatRes_SELECT_CC
SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo) {
  SDValue LHS = GetPromotedFloat(N->getOperand(0));
  SDValue RHS = GetPromotedFloat(N->getOperand(1));

  return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0),
                     LHS, RHS, N->getOperand(2), N->getOperand(3),
                     N->getOperand(4));
}

// Construct a SETCC that compares the promoted values and sets the conditional
// code.
SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo) {
  EVT VT = N->getValueType(0);
  SDValue Op0 = GetPromotedFloat(N->getOperand(0));
  SDValue Op1 = GetPromotedFloat(N->getOperand(1));
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();

  return DAG.getSetCC(SDLoc(N), VT, Op0, Op1, CCCode);

}

// Lower the promoted Float down to the integer value of same size and construct
// a STORE of the integer value.
SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(SDNode *N, unsigned OpNo) {
  StoreSDNode *ST = cast<StoreSDNode>(N);
  SDValue Val = ST->getValue();
  SDLoc DL(N);

  SDValue Promoted = GetPromotedFloat(Val);
  EVT VT = ST->getOperand(1).getValueType();
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());

  SDValue NewVal;
  NewVal = DAG.getNode(GetPromotionOpcode(Promoted.getValueType(), VT), DL,
                       IVT, Promoted);

  return DAG.getStore(ST->getChain(), DL, NewVal, ST->getBasePtr(),
                      ST->getMemOperand());
}

//===----------------------------------------------------------------------===//
//  Float Result Promotion
//===----------------------------------------------------------------------===//

void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
  LLVM_DEBUG(dbgs() << "Promote float result " << ResNo << ": "; N->dump(&DAG);
             dbgs() << "\n");
  SDValue R = SDValue();

  // See if the target wants to custom expand this node.
  if (CustomLowerNode(N, N->getValueType(ResNo), true)) {
    LLVM_DEBUG(dbgs() << "Node has been custom expanded, done\n");
    return;
  }

  switch (N->getOpcode()) {
    // These opcodes cannot appear if promotion of FP16 is done in the backend
    // instead of Clang
    case ISD::FP16_TO_FP:
    case ISD::FP_TO_FP16:
    default:
#ifndef NDEBUG
      dbgs() << "PromoteFloatResult #" << ResNo << ": ";
      N->dump(&DAG); dbgs() << "\n";
#endif
      llvm_unreachable("Do not know how to promote this operator's result!");

    case ISD::BITCAST:    R = PromoteFloatRes_BITCAST(N); break;
    case ISD::ConstantFP: R = PromoteFloatRes_ConstantFP(N); break;
    case ISD::EXTRACT_VECTOR_ELT:
                          R = PromoteFloatRes_EXTRACT_VECTOR_ELT(N); break;
    case ISD::FCOPYSIGN:  R = PromoteFloatRes_FCOPYSIGN(N); break;

    // Unary FP Operations
    case ISD::FABS:
    case ISD::FCBRT:
    case ISD::FCEIL:
    case ISD::FCOS:
    case ISD::FEXP:
    case ISD::FEXP2:
    case ISD::FFLOOR:
    case ISD::FLOG:
    case ISD::FLOG2:
    case ISD::FLOG10:
    case ISD::FNEARBYINT:
    case ISD::FNEG:
    case ISD::FRINT:
    case ISD::FROUND:
    case ISD::FROUNDEVEN:
    case ISD::FSIN:
    case ISD::FSQRT:
    case ISD::FTRUNC:
    case ISD::FCANONICALIZE: R = PromoteFloatRes_UnaryOp(N); break;

    // Binary FP Operations
    case ISD::FADD:
    case ISD::FDIV:
    case ISD::FMAXIMUM:
    case ISD::FMINIMUM:
    case ISD::FMAXNUM:
    case ISD::FMINNUM:
    case ISD::FMUL:
    case ISD::FPOW:
    case ISD::FREM:
    case ISD::FSUB:       R = PromoteFloatRes_BinOp(N); break;

    case ISD::FMA:        // FMA is same as FMAD
    case ISD::FMAD:       R = PromoteFloatRes_FMAD(N); break;

    case ISD::FPOWI:      R = PromoteFloatRes_FPOWI(N); break;

    case ISD::FP_ROUND:   R = PromoteFloatRes_FP_ROUND(N); break;
    case ISD::LOAD:       R = PromoteFloatRes_LOAD(N); break;
    case ISD::SELECT:     R = PromoteFloatRes_SELECT(N); break;
    case ISD::SELECT_CC:  R = PromoteFloatRes_SELECT_CC(N); break;

    case ISD::SINT_TO_FP:
    case ISD::UINT_TO_FP: R = PromoteFloatRes_XINT_TO_FP(N); break;
    case ISD::UNDEF:      R = PromoteFloatRes_UNDEF(N); break;
    case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
    case ISD::VECREDUCE_FADD:
    case ISD::VECREDUCE_FMUL:
    case ISD::VECREDUCE_FMIN:
    case ISD::VECREDUCE_FMAX:
      R = PromoteFloatRes_VECREDUCE(N);
      break;
    case ISD::VECREDUCE_SEQ_FADD:
    case ISD::VECREDUCE_SEQ_FMUL:
      R = PromoteFloatRes_VECREDUCE_SEQ(N);
      break;
  }

  if (R.getNode())
    SetPromotedFloat(SDValue(N, ResNo), R);
}

// Bitcast from i16 to f16:  convert the i16 to a f32 value instead.
// At this point, it is not possible to determine if the bitcast value is
// eventually stored to memory or promoted to f32 or promoted to a floating
// point at a higher precision.  Some of these cases are handled by FP_EXTEND,
// STORE promotion handlers.
SDValue DAGTypeLegalizer::PromoteFloatRes_BITCAST(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  // Input type isn't guaranteed to be a scalar int so bitcast if not. The
  // bitcast will be legalized further if necessary.
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(),
                              N->getOperand(0).getValueType().getSizeInBits());
  SDValue Cast = DAG.getBitcast(IVT, N->getOperand(0));
  return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, Cast);
}

SDValue DAGTypeLegalizer::PromoteFloatRes_ConstantFP(SDNode *N) {
  ConstantFPSDNode *CFPNode = cast<ConstantFPSDNode>(N);
  EVT VT = N->getValueType(0);
  SDLoc DL(N);

  // Get the (bit-cast) APInt of the APFloat and build an integer constant
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
  SDValue C = DAG.getConstant(CFPNode->getValueAPF().bitcastToAPInt(), DL,
                              IVT);

  // Convert the Constant to the desired FP type
  // FIXME We might be able to do the conversion during compilation and get rid
  // of it from the object code
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  return DAG.getNode(GetPromotionOpcode(VT, NVT), DL, NVT, C);
}

// If the Index operand is a constant, try to redirect the extract operation to
// the correct legalized vector.  If not, bit-convert the input vector to
// equivalent integer vector.  Extract the element as an (bit-cast) integer
// value and convert it to the promoted type.
SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) {
  SDLoc DL(N);

  // If the index is constant, try to extract the value from the legalized
  // vector type.
  if (isa<ConstantSDNode>(N->getOperand(1))) {
    SDValue Vec = N->getOperand(0);
    SDValue Idx = N->getOperand(1);
    EVT VecVT = Vec->getValueType(0);
    EVT EltVT = VecVT.getVectorElementType();

    uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();

    switch (getTypeAction(VecVT)) {
    default: break;
    case TargetLowering::TypeScalarizeVector: {
      SDValue Res = GetScalarizedVector(N->getOperand(0));
      ReplaceValueWith(SDValue(N, 0), Res);
      return SDValue();
    }
    case TargetLowering::TypeWidenVector: {
      Vec = GetWidenedVector(Vec);
      SDValue Res = DAG.getNode(N->getOpcode(), DL, EltVT, Vec, Idx);
      ReplaceValueWith(SDValue(N, 0), Res);
      return SDValue();
    }
    case TargetLowering::TypeSplitVector: {
      SDValue Lo, Hi;
      GetSplitVector(Vec, Lo, Hi);

      uint64_t LoElts = Lo.getValueType().getVectorNumElements();
      SDValue Res;
      if (IdxVal < LoElts)
        Res = DAG.getNode(N->getOpcode(), DL, EltVT, Lo, Idx);
      else
        Res = DAG.getNode(N->getOpcode(), DL, EltVT, Hi,
                          DAG.getConstant(IdxVal - LoElts, DL,
                                          Idx.getValueType()));
      ReplaceValueWith(SDValue(N, 0), Res);
      return SDValue();
    }

    }
  }

  // Bit-convert the input vector to the equivalent integer vector
  SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
  EVT IVT = NewOp.getValueType().getVectorElementType();

  // Extract the element as an (bit-cast) integer value
  SDValue NewVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, IVT,
                               NewOp, N->getOperand(1));

  // Convert the element to the desired FP type
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, NewVal);
}

// FCOPYSIGN(X, Y) returns the value of X with the sign of Y.  If the result
// needs promotion, so does the argument X.  Note that Y, if needed, will be
// handled during operand promotion.
SDValue DAGTypeLegalizer::PromoteFloatRes_FCOPYSIGN(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue Op0 = GetPromotedFloat(N->getOperand(0));

  SDValue Op1 = N->getOperand(1);

  return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1);
}

// Unary operation where the result and the operand have PromoteFloat type
// action.  Construct a new SDNode with the promoted float value of the old
// operand.
SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryOp(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue Op = GetPromotedFloat(N->getOperand(0));

  return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op);
}

// Binary operations where the result and both operands have PromoteFloat type
// action.  Construct a new SDNode with the promoted float values of the old
// operands.
SDValue DAGTypeLegalizer::PromoteFloatRes_BinOp(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue Op0 = GetPromotedFloat(N->getOperand(0));
  SDValue Op1 = GetPromotedFloat(N->getOperand(1));
  return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, N->getFlags());
}

SDValue DAGTypeLegalizer::PromoteFloatRes_FMAD(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue Op0 = GetPromotedFloat(N->getOperand(0));
  SDValue Op1 = GetPromotedFloat(N->getOperand(1));
  SDValue Op2 = GetPromotedFloat(N->getOperand(2));

  return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1, Op2);
}

// Promote the Float (first) operand and retain the Integer (second) operand
SDValue DAGTypeLegalizer::PromoteFloatRes_FPOWI(SDNode *N) {
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue Op0 = GetPromotedFloat(N->getOperand(0));
  SDValue Op1 = N->getOperand(1);

  return DAG.getNode(N->getOpcode(), SDLoc(N), NVT, Op0, Op1);
}

// Explicit operation to reduce precision.  Reduce the value to half precision
// and promote it back to the legal type.
SDValue DAGTypeLegalizer::PromoteFloatRes_FP_ROUND(SDNode *N) {
  SDLoc DL(N);

  SDValue Op = N->getOperand(0);
  EVT VT = N->getValueType(0);
  EVT OpVT = Op->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());

  // Round promoted float to desired precision
  SDValue Round = DAG.getNode(GetPromotionOpcode(OpVT, VT), DL, IVT, Op);
  // Promote it back to the legal output type
  return DAG.getNode(GetPromotionOpcode(VT, NVT), DL, NVT, Round);
}

SDValue DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) {
  LoadSDNode *L = cast<LoadSDNode>(N);
  EVT VT = N->getValueType(0);

  // Load the value as an integer value with the same number of bits.
  EVT IVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits());
  SDValue newL = DAG.getLoad(
      L->getAddressingMode(), L->getExtensionType(), IVT, SDLoc(N),
      L->getChain(), L->getBasePtr(), L->getOffset(), L->getPointerInfo(), IVT,
      L->getOriginalAlign(), L->getMemOperand()->getFlags(), L->getAAInfo());
  // Legalize the chain result by replacing uses of the old value chain with the
  // new one
  ReplaceValueWith(SDValue(N, 1), newL.getValue(1));

  // Convert the integer value to the desired FP type
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  return DAG.getNode(GetPromotionOpcode(VT, NVT), SDLoc(N), NVT, newL);
}

// Construct a new SELECT node with the promoted true- and false- values.
SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT(SDNode *N) {
  SDValue TrueVal = GetPromotedFloat(N->getOperand(1));
  SDValue FalseVal = GetPromotedFloat(N->getOperand(2));

  return DAG.getNode(ISD::SELECT, SDLoc(N), TrueVal->getValueType(0),
                     N->getOperand(0), TrueVal, FalseVal);
}

// Construct a new SELECT_CC node with the promoted true- and false- values.
// The operands used for comparison are promoted by PromoteFloatOp_SELECT_CC.
SDValue DAGTypeLegalizer::PromoteFloatRes_SELECT_CC(SDNode *N) {
  SDValue TrueVal = GetPromotedFloat(N->getOperand(2));
  SDValue FalseVal = GetPromotedFloat(N->getOperand(3));

  return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
                     TrueVal.getNode()->getValueType(0), N->getOperand(0),
                     N->getOperand(1), TrueVal, FalseVal, N->getOperand(4));
}

// Construct a SDNode that transforms the SINT or UINT operand to the promoted
// float type.
SDValue DAGTypeLegalizer::PromoteFloatRes_XINT_TO_FP(SDNode *N) {
  SDLoc DL(N);
  EVT VT = N->getValueType(0);
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
  SDValue NV = DAG.getNode(N->getOpcode(), DL, NVT, N->getOperand(0));
  // Round the value to the desired precision (that of the source type).
  return DAG.getNode(
      ISD::FP_EXTEND, DL, NVT,
      DAG.getNode(ISD::FP_ROUND, DL, VT, NV, DAG.getIntPtrConstant(0, DL)));
}

SDValue DAGTypeLegalizer::PromoteFloatRes_UNDEF(SDNode *N) {
  return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
                                               N->getValueType(0)));
}

SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE(SDNode *N) {
  // Expand and promote recursively.
  // TODO: This is non-optimal, but dealing with the concurrently happening
  // vector-legalization is non-trivial. We could do something similar to
  // PromoteFloatRes_EXTRACT_VECTOR_ELT here.
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
  return SDValue();
}

SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(SDNode *N) {
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
  return SDValue();
}

SDValue DAGTypeLegalizer::BitcastToInt_ATOMIC_SWAP(SDNode *N) {
  EVT VT = N->getValueType(0);

  AtomicSDNode *AM = cast<AtomicSDNode>(N);
  SDLoc SL(N);

  SDValue CastVal = BitConvertToInteger(AM->getVal());
  EVT CastVT = CastVal.getValueType();

  SDValue NewAtomic
    = DAG.getAtomic(ISD::ATOMIC_SWAP, SL, CastVT,
                    DAG.getVTList(CastVT, MVT::Other),
                    { AM->getChain(), AM->getBasePtr(), CastVal },
                    AM->getMemOperand());

  SDValue Result = NewAtomic;

  if (getTypeAction(VT) == TargetLowering::TypePromoteFloat) {
    EVT NFPVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
    Result = DAG.getNode(GetPromotionOpcode(VT, NFPVT), SL, NFPVT,
                                     NewAtomic);
  }

  // Legalize the chain result by replacing uses of the old value chain with the
  // new one
  ReplaceValueWith(SDValue(N, 1), NewAtomic.getValue(1));

  return Result;

}

//===----------------------------------------------------------------------===//
//  Half Result Soft Promotion
//===----------------------------------------------------------------------===//

void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
  LLVM_DEBUG(dbgs() << "Soft promote half result " << ResNo << ": ";
             N->dump(&DAG); dbgs() << "\n");
  SDValue R = SDValue();

  // See if the target wants to custom expand this node.
  if (CustomLowerNode(N, N->getValueType(ResNo), true)) {
    LLVM_DEBUG(dbgs() << "Node has been custom expanded, done\n");
    return;
  }

  switch (N->getOpcode()) {
  default:
#ifndef NDEBUG
    dbgs() << "SoftPromoteHalfResult #" << ResNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
#endif
    llvm_unreachable("Do not know how to soft promote this operator's result!");

  case ISD::BITCAST:    R = SoftPromoteHalfRes_BITCAST(N); break;
  case ISD::ConstantFP: R = SoftPromoteHalfRes_ConstantFP(N); break;
  case ISD::EXTRACT_VECTOR_ELT:
    R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(N); break;
  case ISD::FCOPYSIGN:  R = SoftPromoteHalfRes_FCOPYSIGN(N); break;
  case ISD::STRICT_FP_ROUND:
  case ISD::FP_ROUND:   R = SoftPromoteHalfRes_FP_ROUND(N); break;

  // Unary FP Operations
  case ISD::FABS:
  case ISD::FCBRT:
  case ISD::FCEIL:
  case ISD::FCOS:
  case ISD::FEXP:
  case ISD::FEXP2:
  case ISD::FFLOOR:
  case ISD::FLOG:
  case ISD::FLOG2:
  case ISD::FLOG10:
  case ISD::FNEARBYINT:
  case ISD::FNEG:
  case ISD::FREEZE:
  case ISD::FRINT:
  case ISD::FROUND:
  case ISD::FROUNDEVEN:
  case ISD::FSIN:
  case ISD::FSQRT:
  case ISD::FTRUNC:
  case ISD::FCANONICALIZE: R = SoftPromoteHalfRes_UnaryOp(N); break;

  // Binary FP Operations
  case ISD::FADD:
  case ISD::FDIV:
  case ISD::FMAXIMUM:
  case ISD::FMINIMUM:
  case ISD::FMAXNUM:
  case ISD::FMINNUM:
  case ISD::FMUL:
  case ISD::FPOW:
  case ISD::FREM:
  case ISD::FSUB:        R = SoftPromoteHalfRes_BinOp(N); break;

  case ISD::FMA:         // FMA is same as FMAD
  case ISD::FMAD:        R = SoftPromoteHalfRes_FMAD(N); break;

  case ISD::FPOWI:       R = SoftPromoteHalfRes_FPOWI(N); break;

  case ISD::LOAD:        R = SoftPromoteHalfRes_LOAD(N); break;
  case ISD::SELECT:      R = SoftPromoteHalfRes_SELECT(N); break;
  case ISD::SELECT_CC:   R = SoftPromoteHalfRes_SELECT_CC(N); break;
  case ISD::SINT_TO_FP:
  case ISD::UINT_TO_FP:  R = SoftPromoteHalfRes_XINT_TO_FP(N); break;
  case ISD::UNDEF:       R = SoftPromoteHalfRes_UNDEF(N); break;
  case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
  case ISD::VECREDUCE_FADD:
  case ISD::VECREDUCE_FMUL:
  case ISD::VECREDUCE_FMIN:
  case ISD::VECREDUCE_FMAX:
    R = SoftPromoteHalfRes_VECREDUCE(N);
    break;
  case ISD::VECREDUCE_SEQ_FADD:
  case ISD::VECREDUCE_SEQ_FMUL:
    R = SoftPromoteHalfRes_VECREDUCE_SEQ(N);
    break;
  }

  if (R.getNode())
    SetSoftPromotedHalf(SDValue(N, ResNo), R);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BITCAST(SDNode *N) {
  return BitConvertToInteger(N->getOperand(0));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(SDNode *N) {
  ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);

  // Get the (bit-cast) APInt of the APFloat and build an integer constant
  return DAG.getConstant(CN->getValueAPF().bitcastToAPInt(), SDLoc(CN),
                         MVT::i16);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(SDNode *N) {
  SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
                     NewOp.getValueType().getVectorElementType(), NewOp,
                     N->getOperand(1));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(SDNode *N) {
  SDValue LHS = GetSoftPromotedHalf(N->getOperand(0));
  SDValue RHS = BitConvertToInteger(N->getOperand(1));
  SDLoc dl(N);

  EVT LVT = LHS.getValueType();
  EVT RVT = RHS.getValueType();

  unsigned LSize = LVT.getSizeInBits();
  unsigned RSize = RVT.getSizeInBits();

  // First get the sign bit of second operand.
  SDValue SignBit = DAG.getNode(
      ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
      DAG.getConstant(RSize - 1, dl,
                      TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
  SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit);

  // Shift right or sign-extend it if the two operands have different types.
  int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
  if (SizeDiff > 0) {
    SignBit =
        DAG.getNode(ISD::SRL, dl, RVT, SignBit,
                    DAG.getConstant(SizeDiff, dl,
                                    TLI.getShiftAmountTy(SignBit.getValueType(),
                                                         DAG.getDataLayout())));
    SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit);
  } else if (SizeDiff < 0) {
    SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit);
    SignBit =
        DAG.getNode(ISD::SHL, dl, LVT, SignBit,
                    DAG.getConstant(-SizeDiff, dl,
                                    TLI.getShiftAmountTy(SignBit.getValueType(),
                                                         DAG.getDataLayout())));
  }

  // Clear the sign bit of the first operand.
  SDValue Mask = DAG.getNode(
      ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
      DAG.getConstant(LSize - 1, dl,
                      TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
  Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
  LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask);

  // Or the value with the sign bit.
  return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FMAD(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
  SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
  SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
  SDLoc dl(N);

  // Promote to the larger FP type.
  Op0 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op0);
  Op1 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op1);
  Op2 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op2);

  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1, Op2);

  // Convert back to FP16 as an integer.
  return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FPOWI(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
  SDValue Op1 = N->getOperand(1);
  SDLoc dl(N);

  Op0 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op0);

  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1);

  // Convert back to FP16 as an integer.
  return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(SDNode *N) {
  if (N->isStrictFPOpcode()) {
    SDValue Res =
        DAG.getNode(ISD::STRICT_FP_TO_FP16, SDLoc(N), {MVT::i16, MVT::Other},
                    {N->getOperand(0), N->getOperand(1)});
    ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
    return Res;
  }

  return DAG.getNode(ISD::FP_TO_FP16, SDLoc(N), MVT::i16, N->getOperand(0));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_LOAD(SDNode *N) {
  LoadSDNode *L = cast<LoadSDNode>(N);

  // Load the value as an integer value with the same number of bits.
  assert(L->getExtensionType() == ISD::NON_EXTLOAD && "Unexpected extension!");
  SDValue NewL =
      DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), MVT::i16,
                  SDLoc(N), L->getChain(), L->getBasePtr(), L->getOffset(),
                  L->getPointerInfo(), MVT::i16, L->getOriginalAlign(),
                  L->getMemOperand()->getFlags(), L->getAAInfo());
  // Legalize the chain result by replacing uses of the old value chain with the
  // new one
  ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
  return NewL;
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT(SDNode *N) {
  SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
  SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
  return DAG.getSelect(SDLoc(N), Op1.getValueType(), N->getOperand(0), Op1,
                       Op2);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(SDNode *N) {
  SDValue Op2 = GetSoftPromotedHalf(N->getOperand(2));
  SDValue Op3 = GetSoftPromotedHalf(N->getOperand(3));
  return DAG.getNode(ISD::SELECT_CC, SDLoc(N), Op2.getValueType(),
                     N->getOperand(0), N->getOperand(1), Op2, Op3,
                     N->getOperand(4));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDLoc dl(N);

  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));

  // Round the value to the softened type.
  return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UNDEF(SDNode *N) {
  return DAG.getUNDEF(MVT::i16);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryOp(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op = GetSoftPromotedHalf(N->getOperand(0));
  SDLoc dl(N);

  // Promote to the larger FP type.
  Op = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op);

  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op);

  // Convert back to FP16 as an integer.
  return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_BinOp(SDNode *N) {
  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
  SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));
  SDValue Op1 = GetSoftPromotedHalf(N->getOperand(1));
  SDLoc dl(N);

  // Promote to the larger FP type.
  Op0 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op0);
  Op1 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op1);

  SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, Op0, Op1);

  // Convert back to FP16 as an integer.
  return DAG.getNode(ISD::FP_TO_FP16, dl, MVT::i16, Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(SDNode *N) {
  // Expand and soften recursively.
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduce(N, DAG));
  return SDValue();
}

SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(SDNode *N) {
  // Expand and soften.
  ReplaceValueWith(SDValue(N, 0), TLI.expandVecReduceSeq(N, DAG));
  return SDValue();
}

//===----------------------------------------------------------------------===//
//  Half Operand Soft Promotion
//===----------------------------------------------------------------------===//

bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
  LLVM_DEBUG(dbgs() << "Soft promote half operand " << OpNo << ": ";
             N->dump(&DAG); dbgs() << "\n");
  SDValue Res = SDValue();

  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
    LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
    return false;
  }

  // Nodes that use a promotion-requiring floating point operand, but doesn't
  // produce a soft promotion-requiring floating point result, need to be
  // legalized to use the soft promoted float operand.  Nodes that produce at
  // least one soft promotion-requiring floating point result have their
  // operands legalized as a part of PromoteFloatResult.
  switch (N->getOpcode()) {
  default:
  #ifndef NDEBUG
    dbgs() << "SoftPromoteHalfOperand Op #" << OpNo << ": ";
    N->dump(&DAG); dbgs() << "\n";
  #endif
    llvm_unreachable("Do not know how to soft promote this operator's operand!");

  case ISD::BITCAST:    Res = SoftPromoteHalfOp_BITCAST(N); break;
  case ISD::FCOPYSIGN:  Res = SoftPromoteHalfOp_FCOPYSIGN(N, OpNo); break;
  case ISD::FP_TO_SINT:
  case ISD::FP_TO_UINT: Res = SoftPromoteHalfOp_FP_TO_XINT(N); break;
  case ISD::FP_TO_SINT_SAT:
  case ISD::FP_TO_UINT_SAT:
                        Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(N); break;
  case ISD::STRICT_FP_EXTEND:
  case ISD::FP_EXTEND:  Res = SoftPromoteHalfOp_FP_EXTEND(N); break;
  case ISD::SELECT_CC:  Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break;
  case ISD::SETCC:      Res = SoftPromoteHalfOp_SETCC(N); break;
  case ISD::STORE:      Res = SoftPromoteHalfOp_STORE(N, OpNo); break;
  }

  if (!Res.getNode())
    return false;

  assert(Res.getNode() != N && "Expected a new node!");

  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
         "Invalid operand expansion");

  ReplaceValueWith(SDValue(N, 0), Res);
  return false;
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BITCAST(SDNode *N) {
  SDValue Op0 = GetSoftPromotedHalf(N->getOperand(0));

  return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op0);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FCOPYSIGN(SDNode *N,
                                                      unsigned OpNo) {
  assert(OpNo == 1 && "Only Operand 1 must need promotion here");
  SDValue Op1 = N->getOperand(1);
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.getValueType());

  Op1 = GetSoftPromotedHalf(Op1);
  Op1 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op1);

  return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), N->getOperand(0),
                     Op1);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(SDNode *N) {
  bool IsStrict = N->isStrictFPOpcode();
  SDValue Op = GetSoftPromotedHalf(N->getOperand(IsStrict ? 1 : 0));

  if (IsStrict) {
    SDValue Res =
        DAG.getNode(ISD::STRICT_FP16_TO_FP, SDLoc(N),
                    {N->getValueType(0), MVT::Other}, {N->getOperand(0), Op});
    ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
    ReplaceValueWith(SDValue(N, 0), Res);
    return SDValue();
  }

  return DAG.getNode(ISD::FP16_TO_FP, SDLoc(N), N->getValueType(0), Op);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(SDNode *N) {
  SDValue Op = N->getOperand(0);
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());

  Op = GetSoftPromotedHalf(Op);

  SDValue Res = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op);

  return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) {
  SDValue Op = N->getOperand(0);
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType());

  Op = GetSoftPromotedHalf(Op);

  SDValue Res = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op);

  return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Res,
                     N->getOperand(1));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SELECT_CC(SDNode *N,
                                                      unsigned OpNo) {
  assert(OpNo == 0 && "Can only soften the comparison values");
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.getValueType());

  Op0 = GetSoftPromotedHalf(Op0);
  Op1 = GetSoftPromotedHalf(Op1);

  // Promote to the larger FP type.
  Op0 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op0);
  Op1 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op1);

  return DAG.getNode(ISD::SELECT_CC, SDLoc(N), N->getValueType(0), Op0, Op1,
                     N->getOperand(2), N->getOperand(3), N->getOperand(4));
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SETCC(SDNode *N) {
  SDValue Op0 = N->getOperand(0);
  SDValue Op1 = N->getOperand(1);
  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
  SDLoc dl(N);

  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.getValueType());

  Op0 = GetSoftPromotedHalf(Op0);
  Op1 = GetSoftPromotedHalf(Op1);

  // Promote to the larger FP type.
  Op0 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op0);
  Op1 = DAG.getNode(ISD::FP16_TO_FP, dl, NVT, Op1);

  return DAG.getSetCC(SDLoc(N), N->getValueType(0), Op0, Op1, CCCode);
}

SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo) {
  assert(OpNo == 1 && "Can only soften the stored value!");
  StoreSDNode *ST = cast<StoreSDNode>(N);
  SDValue Val = ST->getValue();
  SDLoc dl(N);

  assert(!ST->isTruncatingStore() && "Unexpected truncating store.");
  SDValue Promoted = GetSoftPromotedHalf(Val);
  return DAG.getStore(ST->getChain(), dl, Promoted, ST->getBasePtr(),
                      ST->getMemOperand());
}
