27#define DEBUG_TYPE "legalize-types"
33 RTLIB::Libcall Call_F32,
34 RTLIB::Libcall Call_F64,
35 RTLIB::Libcall Call_F80,
36 RTLIB::Libcall Call_F128,
37 RTLIB::Libcall Call_PPCF128) {
39 VT == MVT::f32 ? Call_F32 :
40 VT == MVT::f64 ? Call_F64 :
41 VT == MVT::f80 ? Call_F80 :
42 VT == MVT::f128 ? Call_F128 :
43 VT == MVT::ppcf128 ? Call_PPCF128 :
44 RTLIB::UNKNOWN_LIBCALL;
51void DAGTypeLegalizer::SoftenFloatResult(
SDNode *
N,
unsigned ResNo) {
52 LLVM_DEBUG(
dbgs() <<
"Soften float result " << ResNo <<
": ";
N->dump(&DAG));
55 switch (
N->getOpcode()) {
59 dbgs() <<
"SoftenFloatResult #" << ResNo <<
": ";
60 N->dump(&DAG);
dbgs() <<
"\n";
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
74 R = SoftenFloatRes_FCANONICALIZE(
N);
break;
117 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
188 SetSoftenedFloat(
SDValue(
N, ResNo), R);
192SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
194 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
195 unsigned Offset = IsStrict ? 1 : 0;
197 "Unexpected number of operands!");
200 TargetLowering::MakeLibCallOptions CallOptions;
201 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
203 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
204 CallOptions, SDLoc(
N),
207 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
211SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
212 bool IsStrict =
N->isStrictFPOpcode();
213 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
214 unsigned Offset = IsStrict ? 1 : 0;
216 "Unexpected number of operands!");
218 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
220 TargetLowering::MakeLibCallOptions CallOptions;
221 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
222 N->getOperand(1 +
Offset).getValueType() };
224 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Ops,
225 CallOptions, SDLoc(
N),
228 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
233 return BitConvertToInteger(
N->getOperand(0));
237 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
239 GetSoftenedFloat(
N->getOperand(0)));
243 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
245 GetSoftenedFloat(
N->getOperand(0)));
251 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
252 return BitConvertToInteger(
Op);
258 TLI.getTypeToTransformTo(*DAG.getContext(),
260 BitConvertToInteger(
N->getOperand(0)),
261 BitConvertToInteger(
N->getOperand(1)));
273 if (DAG.getDataLayout().isBigEndian() &&
277 APInt Val(128, words);
278 return DAG.getConstant(Val, SDLoc(CN),
279 TLI.getTypeToTransformTo(*DAG.getContext(),
283 TLI.getTypeToTransformTo(*DAG.getContext(),
288SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
290 assert(Src.getValueType() == MVT::ppcf128 &&
291 "In floats only ppcf128 can be extracted by element!");
293 N->getValueType(0).changeTypeToInteger(),
294 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
297SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
298 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
301 NewOp,
N->getOperand(1));
305 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
312 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
313 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
316SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
330 SDValue One = DAG.getConstantFP(1.0, dl, VT);
331 SDValue Chain = DAG.getEntryNode();
334 SDNodeFlags CanonicalizeFlags =
N->
getFlags();
337 {Chain, Operand, One}, CanonicalizeFlags);
338 return BitConvertToInteger(
Mul);
342 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
343 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
349 RTLIB::FMIN_PPCF128));
353 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
354 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
360 RTLIB::FMAX_PPCF128));
364 return SoftenFloatRes_Binary(
366 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
367 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128));
371 return SoftenFloatRes_Binary(
373 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
374 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128));
378 return SoftenFloatRes_Binary(
380 RTLIB::FMINIMUM_F64, RTLIB::FMINIMUM_F80,
381 RTLIB::FMINIMUM_F128, RTLIB::FMINIMUM_PPCF128));
385 return SoftenFloatRes_Binary(
387 RTLIB::FMAXIMUM_F64, RTLIB::FMAXIMUM_F80,
388 RTLIB::FMAXIMUM_F128, RTLIB::FMAXIMUM_PPCF128));
397 RTLIB::ADD_PPCF128));
401 return SoftenFloatRes_Unary(
402 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ACOS_F32, RTLIB::ACOS_F64,
403 RTLIB::ACOS_F80, RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128));
407 return SoftenFloatRes_Unary(
408 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ASIN_F32, RTLIB::ASIN_F64,
409 RTLIB::ASIN_F80, RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128));
413 return SoftenFloatRes_Unary(
414 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ATAN_F32, RTLIB::ATAN_F64,
415 RTLIB::ATAN_F80, RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128));
419 return SoftenFloatRes_Binary(
421 GetFPLibCall(
N->getValueType(0), RTLIB::ATAN2_F32, RTLIB::ATAN2_F64,
422 RTLIB::ATAN2_F80, RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128));
431 RTLIB::CBRT_PPCF128));
440 RTLIB::CEIL_PPCF128));
445 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
448 EVT LVT =
LHS.getValueType();
449 EVT RVT =
RHS.getValueType();
456 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
457 DAG.getConstant(RSize - 1, dl,
458 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
466 DAG.getConstant(SizeDiff, dl,
468 DAG.getDataLayout())));
470 }
else if (SizeDiff < 0) {
474 DAG.getConstant(-SizeDiff, dl,
476 DAG.getDataLayout())));
481 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
482 DAG.getConstant(LSize - 1, dl,
483 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
484 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
488 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
497 RTLIB::COS_PPCF128));
501 return SoftenFloatRes_Unary(
502 N,
GetFPLibCall(
N->getValueType(0), RTLIB::COSH_F32, RTLIB::COSH_F64,
503 RTLIB::COSH_F80, RTLIB::COSH_F128, RTLIB::COSH_PPCF128));
512 RTLIB::DIV_PPCF128));
521 RTLIB::EXP_PPCF128));
530 RTLIB::EXP2_PPCF128));
534 return SoftenFloatRes_Unary(
536 GetFPLibCall(
N->getValueType(0), RTLIB::EXP10_F32, RTLIB::EXP10_F64,
537 RTLIB::EXP10_F80, RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128));
546 RTLIB::FLOOR_PPCF128));
555 RTLIB::LOG_PPCF128));
564 RTLIB::LOG2_PPCF128));
573 RTLIB::LOG10_PPCF128));
577 bool IsStrict =
N->isStrictFPOpcode();
578 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
579 unsigned Offset = IsStrict ? 1 : 0;
581 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
582 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
584 TargetLowering::MakeLibCallOptions CallOptions;
585 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
586 N->getOperand(1 +
Offset).getValueType(),
587 N->getOperand(2 +
Offset).getValueType() };
589 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
596 NVT,
Ops, CallOptions, SDLoc(
N), Chain);
598 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
608 RTLIB::MUL_PPCF128));
613 RTLIB::NEARBYINT_F32,
614 RTLIB::NEARBYINT_F64,
615 RTLIB::NEARBYINT_F80,
616 RTLIB::NEARBYINT_F128,
617 RTLIB::NEARBYINT_PPCF128));
621 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
626 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
627 DAG.getConstant(SignMask, dl, NVT));
631 bool IsStrict =
N->isStrictFPOpcode();
632 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
641 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
642 N->getValueType(0) != MVT::f32) {
645 { MVT::f32, MVT::Other }, { Chain,
Op });
646 Chain =
Op.getValue(1);
652 if (
Op.getValueType() == MVT::bf16) {
654 return SoftenFloatRes_BF16_TO_FP(
N);
658 if (LC == RTLIB::UNKNOWN_LIBCALL) {
659 DAG.getContext()->emitError(
"do not know how to soften fp_extend");
661 ReplaceValueWith(
SDValue(
N, 1), Chain);
662 return DAG.getPOISON(NVT);
664 TargetLowering::MakeLibCallOptions CallOptions;
665 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
667 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
668 CallOptions, SDLoc(
N),
671 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
678 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
680 TargetLowering::MakeLibCallOptions CallOptions;
681 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
683 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
684 CallOptions, SDLoc(
N)).first;
685 if (
N->getValueType(0) == MVT::f32)
688 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
690 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
691 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
697 assert(
N->getValueType(0) == MVT::f32 &&
698 "Can only soften BF16_TO_FP with f32 result");
699 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
705 DAG.getShiftAmountConstant(16, NVT,
DL));
710 bool IsStrict =
N->isStrictFPOpcode();
711 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
715 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
716 TargetLowering::MakeLibCallOptions CallOptions;
717 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
719 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
720 CallOptions, SDLoc(
N),
723 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
732 bool IsStrict =
N->isStrictFPOpcode();
733 unsigned Offset = IsStrict ? 1 : 0;
736 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
740 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
741 if (DAG.getLibcalls().getLibcallImpl(LC) == RTLIB::Unsupported) {
744 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
746 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
747 return DAG.getPOISON(NVT);
750 if (DAG.getLibInfo().getIntSize() !=
751 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
754 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
756 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
757 return DAG.getPOISON(NVT);
763 TargetLowering::MakeLibCallOptions CallOptions;
764 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
765 N->getOperand(1 +
Offset).getValueType() };
767 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Ops,
768 CallOptions, SDLoc(
N),
771 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
776 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
777 EVT VT0 =
N->getValueType(0);
778 EVT VT1 =
N->getValueType(1);
780 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
787 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
788 SDValue PoisonExp = DAG.getPOISON(VT1);
789 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
790 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
793 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
796 TargetLowering::MakeLibCallOptions CallOptions;
797 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
804 .setOpsTypeOverrides(CallOpsTypeOverrides);
806 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0,
Ops, CallOptions,
DL,
812 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
814 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
818bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
819 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
820 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
821 EVT VT =
N->getValueType(0);
823 assert(VT ==
N->getValueType(1) &&
824 "expected both return values to have the same type");
826 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
827 if (LCImpl == RTLIB::Unsupported)
830 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
837 std::array<SDValue, 2> StackSlots;
840 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
841 if (ResNum == CallRetResNo)
843 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
844 Ops.push_back(StackSlot);
846 StackSlots[ResNum] = StackSlot;
850 TargetLowering::MakeLibCallOptions CallOptions;
854 .setOpsTypeOverrides(CallOpsTypeOverrides);
856 auto [ReturnVal, Chain] =
857 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
860 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
864 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
867 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
868 if (CallRetResNo == ResNum) {
869 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
872 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
879 EVT VT =
N->getValueType(0);
888 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
889 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
890 DAG.getContext()->emitError(
"do not know how to soften fsincos");
892 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
893 SoftSin = SoftCos = DAG.getPOISON(NVT);
895 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
896 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
899 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
900 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
905 EVT VT =
N->getValueType(0);
910 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
911 DAG.getContext()->emitError(
"do not know how to soften fmodf");
924 RTLIB::REM_PPCF128));
933 RTLIB::RINT_PPCF128));
942 RTLIB::ROUND_PPCF128));
947 RTLIB::ROUNDEVEN_F32,
948 RTLIB::ROUNDEVEN_F64,
949 RTLIB::ROUNDEVEN_F80,
950 RTLIB::ROUNDEVEN_F128,
951 RTLIB::ROUNDEVEN_PPCF128));
960 RTLIB::SIN_PPCF128));
964 return SoftenFloatRes_Unary(
965 N,
GetFPLibCall(
N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
966 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
975 RTLIB::SQRT_PPCF128));
984 RTLIB::SUB_PPCF128));
988 return SoftenFloatRes_Unary(
989 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
990 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
994 return SoftenFloatRes_Unary(
995 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
996 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
1005 RTLIB::TRUNC_PPCF128));
1010 EVT VT =
N->getValueType(0);
1011 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1015 L->getMemOperand()->getFlags() &
1019 NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
1020 L->getChain(),
L->getBasePtr(),
L->getOffset(),
1021 L->getPointerInfo(), NVT,
L->getBaseAlign(), MMOFlags,
1031 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
1032 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
1033 MMOFlags,
L->getAAInfo());
1038 return BitConvertToInteger(ExtendNode);
1043 EVT VT =
N->getValueType(0);
1044 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1050 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
1064 return DAG.getSelect(SDLoc(
N),
1065 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
1072 LHS.getValueType(),
N->getOperand(0),
1073 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
1077 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1078 N->getValueType(0)));
1084 EVT VT =
N->getValueType(0);
1085 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1089 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
1090 N->getConstantOperandVal(3));
1100 bool IsStrict =
N->isStrictFPOpcode();
1103 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1104 EVT RVT =
N->getValueType(0);
1111 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1112 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1113 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1119 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1124 NVT,
N->getOperand(IsStrict ? 1 : 0));
1125 TargetLowering::MakeLibCallOptions CallOptions;
1128 std::pair<SDValue, SDValue> Tmp =
1129 TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
1130 Op, CallOptions, dl, Chain);
1133 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1139 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1143SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1144 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1152bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1153 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1156 switch (
N->getOpcode()) {
1159 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1160 N->dump(&DAG);
dbgs() <<
"\n";
1165 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1178 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1180 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1184 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1186 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1190 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1191 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1193 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1197 Res = SoftenFloatOp_FAKE_USE(
N);
1200 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1203 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1208 if (!Res.
getNode())
return false;
1216 "Invalid operand softening");
1218 ReplaceValueWith(
SDValue(
N, 0), Res);
1223 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1225 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1237 bool IsStrict =
N->isStrictFPOpcode();
1238 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1239 EVT SVT =
Op.getValueType();
1240 EVT RVT =
N->getValueType(0);
1244 FloatRVT = MVT::f16;
1247 FloatRVT = MVT::bf16;
1250 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1253 Op = GetSoftenedFloat(
Op);
1254 TargetLowering::MakeLibCallOptions CallOptions;
1256 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT,
Op,
1257 CallOptions, SDLoc(
N),
1260 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1261 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1272 NewLHS = GetSoftenedFloat(NewLHS);
1273 NewRHS = GetSoftenedFloat(NewRHS);
1274 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1275 N->getOperand(2),
N->getOperand(3));
1279 if (!NewRHS.getNode()) {
1280 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1285 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1286 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1296 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1297 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1298 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1302 if (Promoted.
bitsGE(RetVT))
1310 bool IsStrict =
N->isStrictFPOpcode();
1314 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1315 EVT SVT =
Op.getValueType();
1316 EVT RVT =
N->getValueType(0);
1326 "Unsupported FP_TO_XINT!");
1328 Op = GetSoftenedFloat(
Op);
1330 TargetLowering::MakeLibCallOptions CallOptions;
1332 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1333 CallOptions, dl, Chain);
1341 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1342 ReplaceValueWith(
SDValue(
N, 0), Res);
1346SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1347 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1356 NewLHS = GetSoftenedFloat(NewLHS);
1357 NewRHS = GetSoftenedFloat(NewRHS);
1358 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1359 N->getOperand(0),
N->getOperand(1));
1363 if (!NewRHS.getNode()) {
1364 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1369 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1370 N->getOperand(2),
N->getOperand(3),
1371 DAG.getCondCode(CCCode)),
1376 bool IsStrict =
N->isStrictFPOpcode();
1384 SDValue NewLHS = GetSoftenedFloat(Op0);
1385 SDValue NewRHS = GetSoftenedFloat(Op1);
1386 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1393 NewRHS, DAG.getCondCode(CCCode));
1395 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1396 DAG.getCondCode(CCCode)), 0);
1401 "Unexpected setcc expansion!");
1404 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1405 ReplaceValueWith(
SDValue(
N, 1), Chain);
1411SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1413 assert(OpNo == 1 &&
"Can only soften the stored value!");
1418 if (
ST->isTruncatingStore())
1420 Val = BitConvertToInteger(
1422 DAG.getIntPtrConstant(0, dl,
true)));
1424 Val = GetSoftenedFloat(Val);
1426 return DAG.getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1427 ST->getMemOperand());
1430SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1431 assert(OpNo == 1 &&
"Can only soften the stored value!");
1437 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1439 SDValue NewVal = GetSoftenedFloat(Val);
1441 ST->getBasePtr(),
ST->getMemOperand());
1446 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1449 EVT LVT =
LHS.getValueType();
1451 EVT RVT =
RHS.getValueType();
1457 int SizeDiff = RSize - LSize;
1461 DAG.getConstant(SizeDiff, dl,
1462 TLI.getShiftAmountTy(
RHS.getValueType(),
1463 DAG.getDataLayout())));
1465 }
else if (SizeDiff < 0) {
1469 DAG.getConstant(-SizeDiff, dl,
1470 TLI.getShiftAmountTy(
RHS.getValueType(),
1471 DAG.getDataLayout())));
1474 RHS = DAG.getBitcast(LVT,
RHS);
1478SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1479 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1480 bool IsStrict =
N->isStrictFPOpcode();
1481 unsigned Offset = IsStrict ? 1 : 0;
1484 TargetLowering::MakeLibCallOptions CallOptions;
1485 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1487 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1488 CallOptions, SDLoc(
N),
1491 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1492 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1500 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1506 RTLIB::LROUND_PPCF128));
1510 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1515 RTLIB::LLROUND_F128,
1516 RTLIB::LLROUND_PPCF128));
1520 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1526 RTLIB::LRINT_PPCF128));
1530 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1536 RTLIB::LLRINT_PPCF128));
1540 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1541 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1542 N->getOperand(0), Op1);
1545SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1548 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1549 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1552SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1555 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1556 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1567void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1573 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1576 switch (
N->getOpcode()) {
1579 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1580 N->dump(&DAG);
dbgs() <<
"\n";
1695 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1697 "Do not know how to expand this float constant!");
1701 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1702 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1705void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1707 bool IsStrict =
N->isStrictFPOpcode();
1708 unsigned Offset = IsStrict ? 1 : 0;
1711 TargetLowering::MakeLibCallOptions CallOptions;
1712 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1713 Op, CallOptions, SDLoc(
N),
1716 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1717 GetPairElements(Tmp.first,
Lo,
Hi);
1720void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1722 bool IsStrict =
N->isStrictFPOpcode();
1723 unsigned Offset = IsStrict ? 1 : 0;
1726 TargetLowering::MakeLibCallOptions CallOptions;
1727 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1728 Ops, CallOptions, SDLoc(
N),
1731 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1732 GetPairElements(Tmp.first,
Lo,
Hi);
1735void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1736 ExpandFloatRes_UnaryWithTwoFPResults(
N,
RTLIB::getMODF(
N->getValueType(0)),
1740void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1744void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1745 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1749void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1750 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1751 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1753 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1756 GetPairElements(Res,
Lo,
Hi);
1763 assert(
N->getValueType(0) == MVT::ppcf128 &&
1764 "Logic only correct for ppcf128!");
1767 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1770 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1778 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1779 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1780 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1786 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1787 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1788 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1793 ExpandFloatRes_Binary(
1796 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
1797 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128),
1803 ExpandFloatRes_Binary(
1806 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
1807 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128),
1814 RTLIB::ADD_F32, RTLIB::ADD_F64,
1815 RTLIB::ADD_F80, RTLIB::ADD_F128,
1816 RTLIB::ADD_PPCF128),
Lo,
Hi);
1821 ExpandFloatRes_Unary(
N,
1823 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1824 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1830 ExpandFloatRes_Unary(
N,
1832 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1833 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1839 ExpandFloatRes_Unary(
N,
1841 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1842 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1848 ExpandFloatRes_Binary(
N,
1850 RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
1851 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128),
1857 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1858 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1860 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1863void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1866 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1867 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1868 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1871void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1874 RTLIB::COPYSIGN_F32,
1875 RTLIB::COPYSIGN_F64,
1876 RTLIB::COPYSIGN_F80,
1877 RTLIB::COPYSIGN_F128,
1878 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1881void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1884 RTLIB::COS_F32, RTLIB::COS_F64,
1885 RTLIB::COS_F80, RTLIB::COS_F128,
1886 RTLIB::COS_PPCF128),
Lo,
Hi);
1891 ExpandFloatRes_Unary(
N,
1893 RTLIB::COSH_F64, RTLIB::COSH_F80,
1894 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1905 RTLIB::DIV_PPCF128),
Lo,
Hi);
1908void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1911 RTLIB::EXP_F32, RTLIB::EXP_F64,
1912 RTLIB::EXP_F80, RTLIB::EXP_F128,
1913 RTLIB::EXP_PPCF128),
Lo,
Hi);
1916void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1919 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1920 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1921 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1926 ExpandFloatRes_Unary(
N,
1928 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1929 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1933void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1936 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1937 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1938 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1941void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1944 RTLIB::LOG_F32, RTLIB::LOG_F64,
1945 RTLIB::LOG_F80, RTLIB::LOG_F128,
1946 RTLIB::LOG_PPCF128),
Lo,
Hi);
1949void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1952 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1953 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1954 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1957void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1960 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1961 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1962 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1967 bool IsStrict =
N->isStrictFPOpcode();
1968 unsigned Offset = IsStrict ? 1 : 0;
1972 TargetLowering::MakeLibCallOptions CallOptions;
1973 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
GetFPLibCall(
N->getValueType(0),
1978 RTLIB::FMA_PPCF128),
1979 N->getValueType(0),
Ops, CallOptions,
1982 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1983 GetPairElements(Tmp.first,
Lo,
Hi);
1993 RTLIB::MUL_PPCF128),
Lo,
Hi);
1996void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1999 RTLIB::NEARBYINT_F32,
2000 RTLIB::NEARBYINT_F64,
2001 RTLIB::NEARBYINT_F80,
2002 RTLIB::NEARBYINT_F128,
2003 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
2009 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2014void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
2018 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2023 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
2025 bool IsStrict =
N->isStrictFPOpcode();
2030 if (NVT ==
N->getOperand(1).getValueType()) {
2031 Hi =
N->getOperand(1);
2036 {
N->getOperand(0),
N->getOperand(1) });
2046 ReplaceValueWith(
SDValue(
N, 1), Chain);
2049void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
2052 RTLIB::POW_F32, RTLIB::POW_F64,
2053 RTLIB::POW_F80, RTLIB::POW_F128,
2054 RTLIB::POW_PPCF128),
Lo,
Hi);
2057void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
2067void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
2069 assert(
N->getValueType(0) == MVT::ppcf128 &&
2070 "Logic only correct for ppcf128!");
2073 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2078void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
2081 RTLIB::REM_F32, RTLIB::REM_F64,
2082 RTLIB::REM_F80, RTLIB::REM_F128,
2083 RTLIB::REM_PPCF128),
Lo,
Hi);
2086void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
2089 RTLIB::RINT_F32, RTLIB::RINT_F64,
2090 RTLIB::RINT_F80, RTLIB::RINT_F128,
2091 RTLIB::RINT_PPCF128),
Lo,
Hi);
2094void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
2101 RTLIB::ROUND_PPCF128),
Lo,
Hi);
2104void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
2107 RTLIB::ROUNDEVEN_F32,
2108 RTLIB::ROUNDEVEN_F64,
2109 RTLIB::ROUNDEVEN_F80,
2110 RTLIB::ROUNDEVEN_F128,
2111 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
2114void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
2117 RTLIB::SIN_F32, RTLIB::SIN_F64,
2118 RTLIB::SIN_F80, RTLIB::SIN_F128,
2119 RTLIB::SIN_PPCF128),
Lo,
Hi);
2124 ExpandFloatRes_Unary(
N,
2126 RTLIB::SINH_F64, RTLIB::SINH_F80,
2127 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
2131void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
2134 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
2135 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
2136 RTLIB::SQRT_PPCF128),
Lo,
Hi);
2146 RTLIB::SUB_PPCF128),
Lo,
Hi);
2151 ExpandFloatRes_Unary(
N,
2153 RTLIB::TAN_F64, RTLIB::TAN_F80,
2154 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
2160 ExpandFloatRes_Unary(
N,
2162 RTLIB::TANH_F64, RTLIB::TANH_F80,
2163 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
2167void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2170 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
2171 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
2172 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
2178 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2188 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2190 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2192 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2193 LD->getMemoryVT(),
LD->getMemOperand());
2203 ReplaceValueWith(
SDValue(LD, 1), Chain);
2208 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2209 EVT VT =
N->getValueType(0);
2210 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2211 bool Strict =
N->isStrictFPOpcode();
2212 SDValue Src =
N->getOperand(Strict ? 1 : 0);
2213 EVT SrcVT = Src.getValueType();
2221 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2226 if (SrcVT.
bitsLE(MVT::i32)) {
2230 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2231 {Chain, Src}, Flags);
2234 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2236 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2237 if (SrcVT.
bitsLE(MVT::i64)) {
2240 LC = RTLIB::SINTTOFP_I64_PPCF128;
2241 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2243 LC = RTLIB::SINTTOFP_I128_PPCF128;
2245 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2247 TargetLowering::MakeLibCallOptions CallOptions;
2249 std::pair<SDValue, SDValue> Tmp =
2250 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2253 GetPairElements(Tmp.first,
Lo,
Hi);
2257 if (isSigned || SrcVT.
bitsLE(MVT::i32)) {
2259 ReplaceValueWith(
SDValue(
N, 1), Chain);
2269 SrcVT = Src.getValueType();
2272 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2273 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2274 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2275 ArrayRef<uint64_t> Parts;
2292 SDValue NewLo = DAG.getConstantFP(
2296 {Chain, Hi, NewLo}, Flags);
2298 ReplaceValueWith(
SDValue(
N, 1), Chain);
2301 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2303 GetPairElements(
Lo,
Lo,
Hi);
2315bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2320 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2323 switch (
N->getOpcode()) {
2326 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2327 N->dump(&DAG);
dbgs() <<
"\n";
2335 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2343 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2345 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2346 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2350 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2356 if (!Res.
getNode())
return false;
2364 "Invalid operand expansion");
2366 ReplaceValueWith(
SDValue(
N, 0), Res);
2372void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2377 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2378 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2379 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2388 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2389 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2392 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2393 RHSLo, CCCode, OutputChain, IsSignaling);
2397 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2400 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2401 RHSHi, CCCode, OutputChain, IsSignaling);
2406 Chain = OutputChain;
2413 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2418 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2423 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2424 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2425 N->getOperand(4)), 0);
2429 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2430 "Logic only correct for ppcf128!");
2432 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2436 N->getValueType(0),
N->getOperand(0),
Hi);
2440 bool IsStrict =
N->isStrictFPOpcode();
2441 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2442 "Logic only correct for ppcf128!");
2444 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2449 N->getValueType(0),
Hi,
N->getOperand(1));
2453 if (
Hi.getValueType() ==
N->getValueType(0)) {
2455 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2461 {
N->getValueType(0), MVT::Other},
2462 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2469 EVT RVT =
N->getValueType(0);
2472 bool IsStrict =
N->isStrictFPOpcode();
2475 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2481 "Unsupported FP_TO_XINT!");
2482 TargetLowering::MakeLibCallOptions CallOptions;
2483 std::pair<SDValue, SDValue> Tmp =
2484 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2488 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2489 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2497 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2502 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2507 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2508 N->getOperand(2),
N->getOperand(3),
2509 DAG.getCondCode(CCCode)), 0);
2513 bool IsStrict =
N->isStrictFPOpcode();
2519 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2525 "Unexpected setcc expansion!");
2527 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2528 ReplaceValueWith(
SDValue(
N, 1), Chain);
2534SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2536 return ExpandOp_NormalStore(
N, OpNo);
2539 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2545 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2546 ST->getValue().getValueType());
2548 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2552 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2554 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2555 ST->getMemoryVT(),
ST->getMemOperand());
2559 EVT RVT =
N->getValueType(0);
2560 EVT RetVT =
N->getOperand(0).getValueType();
2561 TargetLowering::MakeLibCallOptions CallOptions;
2567 RTLIB::LROUND_PPCF128),
2568 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2572 EVT RVT =
N->getValueType(0);
2573 EVT RetVT =
N->getOperand(0).getValueType();
2574 TargetLowering::MakeLibCallOptions CallOptions;
2579 RTLIB::LLROUND_F128,
2580 RTLIB::LLROUND_PPCF128),
2581 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2585 EVT RVT =
N->getValueType(0);
2586 EVT RetVT =
N->getOperand(0).getValueType();
2587 TargetLowering::MakeLibCallOptions CallOptions;
2593 RTLIB::LRINT_PPCF128),
2594 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2598 EVT RVT =
N->getValueType(0);
2599 EVT RetVT =
N->getOperand(0).getValueType();
2600 TargetLowering::MakeLibCallOptions CallOptions;
2606 RTLIB::LLRINT_PPCF128),
2607 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2616 if (OpVT == MVT::f16)
2618 if (RetVT == MVT::f16)
2620 if (OpVT == MVT::bf16)
2622 if (RetVT == MVT::bf16)
2628 if (OpVT == MVT::f16)
2630 if (RetVT == MVT::f16)
2632 if (OpVT == MVT::bf16)
2634 if (RetVT == MVT::bf16)
2648 DAG.getVTList(CastVT, MVT::Other),
2649 { AM->getChain(), AM->getBasePtr(), CastVal },
2665void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2666 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2671 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2676 switch (
N->getOpcode()) {
2679 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2680 N->dump(&DAG);
dbgs() <<
"\n";
2686 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2690 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2723 R = SoftPromoteHalfRes_FABS(
N);
2726 R = SoftPromoteHalfRes_FNEG(
N);
2729 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2745 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2748 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2758 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2761 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2763 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2772 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2780 R = SoftPromoteHalfRes_VECREDUCE(
N);
2784 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2789 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2792SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2794 BitConvertToInteger(
N->getOperand(0)));
2798 return BitConvertToInteger(
N->getOperand(0));
2801SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2809SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2810 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2816SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2817 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2818 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2821 EVT LVT =
LHS.getValueType();
2822 EVT RVT =
RHS.getValueType();
2829 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2830 DAG.getConstant(RSize - 1, dl,
2831 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2839 DAG.getConstant(SizeDiff, dl,
2841 DAG.getDataLayout())));
2843 }
else if (SizeDiff < 0) {
2847 DAG.getConstant(-SizeDiff, dl,
2849 DAG.getDataLayout())));
2854 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2855 DAG.getConstant(LSize - 1, dl,
2856 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2857 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2861 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2866 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2867 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2868 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2869 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2870 SDNodeFlags
Flags =
N->getFlags();
2875 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2876 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2877 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2880 if (OVT == MVT::f16) {
2889 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2900 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2905 EVT OVT =
N->getValueType(0);
2906 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2907 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2921 EVT OVT =
N->getValueType(0);
2922 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2923 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2930 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2938SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2939 EVT OVT =
N->getValueType(0);
2940 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2941 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2950 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2952 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2953 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2959SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2960 EVT RVT =
N->getValueType(0);
2961 bool IsStrict =
N->isStrictFPOpcode();
2962 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2963 EVT SVT =
Op.getValueType();
2969 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2972 Op = GetSoftenedFloat(
Op);
2973 TargetLowering::MakeLibCallOptions CallOptions;
2975 std::pair<SDValue, SDValue> Tmp =
2976 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2978 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2979 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2984 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2999 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
3000 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
3001 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
3002 L->getMemOperand()->getFlags(),
L->getAAInfo());
3009SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3024 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3025 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3026 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1,
3030SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3031 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3032 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3034 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3038SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3039 EVT OVT =
N->getValueType(0);
3040 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3043 if (
N->isStrictFPOpcode()) {
3044 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
3045 {N->getOperand(0), N->getOperand(1)});
3047 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
3048 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3059 return DAG.getUNDEF(MVT::i16);
3063 EVT OVT =
N->getValueType(0);
3064 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3065 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3078 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3082 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
3083 DAG.getConstant(0x7fff, dl, MVT::i16));
3087 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3091 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
3092 DAG.getConstant(0x8000, dl, MVT::i16));
3095SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
3096 return GetSoftPromotedHalf(
N->getOperand(0));
3100 EVT OVT =
N->getValueType(0);
3101 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3102 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3103 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3108 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3109 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3117SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3119 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3123SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3125 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3133bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3134 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3138 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3148 switch (
N->getOpcode()) {
3151 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3152 N->dump(&DAG);
dbgs() <<
"\n";
3157 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3159 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3162 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3176 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3180 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3183 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3184 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3185 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3187 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3190 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3193 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3203 "Invalid operand expansion");
3205 ReplaceValueWith(
SDValue(
N, 0), Res);
3210 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3212 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3215SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3216 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3217 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3218 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3224 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3229 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3231 Op1 = GetSoftPromotedHalf(Op1);
3234 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3238SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3239 EVT RVT =
N->getValueType(0);
3240 bool IsStrict =
N->isStrictFPOpcode();
3241 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3242 EVT SVT =
Op.getValueType();
3243 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3247 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3249 ReplaceValueWith(
SDValue(
N, 0), Res);
3256SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3257 EVT RVT =
N->getValueType(0);
3258 bool IsStrict =
N->isStrictFPOpcode();
3259 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3260 EVT SVT =
Op.getValueType();
3263 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3264 Op = GetSoftPromotedHalf(
Op);
3268 {
N->getOperand(0),
Op});
3269 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3270 {Op.getValue(1), Op});
3271 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3277 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3280SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3281 EVT RVT =
N->getValueType(0);
3283 EVT SVT =
Op.getValueType();
3286 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3288 Op = GetSoftPromotedHalf(
Op);
3292 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3298 assert(OpNo == 0 &&
"Can only soften the comparison values");
3304 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3306 Op0 = GetSoftPromotedHalf(Op0);
3307 Op1 = GetSoftPromotedHalf(Op1);
3311 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3312 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3315 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3325 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3327 Op0 = GetSoftPromotedHalf(Op0);
3328 Op1 = GetSoftPromotedHalf(Op1);
3332 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3333 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3335 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3338SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3339 assert(OpNo == 1 &&
"Can only soften the stored value!");
3344 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3345 SDValue Promoted = GetSoftPromotedHalf(Val);
3346 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3347 ST->getMemOperand());
3350SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3352 assert(OpNo == 1 &&
"Can only soften the stored value!");
3357 SDValue Promoted = GetSoftPromotedHalf(Val);
3359 ST->getChain(), Promoted,
ST->getBasePtr(),
3360 ST->getMemOperand());
3363SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3367 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3369 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3371 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3382 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3384 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3386 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted, bool Signed)
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)
GetFPLibCall - Return the right libcall for the given floating point type.
static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT)
static ISD::NodeType GetPromotionOpcodeStrict(EVT OpVT, EVT RetVT)
static Type * getValueType(Value *V)
Returns the type of the given value/instruction V.
static const fltSemantics & PPCDoubleDouble()
APInt bitcastToAPInt() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
const SDValue & getVal() const
const APFloat & getValueAPF() const
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ PATCHPOINT
The llvm.experimental.patchpoint.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ STACKMAP
The llvm.experimental.stackmap intrinsic.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
LLVM_ABI Libcall getPOWI(EVT RetVT)
getPOWI - Return the POWI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getLDEXP(EVT RetVT)
getLDEXP - Return the LDEXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFREXP(EVT RetVT)
getFREXP - Return the FREXP_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOSPI(EVT RetVT)
getSINCOSPI - Return the SINCOSPI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getCOS(EVT RetVT)
Return the COS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT VT)
getMODF - Return the MODF_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSIN(EVT RetVT)
Return the SIN_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getPOW(EVT RetVT)
getPOW - Return the POW_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getSINCOS(EVT RetVT)
getSINCOS - Return the SINCOS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Mul
Product of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
LLVM_ABI const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
void setNoFPExcept(bool b)
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT)
MakeLibCallOptions & setIsSigned(bool Value=true)