bool SelectionDAGLegalize::ExpandNode()

in llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp [2675:3861]


bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
  LLVM_DEBUG(dbgs() << "Trying to expand node\n");
  SmallVector<SDValue, 8> Results;
  SDLoc dl(Node);
  SDValue Tmp1, Tmp2, Tmp3, Tmp4;
  bool NeedInvert;
  switch (Node->getOpcode()) {
  case ISD::ABS:
    if ((Tmp1 = TLI.expandABS(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::CTPOP:
    if ((Tmp1 = TLI.expandCTPOP(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::CTLZ:
  case ISD::CTLZ_ZERO_UNDEF:
    if ((Tmp1 = TLI.expandCTLZ(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::CTTZ:
  case ISD::CTTZ_ZERO_UNDEF:
    if ((Tmp1 = TLI.expandCTTZ(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::BITREVERSE:
    if ((Tmp1 = TLI.expandBITREVERSE(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::BSWAP:
    if ((Tmp1 = TLI.expandBSWAP(Node, DAG)))
      Results.push_back(Tmp1);
    break;
  case ISD::PARITY:
    Results.push_back(ExpandPARITY(Node->getOperand(0), dl));
    break;
  case ISD::FRAMEADDR:
  case ISD::RETURNADDR:
  case ISD::FRAME_TO_ARGS_OFFSET:
    Results.push_back(DAG.getConstant(0, dl, Node->getValueType(0)));
    break;
  case ISD::EH_DWARF_CFA: {
    SDValue CfaArg = DAG.getSExtOrTrunc(Node->getOperand(0), dl,
                                        TLI.getPointerTy(DAG.getDataLayout()));
    SDValue Offset = DAG.getNode(ISD::ADD, dl,
                                 CfaArg.getValueType(),
                                 DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET, dl,
                                             CfaArg.getValueType()),
                                 CfaArg);
    SDValue FA = DAG.getNode(
        ISD::FRAMEADDR, dl, TLI.getPointerTy(DAG.getDataLayout()),
        DAG.getConstant(0, dl, TLI.getPointerTy(DAG.getDataLayout())));
    Results.push_back(DAG.getNode(ISD::ADD, dl, FA.getValueType(),
                                  FA, Offset));
    break;
  }
  case ISD::FLT_ROUNDS_:
    Results.push_back(DAG.getConstant(1, dl, Node->getValueType(0)));
    Results.push_back(Node->getOperand(0));
    break;
  case ISD::EH_RETURN:
  case ISD::EH_LABEL:
  case ISD::PREFETCH:
  case ISD::VAEND:
  case ISD::EH_SJLJ_LONGJMP:
    // If the target didn't expand these, there's nothing to do, so just
    // preserve the chain and be done.
    Results.push_back(Node->getOperand(0));
    break;
  case ISD::READCYCLECOUNTER:
    // If the target didn't expand this, just return 'zero' and preserve the
    // chain.
    Results.append(Node->getNumValues() - 1,
                   DAG.getConstant(0, dl, Node->getValueType(0)));
    Results.push_back(Node->getOperand(0));
    break;
  case ISD::EH_SJLJ_SETJMP:
    // If the target didn't expand this, just return 'zero' and preserve the
    // chain.
    Results.push_back(DAG.getConstant(0, dl, MVT::i32));
    Results.push_back(Node->getOperand(0));
    break;
  case ISD::ATOMIC_LOAD: {
    // There is no libcall for atomic load; fake it with ATOMIC_CMP_SWAP.
    SDValue Zero = DAG.getConstant(0, dl, Node->getValueType(0));
    SDVTList VTs = DAG.getVTList(Node->getValueType(0), MVT::Other);
    SDValue Swap = DAG.getAtomicCmpSwap(
        ISD::ATOMIC_CMP_SWAP, dl, cast<AtomicSDNode>(Node)->getMemoryVT(), VTs,
        Node->getOperand(0), Node->getOperand(1), Zero, Zero,
        cast<AtomicSDNode>(Node)->getMemOperand());
    Results.push_back(Swap.getValue(0));
    Results.push_back(Swap.getValue(1));
    break;
  }
  case ISD::ATOMIC_STORE: {
    // There is no libcall for atomic store; fake it with ATOMIC_SWAP.
    SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl,
                                 cast<AtomicSDNode>(Node)->getMemoryVT(),
                                 Node->getOperand(0),
                                 Node->getOperand(1), Node->getOperand(2),
                                 cast<AtomicSDNode>(Node)->getMemOperand());
    Results.push_back(Swap.getValue(1));
    break;
  }
  case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
    // Expanding an ATOMIC_CMP_SWAP_WITH_SUCCESS produces an ATOMIC_CMP_SWAP and
    // splits out the success value as a comparison. Expanding the resulting
    // ATOMIC_CMP_SWAP will produce a libcall.
    SDVTList VTs = DAG.getVTList(Node->getValueType(0), MVT::Other);
    SDValue Res = DAG.getAtomicCmpSwap(
        ISD::ATOMIC_CMP_SWAP, dl, cast<AtomicSDNode>(Node)->getMemoryVT(), VTs,
        Node->getOperand(0), Node->getOperand(1), Node->getOperand(2),
        Node->getOperand(3), cast<MemSDNode>(Node)->getMemOperand());

    SDValue ExtRes = Res;
    SDValue LHS = Res;
    SDValue RHS = Node->getOperand(1);

    EVT AtomicType = cast<AtomicSDNode>(Node)->getMemoryVT();
    EVT OuterType = Node->getValueType(0);
    switch (TLI.getExtendForAtomicOps()) {
    case ISD::SIGN_EXTEND:
      LHS = DAG.getNode(ISD::AssertSext, dl, OuterType, Res,
                        DAG.getValueType(AtomicType));
      RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, OuterType,
                        Node->getOperand(2), DAG.getValueType(AtomicType));
      ExtRes = LHS;
      break;
    case ISD::ZERO_EXTEND:
      LHS = DAG.getNode(ISD::AssertZext, dl, OuterType, Res,
                        DAG.getValueType(AtomicType));
      RHS = DAG.getZeroExtendInReg(Node->getOperand(2), dl, AtomicType);
      ExtRes = LHS;
      break;
    case ISD::ANY_EXTEND:
      LHS = DAG.getZeroExtendInReg(Res, dl, AtomicType);
      RHS = DAG.getZeroExtendInReg(Node->getOperand(2), dl, AtomicType);
      break;
    default:
      llvm_unreachable("Invalid atomic op extension");
    }

    SDValue Success =
        DAG.getSetCC(dl, Node->getValueType(1), LHS, RHS, ISD::SETEQ);

    Results.push_back(ExtRes.getValue(0));
    Results.push_back(Success);
    Results.push_back(Res.getValue(1));
    break;
  }
  case ISD::DYNAMIC_STACKALLOC:
    ExpandDYNAMIC_STACKALLOC(Node, Results);
    break;
  case ISD::MERGE_VALUES:
    for (unsigned i = 0; i < Node->getNumValues(); i++)
      Results.push_back(Node->getOperand(i));
    break;
  case ISD::UNDEF: {
    EVT VT = Node->getValueType(0);
    if (VT.isInteger())
      Results.push_back(DAG.getConstant(0, dl, VT));
    else {
      assert(VT.isFloatingPoint() && "Unknown value type!");
      Results.push_back(DAG.getConstantFP(0, dl, VT));
    }
    break;
  }
  case ISD::STRICT_FP_ROUND:
    // When strict mode is enforced we can't do expansion because it
    // does not honor the "strict" properties. Only libcall is allowed.
    if (TLI.isStrictFPEnabled())
      break;
    // We might as well mutate to FP_ROUND when FP_ROUND operation is legal
    // since this operation is more efficient than stack operation.
    if (TLI.getStrictFPOperationAction(Node->getOpcode(),
                                       Node->getValueType(0))
        == TargetLowering::Legal)
      break;
    // We fall back to use stack operation when the FP_ROUND operation
    // isn't available.
    if ((Tmp1 = EmitStackConvert(Node->getOperand(1), Node->getValueType(0),
                                 Node->getValueType(0), dl,
                                 Node->getOperand(0)))) {
      ReplaceNode(Node, Tmp1.getNode());
      LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_ROUND node\n");
      return true;
    }
    break;
  case ISD::FP_ROUND:
  case ISD::BITCAST:
    if ((Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
                                 Node->getValueType(0), dl)))
      Results.push_back(Tmp1);
    break;
  case ISD::STRICT_FP_EXTEND:
    // When strict mode is enforced we can't do expansion because it
    // does not honor the "strict" properties. Only libcall is allowed.
    if (TLI.isStrictFPEnabled())
      break;
    // We might as well mutate to FP_EXTEND when FP_EXTEND operation is legal
    // since this operation is more efficient than stack operation.
    if (TLI.getStrictFPOperationAction(Node->getOpcode(),
                                       Node->getValueType(0))
        == TargetLowering::Legal)
      break;
    // We fall back to use stack operation when the FP_EXTEND operation
    // isn't available.
    if ((Tmp1 = EmitStackConvert(
             Node->getOperand(1), Node->getOperand(1).getValueType(),
             Node->getValueType(0), dl, Node->getOperand(0)))) {
      ReplaceNode(Node, Tmp1.getNode());
      LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_EXTEND node\n");
      return true;
    }
    break;
  case ISD::FP_EXTEND:
    if ((Tmp1 = EmitStackConvert(Node->getOperand(0),
                                 Node->getOperand(0).getValueType(),
                                 Node->getValueType(0), dl)))
      Results.push_back(Tmp1);
    break;
  case ISD::SIGN_EXTEND_INREG: {
    EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
    EVT VT = Node->getValueType(0);

    // An in-register sign-extend of a boolean is a negation:
    // 'true' (1) sign-extended is -1.
    // 'false' (0) sign-extended is 0.
    // However, we must mask the high bits of the source operand because the
    // SIGN_EXTEND_INREG does not guarantee that the high bits are already zero.

    // TODO: Do this for vectors too?
    if (ExtraVT.getSizeInBits() == 1) {
      SDValue One = DAG.getConstant(1, dl, VT);
      SDValue And = DAG.getNode(ISD::AND, dl, VT, Node->getOperand(0), One);
      SDValue Zero = DAG.getConstant(0, dl, VT);
      SDValue Neg = DAG.getNode(ISD::SUB, dl, VT, Zero, And);
      Results.push_back(Neg);
      break;
    }

    // NOTE: we could fall back on load/store here too for targets without
    // SRA.  However, it is doubtful that any exist.
    EVT ShiftAmountTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
    unsigned BitsDiff = VT.getScalarSizeInBits() -
                        ExtraVT.getScalarSizeInBits();
    SDValue ShiftCst = DAG.getConstant(BitsDiff, dl, ShiftAmountTy);
    Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0),
                       Node->getOperand(0), ShiftCst);
    Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst);
    Results.push_back(Tmp1);
    break;
  }
  case ISD::UINT_TO_FP:
  case ISD::STRICT_UINT_TO_FP:
    if (TLI.expandUINT_TO_FP(Node, Tmp1, Tmp2, DAG)) {
      Results.push_back(Tmp1);
      if (Node->isStrictFPOpcode())
        Results.push_back(Tmp2);
      break;
    }
    LLVM_FALLTHROUGH;
  case ISD::SINT_TO_FP:
  case ISD::STRICT_SINT_TO_FP:
    if ((Tmp1 = ExpandLegalINT_TO_FP(Node, Tmp2))) {
      Results.push_back(Tmp1);
      if (Node->isStrictFPOpcode())
        Results.push_back(Tmp2);
    }
    break;
  case ISD::FP_TO_SINT:
    if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG))
      Results.push_back(Tmp1);
    break;
  case ISD::STRICT_FP_TO_SINT:
    if (TLI.expandFP_TO_SINT(Node, Tmp1, DAG)) {
      ReplaceNode(Node, Tmp1.getNode());
      LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_TO_SINT node\n");
      return true;
    }
    break;
  case ISD::FP_TO_UINT:
    if (TLI.expandFP_TO_UINT(Node, Tmp1, Tmp2, DAG))
      Results.push_back(Tmp1);
    break;
  case ISD::STRICT_FP_TO_UINT:
    if (TLI.expandFP_TO_UINT(Node, Tmp1, Tmp2, DAG)) {
      // Relink the chain.
      DAG.ReplaceAllUsesOfValueWith(SDValue(Node,1), Tmp2);
      // Replace the new UINT result.
      ReplaceNodeWithValue(SDValue(Node, 0), Tmp1);
      LLVM_DEBUG(dbgs() << "Successfully expanded STRICT_FP_TO_UINT node\n");
      return true;
    }
    break;
  case ISD::FP_TO_SINT_SAT:
  case ISD::FP_TO_UINT_SAT:
    Results.push_back(TLI.expandFP_TO_INT_SAT(Node, DAG));
    break;
  case ISD::VAARG:
    Results.push_back(DAG.expandVAArg(Node));
    Results.push_back(Results[0].getValue(1));
    break;
  case ISD::VACOPY:
    Results.push_back(DAG.expandVACopy(Node));
    break;
  case ISD::EXTRACT_VECTOR_ELT:
    if (Node->getOperand(0).getValueType().getVectorNumElements() == 1)
      // This must be an access of the only element.  Return it.
      Tmp1 = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0),
                         Node->getOperand(0));
    else
      Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0));
    Results.push_back(Tmp1);
    break;
  case ISD::EXTRACT_SUBVECTOR:
    Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0)));
    break;
  case ISD::INSERT_SUBVECTOR:
    Results.push_back(ExpandInsertToVectorThroughStack(SDValue(Node, 0)));
    break;
  case ISD::CONCAT_VECTORS:
    Results.push_back(ExpandVectorBuildThroughStack(Node));
    break;
  case ISD::SCALAR_TO_VECTOR:
    Results.push_back(ExpandSCALAR_TO_VECTOR(Node));
    break;
  case ISD::INSERT_VECTOR_ELT:
    Results.push_back(ExpandINSERT_VECTOR_ELT(Node->getOperand(0),
                                              Node->getOperand(1),
                                              Node->getOperand(2), dl));
    break;
  case ISD::VECTOR_SHUFFLE: {
    SmallVector<int, 32> NewMask;
    ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(Node)->getMask();

    EVT VT = Node->getValueType(0);
    EVT EltVT = VT.getVectorElementType();
    SDValue Op0 = Node->getOperand(0);
    SDValue Op1 = Node->getOperand(1);
    if (!TLI.isTypeLegal(EltVT)) {
      EVT NewEltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);

      // BUILD_VECTOR operands are allowed to be wider than the element type.
      // But if NewEltVT is smaller that EltVT the BUILD_VECTOR does not accept
      // it.
      if (NewEltVT.bitsLT(EltVT)) {
        // Convert shuffle node.
        // If original node was v4i64 and the new EltVT is i32,
        // cast operands to v8i32 and re-build the mask.

        // Calculate new VT, the size of the new VT should be equal to original.
        EVT NewVT =
            EVT::getVectorVT(*DAG.getContext(), NewEltVT,
                             VT.getSizeInBits() / NewEltVT.getSizeInBits());
        assert(NewVT.bitsEq(VT));

        // cast operands to new VT
        Op0 = DAG.getNode(ISD::BITCAST, dl, NewVT, Op0);
        Op1 = DAG.getNode(ISD::BITCAST, dl, NewVT, Op1);

        // Convert the shuffle mask
        unsigned int factor =
                         NewVT.getVectorNumElements()/VT.getVectorNumElements();

        // EltVT gets smaller
        assert(factor > 0);

        for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
          if (Mask[i] < 0) {
            for (unsigned fi = 0; fi < factor; ++fi)
              NewMask.push_back(Mask[i]);
          }
          else {
            for (unsigned fi = 0; fi < factor; ++fi)
              NewMask.push_back(Mask[i]*factor+fi);
          }
        }
        Mask = NewMask;
        VT = NewVT;
      }
      EltVT = NewEltVT;
    }
    unsigned NumElems = VT.getVectorNumElements();
    SmallVector<SDValue, 16> Ops;
    for (unsigned i = 0; i != NumElems; ++i) {
      if (Mask[i] < 0) {
        Ops.push_back(DAG.getUNDEF(EltVT));
        continue;
      }
      unsigned Idx = Mask[i];
      if (Idx < NumElems)
        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op0,
                                  DAG.getVectorIdxConstant(Idx, dl)));
      else
        Ops.push_back(
            DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Op1,
                        DAG.getVectorIdxConstant(Idx - NumElems, dl)));
    }

    Tmp1 = DAG.getBuildVector(VT, dl, Ops);
    // We may have changed the BUILD_VECTOR type. Cast it back to the Node type.
    Tmp1 = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), Tmp1);
    Results.push_back(Tmp1);
    break;
  }
  case ISD::VECTOR_SPLICE: {
    Results.push_back(TLI.expandVectorSplice(Node, DAG));
    break;
  }
  case ISD::EXTRACT_ELEMENT: {
    EVT OpTy = Node->getOperand(0).getValueType();
    if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
      // 1 -> Hi
      Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0),
                         DAG.getConstant(OpTy.getSizeInBits() / 2, dl,
                                         TLI.getShiftAmountTy(
                                             Node->getOperand(0).getValueType(),
                                             DAG.getDataLayout())));
      Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1);
    } else {
      // 0 -> Lo
      Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0),
                         Node->getOperand(0));
    }
    Results.push_back(Tmp1);
    break;
  }
  case ISD::STACKSAVE:
    // Expand to CopyFromReg if the target set
    // StackPointerRegisterToSaveRestore.
    if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
      Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, SP,
                                           Node->getValueType(0)));
      Results.push_back(Results[0].getValue(1));
    } else {
      Results.push_back(DAG.getUNDEF(Node->getValueType(0)));
      Results.push_back(Node->getOperand(0));
    }
    break;
  case ISD::STACKRESTORE:
    // Expand to CopyToReg if the target set
    // StackPointerRegisterToSaveRestore.
    if (Register SP = TLI.getStackPointerRegisterToSaveRestore()) {
      Results.push_back(DAG.getCopyToReg(Node->getOperand(0), dl, SP,
                                         Node->getOperand(1)));
    } else {
      Results.push_back(Node->getOperand(0));
    }
    break;
  case ISD::GET_DYNAMIC_AREA_OFFSET:
    Results.push_back(DAG.getConstant(0, dl, Node->getValueType(0)));
    Results.push_back(Results[0].getValue(0));
    break;
  case ISD::FCOPYSIGN:
    Results.push_back(ExpandFCOPYSIGN(Node));
    break;
  case ISD::FNEG:
    Results.push_back(ExpandFNEG(Node));
    break;
  case ISD::FABS:
    Results.push_back(ExpandFABS(Node));
    break;
  case ISD::SMIN:
  case ISD::SMAX:
  case ISD::UMIN:
  case ISD::UMAX: {
    // Expand Y = MAX(A, B) -> Y = (A > B) ? A : B
    ISD::CondCode Pred;
    switch (Node->getOpcode()) {
    default: llvm_unreachable("How did we get here?");
    case ISD::SMAX: Pred = ISD::SETGT; break;
    case ISD::SMIN: Pred = ISD::SETLT; break;
    case ISD::UMAX: Pred = ISD::SETUGT; break;
    case ISD::UMIN: Pred = ISD::SETULT; break;
    }
    Tmp1 = Node->getOperand(0);
    Tmp2 = Node->getOperand(1);
    Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
    Results.push_back(Tmp1);
    break;
  }
  case ISD::FMINNUM:
  case ISD::FMAXNUM: {
    if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Node, DAG))
      Results.push_back(Expanded);
    break;
  }
  case ISD::FSIN:
  case ISD::FCOS: {
    EVT VT = Node->getValueType(0);
    // Turn fsin / fcos into ISD::FSINCOS node if there are a pair of fsin /
    // fcos which share the same operand and both are used.
    if ((TLI.isOperationLegalOrCustom(ISD::FSINCOS, VT) ||
         isSinCosLibcallAvailable(Node, TLI))
        && useSinCos(Node)) {
      SDVTList VTs = DAG.getVTList(VT, VT);
      Tmp1 = DAG.getNode(ISD::FSINCOS, dl, VTs, Node->getOperand(0));
      if (Node->getOpcode() == ISD::FCOS)
        Tmp1 = Tmp1.getValue(1);
      Results.push_back(Tmp1);
    }
    break;
  }
  case ISD::FMAD:
    llvm_unreachable("Illegal fmad should never be formed");

  case ISD::FP16_TO_FP:
    if (Node->getValueType(0) != MVT::f32) {
      // We can extend to types bigger than f32 in two steps without changing
      // the result. Since "f16 -> f32" is much more commonly available, give
      // CodeGen the option of emitting that before resorting to a libcall.
      SDValue Res =
          DAG.getNode(ISD::FP16_TO_FP, dl, MVT::f32, Node->getOperand(0));
      Results.push_back(
          DAG.getNode(ISD::FP_EXTEND, dl, Node->getValueType(0), Res));
    }
    break;
  case ISD::STRICT_FP16_TO_FP:
    if (Node->getValueType(0) != MVT::f32) {
      // We can extend to types bigger than f32 in two steps without changing
      // the result. Since "f16 -> f32" is much more commonly available, give
      // CodeGen the option of emitting that before resorting to a libcall.
      SDValue Res =
          DAG.getNode(ISD::STRICT_FP16_TO_FP, dl, {MVT::f32, MVT::Other},
                      {Node->getOperand(0), Node->getOperand(1)});
      Res = DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
                        {Node->getValueType(0), MVT::Other},
                        {Res.getValue(1), Res});
      Results.push_back(Res);
      Results.push_back(Res.getValue(1));
    }
    break;
  case ISD::FP_TO_FP16:
    LLVM_DEBUG(dbgs() << "Legalizing FP_TO_FP16\n");
    if (!TLI.useSoftFloat() && TM.Options.UnsafeFPMath) {
      SDValue Op = Node->getOperand(0);
      MVT SVT = Op.getSimpleValueType();
      if ((SVT == MVT::f64 || SVT == MVT::f80) &&
          TLI.isOperationLegalOrCustom(ISD::FP_TO_FP16, MVT::f32)) {
        // Under fastmath, we can expand this node into a fround followed by
        // a float-half conversion.
        SDValue FloatVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Op,
                                       DAG.getIntPtrConstant(0, dl));
        Results.push_back(
            DAG.getNode(ISD::FP_TO_FP16, dl, Node->getValueType(0), FloatVal));
      }
    }
    break;
  case ISD::ConstantFP: {
    ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node);
    // Check to see if this FP immediate is already legal.
    // If this is a legal constant, turn it into a TargetConstantFP node.
    if (!TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0),
                          DAG.shouldOptForSize()))
      Results.push_back(ExpandConstantFP(CFP, true));
    break;
  }
  case ISD::Constant: {
    ConstantSDNode *CP = cast<ConstantSDNode>(Node);
    Results.push_back(ExpandConstant(CP));
    break;
  }
  case ISD::FSUB: {
    EVT VT = Node->getValueType(0);
    if (TLI.isOperationLegalOrCustom(ISD::FADD, VT) &&
        TLI.isOperationLegalOrCustom(ISD::FNEG, VT)) {
      const SDNodeFlags Flags = Node->getFlags();
      Tmp1 = DAG.getNode(ISD::FNEG, dl, VT, Node->getOperand(1));
      Tmp1 = DAG.getNode(ISD::FADD, dl, VT, Node->getOperand(0), Tmp1, Flags);
      Results.push_back(Tmp1);
    }
    break;
  }
  case ISD::SUB: {
    EVT VT = Node->getValueType(0);
    assert(TLI.isOperationLegalOrCustom(ISD::ADD, VT) &&
           TLI.isOperationLegalOrCustom(ISD::XOR, VT) &&
           "Don't know how to expand this subtraction!");
    Tmp1 = DAG.getNOT(dl, Node->getOperand(1), VT);
    Tmp1 = DAG.getNode(ISD::ADD, dl, VT, Tmp1, DAG.getConstant(1, dl, VT));
    Results.push_back(DAG.getNode(ISD::ADD, dl, VT, Node->getOperand(0), Tmp1));
    break;
  }
  case ISD::UREM:
  case ISD::SREM:
    if (TLI.expandREM(Node, Tmp1, DAG))
      Results.push_back(Tmp1);
    break;
  case ISD::UDIV:
  case ISD::SDIV: {
    bool isSigned = Node->getOpcode() == ISD::SDIV;
    unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM;
    EVT VT = Node->getValueType(0);
    if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
      SDVTList VTs = DAG.getVTList(VT, VT);
      Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0),
                         Node->getOperand(1));
      Results.push_back(Tmp1);
    }
    break;
  }
  case ISD::MULHU:
  case ISD::MULHS: {
    unsigned ExpandOpcode =
        Node->getOpcode() == ISD::MULHU ? ISD::UMUL_LOHI : ISD::SMUL_LOHI;
    EVT VT = Node->getValueType(0);
    SDVTList VTs = DAG.getVTList(VT, VT);

    Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->getOperand(0),
                       Node->getOperand(1));
    Results.push_back(Tmp1.getValue(1));
    break;
  }
  case ISD::UMUL_LOHI:
  case ISD::SMUL_LOHI: {
    SDValue LHS = Node->getOperand(0);
    SDValue RHS = Node->getOperand(1);
    MVT VT = LHS.getSimpleValueType();
    unsigned MULHOpcode =
        Node->getOpcode() == ISD::UMUL_LOHI ? ISD::MULHU : ISD::MULHS;

    if (TLI.isOperationLegalOrCustom(MULHOpcode, VT)) {
      Results.push_back(DAG.getNode(ISD::MUL, dl, VT, LHS, RHS));
      Results.push_back(DAG.getNode(MULHOpcode, dl, VT, LHS, RHS));
      break;
    }

    SmallVector<SDValue, 4> Halves;
    EVT HalfType = EVT(VT).getHalfSizedIntegerVT(*DAG.getContext());
    assert(TLI.isTypeLegal(HalfType));
    if (TLI.expandMUL_LOHI(Node->getOpcode(), VT, dl, LHS, RHS, Halves,
                           HalfType, DAG,
                           TargetLowering::MulExpansionKind::Always)) {
      for (unsigned i = 0; i < 2; ++i) {
        SDValue Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Halves[2 * i]);
        SDValue Hi = DAG.getNode(ISD::ANY_EXTEND, dl, VT, Halves[2 * i + 1]);
        SDValue Shift = DAG.getConstant(
            HalfType.getScalarSizeInBits(), dl,
            TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
        Hi = DAG.getNode(ISD::SHL, dl, VT, Hi, Shift);
        Results.push_back(DAG.getNode(ISD::OR, dl, VT, Lo, Hi));
      }
      break;
    }
    break;
  }
  case ISD::MUL: {
    EVT VT = Node->getValueType(0);
    SDVTList VTs = DAG.getVTList(VT, VT);
    // See if multiply or divide can be lowered using two-result operations.
    // We just need the low half of the multiply; try both the signed
    // and unsigned forms. If the target supports both SMUL_LOHI and
    // UMUL_LOHI, form a preference by checking which forms of plain
    // MULH it supports.
    bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT);
    bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT);
    bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT);
    bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT);
    unsigned OpToUse = 0;
    if (HasSMUL_LOHI && !HasMULHS) {
      OpToUse = ISD::SMUL_LOHI;
    } else if (HasUMUL_LOHI && !HasMULHU) {
      OpToUse = ISD::UMUL_LOHI;
    } else if (HasSMUL_LOHI) {
      OpToUse = ISD::SMUL_LOHI;
    } else if (HasUMUL_LOHI) {
      OpToUse = ISD::UMUL_LOHI;
    }
    if (OpToUse) {
      Results.push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0),
                                    Node->getOperand(1)));
      break;
    }

    SDValue Lo, Hi;
    EVT HalfType = VT.getHalfSizedIntegerVT(*DAG.getContext());
    if (TLI.isOperationLegalOrCustom(ISD::ZERO_EXTEND, VT) &&
        TLI.isOperationLegalOrCustom(ISD::ANY_EXTEND, VT) &&
        TLI.isOperationLegalOrCustom(ISD::SHL, VT) &&
        TLI.isOperationLegalOrCustom(ISD::OR, VT) &&
        TLI.expandMUL(Node, Lo, Hi, HalfType, DAG,
                      TargetLowering::MulExpansionKind::OnlyLegalOrCustom)) {
      Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Lo);
      Hi = DAG.getNode(ISD::ANY_EXTEND, dl, VT, Hi);
      SDValue Shift =
          DAG.getConstant(HalfType.getSizeInBits(), dl,
                          TLI.getShiftAmountTy(HalfType, DAG.getDataLayout()));
      Hi = DAG.getNode(ISD::SHL, dl, VT, Hi, Shift);
      Results.push_back(DAG.getNode(ISD::OR, dl, VT, Lo, Hi));
    }
    break;
  }
  case ISD::FSHL:
  case ISD::FSHR:
    if (SDValue Expanded = TLI.expandFunnelShift(Node, DAG))
      Results.push_back(Expanded);
    break;
  case ISD::ROTL:
  case ISD::ROTR:
    if (SDValue Expanded = TLI.expandROT(Node, true /*AllowVectorOps*/, DAG))
      Results.push_back(Expanded);
    break;
  case ISD::SADDSAT:
  case ISD::UADDSAT:
  case ISD::SSUBSAT:
  case ISD::USUBSAT:
    Results.push_back(TLI.expandAddSubSat(Node, DAG));
    break;
  case ISD::SSHLSAT:
  case ISD::USHLSAT:
    Results.push_back(TLI.expandShlSat(Node, DAG));
    break;
  case ISD::SMULFIX:
  case ISD::SMULFIXSAT:
  case ISD::UMULFIX:
  case ISD::UMULFIXSAT:
    Results.push_back(TLI.expandFixedPointMul(Node, DAG));
    break;
  case ISD::SDIVFIX:
  case ISD::SDIVFIXSAT:
  case ISD::UDIVFIX:
  case ISD::UDIVFIXSAT:
    if (SDValue V = TLI.expandFixedPointDiv(Node->getOpcode(), SDLoc(Node),
                                            Node->getOperand(0),
                                            Node->getOperand(1),
                                            Node->getConstantOperandVal(2),
                                            DAG)) {
      Results.push_back(V);
      break;
    }
    // FIXME: We might want to retry here with a wider type if we fail, if that
    // type is legal.
    // FIXME: Technically, so long as we only have sdivfixes where BW+Scale is
    // <= 128 (which is the case for all of the default Embedded-C types),
    // we will only get here with types and scales that we could always expand
    // if we were allowed to generate libcalls to division functions of illegal
    // type. But we cannot do that.
    llvm_unreachable("Cannot expand DIVFIX!");
  case ISD::ADDCARRY:
  case ISD::SUBCARRY: {
    SDValue LHS = Node->getOperand(0);
    SDValue RHS = Node->getOperand(1);
    SDValue Carry = Node->getOperand(2);

    bool IsAdd = Node->getOpcode() == ISD::ADDCARRY;

    // Initial add of the 2 operands.
    unsigned Op = IsAdd ? ISD::ADD : ISD::SUB;
    EVT VT = LHS.getValueType();
    SDValue Sum = DAG.getNode(Op, dl, VT, LHS, RHS);

    // Initial check for overflow.
    EVT CarryType = Node->getValueType(1);
    EVT SetCCType = getSetCCResultType(Node->getValueType(0));
    ISD::CondCode CC = IsAdd ? ISD::SETULT : ISD::SETUGT;
    SDValue Overflow = DAG.getSetCC(dl, SetCCType, Sum, LHS, CC);

    // Add of the sum and the carry.
    SDValue One = DAG.getConstant(1, dl, VT);
    SDValue CarryExt =
        DAG.getNode(ISD::AND, dl, VT, DAG.getZExtOrTrunc(Carry, dl, VT), One);
    SDValue Sum2 = DAG.getNode(Op, dl, VT, Sum, CarryExt);

    // Second check for overflow. If we are adding, we can only overflow if the
    // initial sum is all 1s ang the carry is set, resulting in a new sum of 0.
    // If we are subtracting, we can only overflow if the initial sum is 0 and
    // the carry is set, resulting in a new sum of all 1s.
    SDValue Zero = DAG.getConstant(0, dl, VT);
    SDValue Overflow2 =
        IsAdd ? DAG.getSetCC(dl, SetCCType, Sum2, Zero, ISD::SETEQ)
              : DAG.getSetCC(dl, SetCCType, Sum, Zero, ISD::SETEQ);
    Overflow2 = DAG.getNode(ISD::AND, dl, SetCCType, Overflow2,
                            DAG.getZExtOrTrunc(Carry, dl, SetCCType));

    SDValue ResultCarry =
        DAG.getNode(ISD::OR, dl, SetCCType, Overflow, Overflow2);

    Results.push_back(Sum2);
    Results.push_back(DAG.getBoolExtOrTrunc(ResultCarry, dl, CarryType, VT));
    break;
  }
  case ISD::SADDO:
  case ISD::SSUBO: {
    SDValue Result, Overflow;
    TLI.expandSADDSUBO(Node, Result, Overflow, DAG);
    Results.push_back(Result);
    Results.push_back(Overflow);
    break;
  }
  case ISD::UADDO:
  case ISD::USUBO: {
    SDValue Result, Overflow;
    TLI.expandUADDSUBO(Node, Result, Overflow, DAG);
    Results.push_back(Result);
    Results.push_back(Overflow);
    break;
  }
  case ISD::UMULO:
  case ISD::SMULO: {
    SDValue Result, Overflow;
    if (TLI.expandMULO(Node, Result, Overflow, DAG)) {
      Results.push_back(Result);
      Results.push_back(Overflow);
    }
    break;
  }
  case ISD::BUILD_PAIR: {
    EVT PairTy = Node->getValueType(0);
    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Node->getOperand(0));
    Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Node->getOperand(1));
    Tmp2 = DAG.getNode(
        ISD::SHL, dl, PairTy, Tmp2,
        DAG.getConstant(PairTy.getSizeInBits() / 2, dl,
                        TLI.getShiftAmountTy(PairTy, DAG.getDataLayout())));
    Results.push_back(DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2));
    break;
  }
  case ISD::SELECT:
    Tmp1 = Node->getOperand(0);
    Tmp2 = Node->getOperand(1);
    Tmp3 = Node->getOperand(2);
    if (Tmp1.getOpcode() == ISD::SETCC) {
      Tmp1 = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1),
                             Tmp2, Tmp3,
                             cast<CondCodeSDNode>(Tmp1.getOperand(2))->get());
    } else {
      Tmp1 = DAG.getSelectCC(dl, Tmp1,
                             DAG.getConstant(0, dl, Tmp1.getValueType()),
                             Tmp2, Tmp3, ISD::SETNE);
    }
    Tmp1->setFlags(Node->getFlags());
    Results.push_back(Tmp1);
    break;
  case ISD::BR_JT: {
    SDValue Chain = Node->getOperand(0);
    SDValue Table = Node->getOperand(1);
    SDValue Index = Node->getOperand(2);

    const DataLayout &TD = DAG.getDataLayout();
    EVT PTy = TLI.getPointerTy(TD);

    unsigned EntrySize =
      DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);

    // For power-of-two jumptable entry sizes convert multiplication to a shift.
    // This transformation needs to be done here since otherwise the MIPS
    // backend will end up emitting a three instruction multiply sequence
    // instead of a single shift and MSP430 will call a runtime function.
    if (llvm::isPowerOf2_32(EntrySize))
      Index = DAG.getNode(
          ISD::SHL, dl, Index.getValueType(), Index,
          DAG.getConstant(llvm::Log2_32(EntrySize), dl, Index.getValueType()));
    else
      Index = DAG.getNode(ISD::MUL, dl, Index.getValueType(), Index,
                          DAG.getConstant(EntrySize, dl, Index.getValueType()));
    SDValue Addr = DAG.getNode(ISD::ADD, dl, Index.getValueType(),
                               Index, Table);

    EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8);
    SDValue LD = DAG.getExtLoad(
        ISD::SEXTLOAD, dl, PTy, Chain, Addr,
        MachinePointerInfo::getJumpTable(DAG.getMachineFunction()), MemVT);
    Addr = LD;
    if (TLI.isJumpTableRelative()) {
      // For PIC, the sequence is:
      // BRIND(load(Jumptable + index) + RelocBase)
      // RelocBase can be JumpTable, GOT or some sort of global base.
      Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr,
                          TLI.getPICJumpTableRelocBase(Table, DAG));
    }

    Tmp1 = TLI.expandIndirectJTBranch(dl, LD.getValue(1), Addr, DAG);
    Results.push_back(Tmp1);
    break;
  }
  case ISD::BRCOND:
    // Expand brcond's setcc into its constituent parts and create a BR_CC
    // Node.
    Tmp1 = Node->getOperand(0);
    Tmp2 = Node->getOperand(1);
    if (Tmp2.getOpcode() == ISD::SETCC &&
        TLI.isOperationLegalOrCustom(ISD::BR_CC,
                                     Tmp2.getOperand(0).getValueType())) {
      Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, Tmp2.getOperand(2),
                         Tmp2.getOperand(0), Tmp2.getOperand(1),
                         Node->getOperand(2));
    } else {
      // We test only the i1 bit.  Skip the AND if UNDEF or another AND.
      if (Tmp2.isUndef() ||
          (Tmp2.getOpcode() == ISD::AND &&
           isa<ConstantSDNode>(Tmp2.getOperand(1)) &&
           cast<ConstantSDNode>(Tmp2.getOperand(1))->getZExtValue() == 1))
        Tmp3 = Tmp2;
      else
        Tmp3 = DAG.getNode(ISD::AND, dl, Tmp2.getValueType(), Tmp2,
                           DAG.getConstant(1, dl, Tmp2.getValueType()));
      Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1,
                         DAG.getCondCode(ISD::SETNE), Tmp3,
                         DAG.getConstant(0, dl, Tmp3.getValueType()),
                         Node->getOperand(2));
    }
    Results.push_back(Tmp1);
    break;
  case ISD::SETCC:
  case ISD::STRICT_FSETCC:
  case ISD::STRICT_FSETCCS: {
    bool IsStrict = Node->getOpcode() != ISD::SETCC;
    bool IsSignaling = Node->getOpcode() == ISD::STRICT_FSETCCS;
    SDValue Chain = IsStrict ? Node->getOperand(0) : SDValue();
    unsigned Offset = IsStrict ? 1 : 0;
    Tmp1 = Node->getOperand(0 + Offset);
    Tmp2 = Node->getOperand(1 + Offset);
    Tmp3 = Node->getOperand(2 + Offset);
    bool Legalized =
        TLI.LegalizeSetCCCondCode(DAG, Node->getValueType(0), Tmp1, Tmp2, Tmp3,
                                  NeedInvert, dl, Chain, IsSignaling);

    if (Legalized) {
      // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
      // condition code, create a new SETCC node.
      if (Tmp3.getNode())
        Tmp1 = DAG.getNode(ISD::SETCC, dl, Node->getValueType(0),
                           Tmp1, Tmp2, Tmp3, Node->getFlags());

      // If we expanded the SETCC by inverting the condition code, then wrap
      // the existing SETCC in a NOT to restore the intended condition.
      if (NeedInvert)
        Tmp1 = DAG.getLogicalNOT(dl, Tmp1, Tmp1->getValueType(0));

      Results.push_back(Tmp1);
      if (IsStrict)
        Results.push_back(Chain);

      break;
    }

    // FIXME: It seems Legalized is false iff CCCode is Legal. I don't
    // understand if this code is useful for strict nodes.
    assert(!IsStrict && "Don't know how to expand for strict nodes.");

    // Otherwise, SETCC for the given comparison type must be completely
    // illegal; expand it into a SELECT_CC.
    EVT VT = Node->getValueType(0);
    int TrueValue;
    switch (TLI.getBooleanContents(Tmp1.getValueType())) {
    case TargetLowering::ZeroOrOneBooleanContent:
    case TargetLowering::UndefinedBooleanContent:
      TrueValue = 1;
      break;
    case TargetLowering::ZeroOrNegativeOneBooleanContent:
      TrueValue = -1;
      break;
    }
    Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2,
                       DAG.getConstant(TrueValue, dl, VT),
                       DAG.getConstant(0, dl, VT),
                       Tmp3);
    Tmp1->setFlags(Node->getFlags());
    Results.push_back(Tmp1);
    break;
  }
  case ISD::SELECT_CC: {
    // TODO: need to add STRICT_SELECT_CC and STRICT_SELECT_CCS
    Tmp1 = Node->getOperand(0);   // LHS
    Tmp2 = Node->getOperand(1);   // RHS
    Tmp3 = Node->getOperand(2);   // True
    Tmp4 = Node->getOperand(3);   // False
    EVT VT = Node->getValueType(0);
    SDValue Chain;
    SDValue CC = Node->getOperand(4);
    ISD::CondCode CCOp = cast<CondCodeSDNode>(CC)->get();

    if (TLI.isCondCodeLegalOrCustom(CCOp, Tmp1.getSimpleValueType())) {
      // If the condition code is legal, then we need to expand this
      // node using SETCC and SELECT.
      EVT CmpVT = Tmp1.getValueType();
      assert(!TLI.isOperationExpand(ISD::SELECT, VT) &&
             "Cannot expand ISD::SELECT_CC when ISD::SELECT also needs to be "
             "expanded.");
      EVT CCVT = getSetCCResultType(CmpVT);
      SDValue Cond = DAG.getNode(ISD::SETCC, dl, CCVT, Tmp1, Tmp2, CC, Node->getFlags());
      Results.push_back(DAG.getSelect(dl, VT, Cond, Tmp3, Tmp4));
      break;
    }

    // SELECT_CC is legal, so the condition code must not be.
    bool Legalized = false;
    // Try to legalize by inverting the condition.  This is for targets that
    // might support an ordered version of a condition, but not the unordered
    // version (or vice versa).
    ISD::CondCode InvCC = ISD::getSetCCInverse(CCOp, Tmp1.getValueType());
    if (TLI.isCondCodeLegalOrCustom(InvCC, Tmp1.getSimpleValueType())) {
      // Use the new condition code and swap true and false
      Legalized = true;
      Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
      Tmp1->setFlags(Node->getFlags());
    } else {
      // If The inverse is not legal, then try to swap the arguments using
      // the inverse condition code.
      ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InvCC);
      if (TLI.isCondCodeLegalOrCustom(SwapInvCC, Tmp1.getSimpleValueType())) {
        // The swapped inverse condition is legal, so swap true and false,
        // lhs and rhs.
        Legalized = true;
        Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
        Tmp1->setFlags(Node->getFlags());
      }
    }

    if (!Legalized) {
      Legalized = TLI.LegalizeSetCCCondCode(
          DAG, getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC,
          NeedInvert, dl, Chain);

      assert(Legalized && "Can't legalize SELECT_CC with legal condition!");

      // If we expanded the SETCC by inverting the condition code, then swap
      // the True/False operands to match.
      if (NeedInvert)
        std::swap(Tmp3, Tmp4);

      // If we expanded the SETCC by swapping LHS and RHS, or by inverting the
      // condition code, create a new SELECT_CC node.
      if (CC.getNode()) {
        Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0),
                           Tmp1, Tmp2, Tmp3, Tmp4, CC);
      } else {
        Tmp2 = DAG.getConstant(0, dl, Tmp1.getValueType());
        CC = DAG.getCondCode(ISD::SETNE);
        Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1,
                           Tmp2, Tmp3, Tmp4, CC);
      }
      Tmp1->setFlags(Node->getFlags());
    }
    Results.push_back(Tmp1);
    break;
  }
  case ISD::BR_CC: {
    // TODO: need to add STRICT_BR_CC and STRICT_BR_CCS
    SDValue Chain;
    Tmp1 = Node->getOperand(0);              // Chain
    Tmp2 = Node->getOperand(2);              // LHS
    Tmp3 = Node->getOperand(3);              // RHS
    Tmp4 = Node->getOperand(1);              // CC

    bool Legalized =
        TLI.LegalizeSetCCCondCode(DAG, getSetCCResultType(Tmp2.getValueType()),
                                  Tmp2, Tmp3, Tmp4, NeedInvert, dl, Chain);
    (void)Legalized;
    assert(Legalized && "Can't legalize BR_CC with legal condition!");

    // If we expanded the SETCC by swapping LHS and RHS, create a new BR_CC
    // node.
    if (Tmp4.getNode()) {
      assert(!NeedInvert && "Don't know how to invert BR_CC!");

      Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1,
                         Tmp4, Tmp2, Tmp3, Node->getOperand(4));
    } else {
      Tmp3 = DAG.getConstant(0, dl, Tmp2.getValueType());
      Tmp4 = DAG.getCondCode(NeedInvert ? ISD::SETEQ : ISD::SETNE);
      Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4,
                         Tmp2, Tmp3, Node->getOperand(4));
    }
    Results.push_back(Tmp1);
    break;
  }
  case ISD::BUILD_VECTOR:
    Results.push_back(ExpandBUILD_VECTOR(Node));
    break;
  case ISD::SPLAT_VECTOR:
    Results.push_back(ExpandSPLAT_VECTOR(Node));
    break;
  case ISD::SRA:
  case ISD::SRL:
  case ISD::SHL: {
    // Scalarize vector SRA/SRL/SHL.
    EVT VT = Node->getValueType(0);
    assert(VT.isVector() && "Unable to legalize non-vector shift");
    assert(TLI.isTypeLegal(VT.getScalarType())&& "Element type must be legal");
    unsigned NumElem = VT.getVectorNumElements();

    SmallVector<SDValue, 8> Scalars;
    for (unsigned Idx = 0; Idx < NumElem; Idx++) {
      SDValue Ex =
          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT.getScalarType(),
                      Node->getOperand(0), DAG.getVectorIdxConstant(Idx, dl));
      SDValue Sh =
          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT.getScalarType(),
                      Node->getOperand(1), DAG.getVectorIdxConstant(Idx, dl));
      Scalars.push_back(DAG.getNode(Node->getOpcode(), dl,
                                    VT.getScalarType(), Ex, Sh));
    }

    SDValue Result = DAG.getBuildVector(Node->getValueType(0), dl, Scalars);
    Results.push_back(Result);
    break;
  }
  case ISD::VECREDUCE_FADD:
  case ISD::VECREDUCE_FMUL:
  case ISD::VECREDUCE_ADD:
  case ISD::VECREDUCE_MUL:
  case ISD::VECREDUCE_AND:
  case ISD::VECREDUCE_OR:
  case ISD::VECREDUCE_XOR:
  case ISD::VECREDUCE_SMAX:
  case ISD::VECREDUCE_SMIN:
  case ISD::VECREDUCE_UMAX:
  case ISD::VECREDUCE_UMIN:
  case ISD::VECREDUCE_FMAX:
  case ISD::VECREDUCE_FMIN:
    Results.push_back(TLI.expandVecReduce(Node, DAG));
    break;
  case ISD::GLOBAL_OFFSET_TABLE:
  case ISD::GlobalAddress:
  case ISD::GlobalTLSAddress:
  case ISD::ExternalSymbol:
  case ISD::ConstantPool:
  case ISD::JumpTable:
  case ISD::INTRINSIC_W_CHAIN:
  case ISD::INTRINSIC_WO_CHAIN:
  case ISD::INTRINSIC_VOID:
    // FIXME: Custom lowering for these operations shouldn't return null!
    // Return true so that we don't call ConvertNodeToLibcall which also won't
    // do anything.
    return true;
  }

  if (!TLI.isStrictFPEnabled() && Results.empty() && Node->isStrictFPOpcode()) {
    // FIXME: We were asked to expand a strict floating-point operation,
    // but there is currently no expansion implemented that would preserve
    // the "strict" properties.  For now, we just fall back to the non-strict
    // version if that is legal on the target.  The actual mutation of the
    // operation will happen in SelectionDAGISel::DoInstructionSelection.
    switch (Node->getOpcode()) {
    default:
      if (TLI.getStrictFPOperationAction(Node->getOpcode(),
                                         Node->getValueType(0))
          == TargetLowering::Legal)
        return true;
      break;
    case ISD::STRICT_FSUB: {
      if (TLI.getStrictFPOperationAction(
              ISD::STRICT_FSUB, Node->getValueType(0)) == TargetLowering::Legal)
        return true;
      if (TLI.getStrictFPOperationAction(
              ISD::STRICT_FADD, Node->getValueType(0)) != TargetLowering::Legal)
        break;

      EVT VT = Node->getValueType(0);
      const SDNodeFlags Flags = Node->getFlags();
      SDValue Neg = DAG.getNode(ISD::FNEG, dl, VT, Node->getOperand(2), Flags);
      SDValue Fadd = DAG.getNode(ISD::STRICT_FADD, dl, Node->getVTList(),
                                 {Node->getOperand(0), Node->getOperand(1), Neg},
                         Flags);

      Results.push_back(Fadd);
      Results.push_back(Fadd.getValue(1));
      break;
    }
    case ISD::STRICT_SINT_TO_FP:
    case ISD::STRICT_UINT_TO_FP:
    case ISD::STRICT_LRINT:
    case ISD::STRICT_LLRINT:
    case ISD::STRICT_LROUND:
    case ISD::STRICT_LLROUND:
      // These are registered by the operand type instead of the value
      // type. Reflect that here.
      if (TLI.getStrictFPOperationAction(Node->getOpcode(),
                                         Node->getOperand(1).getValueType())
          == TargetLowering::Legal)
        return true;
      break;
    }
  }

  // Replace the original node with the legalized result.
  if (Results.empty()) {
    LLVM_DEBUG(dbgs() << "Cannot expand node\n");
    return false;
  }

  LLVM_DEBUG(dbgs() << "Successfully expanded node\n");
  ReplaceNode(Node, Results.data());
  return true;
}