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 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
659 TargetLowering::MakeLibCallOptions CallOptions;
660 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
662 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
663 CallOptions, SDLoc(
N),
666 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
673 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
675 TargetLowering::MakeLibCallOptions CallOptions;
676 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
678 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
679 CallOptions, SDLoc(
N)).first;
680 if (
N->getValueType(0) == MVT::f32)
683 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
685 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
686 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
692 assert(
N->getValueType(0) == MVT::f32 &&
693 "Can only soften BF16_TO_FP with f32 result");
694 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
700 DAG.getShiftAmountConstant(16, NVT,
DL));
705 bool IsStrict =
N->isStrictFPOpcode();
706 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
710 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
711 TargetLowering::MakeLibCallOptions CallOptions;
712 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
714 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
715 CallOptions, SDLoc(
N),
718 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
727 bool IsStrict =
N->isStrictFPOpcode();
728 unsigned Offset = IsStrict ? 1 : 0;
731 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
735 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
736 if (DAG.getLibcalls().getLibcallImpl(LC) == RTLIB::Unsupported) {
739 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
741 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
742 return DAG.getPOISON(NVT);
745 if (DAG.getLibInfo().getIntSize() !=
746 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
749 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
751 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
752 return DAG.getPOISON(NVT);
758 TargetLowering::MakeLibCallOptions CallOptions;
759 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
760 N->getOperand(1 +
Offset).getValueType() };
762 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Ops,
763 CallOptions, SDLoc(
N),
766 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
771 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
772 EVT VT0 =
N->getValueType(0);
773 EVT VT1 =
N->getValueType(1);
775 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
782 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
783 SDValue PoisonExp = DAG.getPOISON(VT1);
784 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
785 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
788 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
791 TargetLowering::MakeLibCallOptions CallOptions;
792 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
799 .setOpsTypeOverrides(CallOpsTypeOverrides);
801 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0,
Ops, CallOptions,
DL,
807 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
809 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
813bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
814 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
815 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
816 EVT VT =
N->getValueType(0);
818 assert(VT ==
N->getValueType(1) &&
819 "expected both return values to have the same type");
821 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
822 if (LCImpl == RTLIB::Unsupported)
825 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
832 std::array<SDValue, 2> StackSlots;
835 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
836 if (ResNum == CallRetResNo)
838 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
839 Ops.push_back(StackSlot);
841 StackSlots[ResNum] = StackSlot;
845 TargetLowering::MakeLibCallOptions CallOptions;
849 .setOpsTypeOverrides(CallOpsTypeOverrides);
851 auto [ReturnVal, Chain] =
852 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
855 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
859 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
862 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
863 if (CallRetResNo == ResNum) {
864 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
867 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
874 EVT VT =
N->getValueType(0);
883 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
884 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
885 DAG.getContext()->emitError(
"do not know how to soften fsincos");
887 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
888 SoftSin = SoftCos = DAG.getPOISON(NVT);
890 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
891 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
894 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
895 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
900 EVT VT =
N->getValueType(0);
905 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
906 DAG.getContext()->emitError(
"do not know how to soften fmodf");
919 RTLIB::REM_PPCF128));
928 RTLIB::RINT_PPCF128));
937 RTLIB::ROUND_PPCF128));
942 RTLIB::ROUNDEVEN_F32,
943 RTLIB::ROUNDEVEN_F64,
944 RTLIB::ROUNDEVEN_F80,
945 RTLIB::ROUNDEVEN_F128,
946 RTLIB::ROUNDEVEN_PPCF128));
955 RTLIB::SIN_PPCF128));
959 return SoftenFloatRes_Unary(
960 N,
GetFPLibCall(
N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
961 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
970 RTLIB::SQRT_PPCF128));
979 RTLIB::SUB_PPCF128));
983 return SoftenFloatRes_Unary(
984 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
985 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
989 return SoftenFloatRes_Unary(
990 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
991 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
1000 RTLIB::TRUNC_PPCF128));
1005 EVT VT =
N->getValueType(0);
1006 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1010 L->getMemOperand()->getFlags() &
1014 NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
1015 L->getChain(),
L->getBasePtr(),
L->getOffset(),
1016 L->getPointerInfo(), NVT,
L->getBaseAlign(), MMOFlags,
1026 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
1027 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
1028 MMOFlags,
L->getAAInfo());
1033 return BitConvertToInteger(ExtendNode);
1038 EVT VT =
N->getValueType(0);
1039 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1045 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
1059 return DAG.getSelect(SDLoc(
N),
1060 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
1067 LHS.getValueType(),
N->getOperand(0),
1068 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
1072 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1073 N->getValueType(0)));
1079 EVT VT =
N->getValueType(0);
1080 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1084 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
1085 N->getConstantOperandVal(3));
1095 bool IsStrict =
N->isStrictFPOpcode();
1098 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1099 EVT RVT =
N->getValueType(0);
1106 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1107 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1108 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1114 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1119 NVT,
N->getOperand(IsStrict ? 1 : 0));
1120 TargetLowering::MakeLibCallOptions CallOptions;
1123 std::pair<SDValue, SDValue> Tmp =
1124 TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
1125 Op, CallOptions, dl, Chain);
1128 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1134 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1138SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1139 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1147bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1148 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1151 switch (
N->getOpcode()) {
1154 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1155 N->dump(&DAG);
dbgs() <<
"\n";
1160 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1173 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1175 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1179 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1181 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1185 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1186 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1188 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1192 Res = SoftenFloatOp_FAKE_USE(
N);
1195 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1198 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1203 if (!Res.
getNode())
return false;
1211 "Invalid operand softening");
1213 ReplaceValueWith(
SDValue(
N, 0), Res);
1218 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1220 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1232 bool IsStrict =
N->isStrictFPOpcode();
1233 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1234 EVT SVT =
Op.getValueType();
1235 EVT RVT =
N->getValueType(0);
1239 FloatRVT = MVT::f16;
1242 FloatRVT = MVT::bf16;
1245 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1248 Op = GetSoftenedFloat(
Op);
1249 TargetLowering::MakeLibCallOptions CallOptions;
1251 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT,
Op,
1252 CallOptions, SDLoc(
N),
1255 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1256 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1267 NewLHS = GetSoftenedFloat(NewLHS);
1268 NewRHS = GetSoftenedFloat(NewRHS);
1269 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1270 N->getOperand(2),
N->getOperand(3));
1274 if (!NewRHS.getNode()) {
1275 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1280 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1281 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1291 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1292 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1293 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1297 if (Promoted.
bitsGE(RetVT))
1305 bool IsStrict =
N->isStrictFPOpcode();
1309 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1310 EVT SVT =
Op.getValueType();
1311 EVT RVT =
N->getValueType(0);
1321 "Unsupported FP_TO_XINT!");
1323 Op = GetSoftenedFloat(
Op);
1325 TargetLowering::MakeLibCallOptions CallOptions;
1327 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1328 CallOptions, dl, Chain);
1336 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1337 ReplaceValueWith(
SDValue(
N, 0), Res);
1341SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1342 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1351 NewLHS = GetSoftenedFloat(NewLHS);
1352 NewRHS = GetSoftenedFloat(NewRHS);
1353 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1354 N->getOperand(0),
N->getOperand(1));
1358 if (!NewRHS.getNode()) {
1359 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1364 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1365 N->getOperand(2),
N->getOperand(3),
1366 DAG.getCondCode(CCCode)),
1371 bool IsStrict =
N->isStrictFPOpcode();
1379 SDValue NewLHS = GetSoftenedFloat(Op0);
1380 SDValue NewRHS = GetSoftenedFloat(Op1);
1381 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1388 NewRHS, DAG.getCondCode(CCCode));
1390 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1391 DAG.getCondCode(CCCode)), 0);
1396 "Unexpected setcc expansion!");
1399 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1400 ReplaceValueWith(
SDValue(
N, 1), Chain);
1406SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1408 assert(OpNo == 1 &&
"Can only soften the stored value!");
1413 if (
ST->isTruncatingStore())
1415 Val = BitConvertToInteger(
1417 DAG.getIntPtrConstant(0, dl,
true)));
1419 Val = GetSoftenedFloat(Val);
1421 return DAG.getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1422 ST->getMemOperand());
1425SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1426 assert(OpNo == 1 &&
"Can only soften the stored value!");
1432 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1434 SDValue NewVal = GetSoftenedFloat(Val);
1436 ST->getBasePtr(),
ST->getMemOperand());
1441 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1444 EVT LVT =
LHS.getValueType();
1446 EVT RVT =
RHS.getValueType();
1452 int SizeDiff = RSize - LSize;
1456 DAG.getConstant(SizeDiff, dl,
1457 TLI.getShiftAmountTy(
RHS.getValueType(),
1458 DAG.getDataLayout())));
1460 }
else if (SizeDiff < 0) {
1464 DAG.getConstant(-SizeDiff, dl,
1465 TLI.getShiftAmountTy(
RHS.getValueType(),
1466 DAG.getDataLayout())));
1469 RHS = DAG.getBitcast(LVT,
RHS);
1473SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1474 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1475 bool IsStrict =
N->isStrictFPOpcode();
1476 unsigned Offset = IsStrict ? 1 : 0;
1479 TargetLowering::MakeLibCallOptions CallOptions;
1480 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1482 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1483 CallOptions, SDLoc(
N),
1486 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1487 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1495 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1501 RTLIB::LROUND_PPCF128));
1505 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1510 RTLIB::LLROUND_F128,
1511 RTLIB::LLROUND_PPCF128));
1515 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1521 RTLIB::LRINT_PPCF128));
1525 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1531 RTLIB::LLRINT_PPCF128));
1535 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1536 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1537 N->getOperand(0), Op1);
1540SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1543 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1544 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1547SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1550 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1551 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1562void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1568 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1571 switch (
N->getOpcode()) {
1574 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1575 N->dump(&DAG);
dbgs() <<
"\n";
1690 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1692 "Do not know how to expand this float constant!");
1696 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1697 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1700void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1702 bool IsStrict =
N->isStrictFPOpcode();
1703 unsigned Offset = IsStrict ? 1 : 0;
1706 TargetLowering::MakeLibCallOptions CallOptions;
1707 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1708 Op, CallOptions, SDLoc(
N),
1711 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1712 GetPairElements(Tmp.first,
Lo,
Hi);
1715void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1717 bool IsStrict =
N->isStrictFPOpcode();
1718 unsigned Offset = IsStrict ? 1 : 0;
1721 TargetLowering::MakeLibCallOptions CallOptions;
1722 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1723 Ops, CallOptions, SDLoc(
N),
1726 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1727 GetPairElements(Tmp.first,
Lo,
Hi);
1730void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1731 ExpandFloatRes_UnaryWithTwoFPResults(
N,
RTLIB::getMODF(
N->getValueType(0)),
1735void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1739void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1740 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1744void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1745 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1746 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1748 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1751 GetPairElements(Res,
Lo,
Hi);
1758 assert(
N->getValueType(0) == MVT::ppcf128 &&
1759 "Logic only correct for ppcf128!");
1762 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1765 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1773 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1774 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1775 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1781 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1782 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1783 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1788 ExpandFloatRes_Binary(
1791 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
1792 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128),
1798 ExpandFloatRes_Binary(
1801 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
1802 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128),
1809 RTLIB::ADD_F32, RTLIB::ADD_F64,
1810 RTLIB::ADD_F80, RTLIB::ADD_F128,
1811 RTLIB::ADD_PPCF128),
Lo,
Hi);
1816 ExpandFloatRes_Unary(
N,
1818 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1819 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1825 ExpandFloatRes_Unary(
N,
1827 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1828 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1834 ExpandFloatRes_Unary(
N,
1836 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1837 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1843 ExpandFloatRes_Binary(
N,
1845 RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
1846 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128),
1852 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1853 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1855 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1858void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1861 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1862 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1863 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1866void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1869 RTLIB::COPYSIGN_F32,
1870 RTLIB::COPYSIGN_F64,
1871 RTLIB::COPYSIGN_F80,
1872 RTLIB::COPYSIGN_F128,
1873 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1876void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1879 RTLIB::COS_F32, RTLIB::COS_F64,
1880 RTLIB::COS_F80, RTLIB::COS_F128,
1881 RTLIB::COS_PPCF128),
Lo,
Hi);
1886 ExpandFloatRes_Unary(
N,
1888 RTLIB::COSH_F64, RTLIB::COSH_F80,
1889 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1900 RTLIB::DIV_PPCF128),
Lo,
Hi);
1903void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1906 RTLIB::EXP_F32, RTLIB::EXP_F64,
1907 RTLIB::EXP_F80, RTLIB::EXP_F128,
1908 RTLIB::EXP_PPCF128),
Lo,
Hi);
1911void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1914 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1915 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1916 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1921 ExpandFloatRes_Unary(
N,
1923 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1924 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1928void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1931 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1932 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1933 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1936void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1939 RTLIB::LOG_F32, RTLIB::LOG_F64,
1940 RTLIB::LOG_F80, RTLIB::LOG_F128,
1941 RTLIB::LOG_PPCF128),
Lo,
Hi);
1944void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1947 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1948 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1949 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1952void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1955 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1956 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1957 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1962 bool IsStrict =
N->isStrictFPOpcode();
1963 unsigned Offset = IsStrict ? 1 : 0;
1967 TargetLowering::MakeLibCallOptions CallOptions;
1968 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
GetFPLibCall(
N->getValueType(0),
1973 RTLIB::FMA_PPCF128),
1974 N->getValueType(0),
Ops, CallOptions,
1977 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1978 GetPairElements(Tmp.first,
Lo,
Hi);
1988 RTLIB::MUL_PPCF128),
Lo,
Hi);
1991void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1994 RTLIB::NEARBYINT_F32,
1995 RTLIB::NEARBYINT_F64,
1996 RTLIB::NEARBYINT_F80,
1997 RTLIB::NEARBYINT_F128,
1998 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
2004 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2009void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
2013 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2018 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
2020 bool IsStrict =
N->isStrictFPOpcode();
2025 if (NVT ==
N->getOperand(1).getValueType()) {
2026 Hi =
N->getOperand(1);
2031 {
N->getOperand(0),
N->getOperand(1) });
2041 ReplaceValueWith(
SDValue(
N, 1), Chain);
2044void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
2047 RTLIB::POW_F32, RTLIB::POW_F64,
2048 RTLIB::POW_F80, RTLIB::POW_F128,
2049 RTLIB::POW_PPCF128),
Lo,
Hi);
2052void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
2062void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
2064 assert(
N->getValueType(0) == MVT::ppcf128 &&
2065 "Logic only correct for ppcf128!");
2068 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2073void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
2076 RTLIB::REM_F32, RTLIB::REM_F64,
2077 RTLIB::REM_F80, RTLIB::REM_F128,
2078 RTLIB::REM_PPCF128),
Lo,
Hi);
2081void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
2084 RTLIB::RINT_F32, RTLIB::RINT_F64,
2085 RTLIB::RINT_F80, RTLIB::RINT_F128,
2086 RTLIB::RINT_PPCF128),
Lo,
Hi);
2089void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
2096 RTLIB::ROUND_PPCF128),
Lo,
Hi);
2099void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
2102 RTLIB::ROUNDEVEN_F32,
2103 RTLIB::ROUNDEVEN_F64,
2104 RTLIB::ROUNDEVEN_F80,
2105 RTLIB::ROUNDEVEN_F128,
2106 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
2109void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
2112 RTLIB::SIN_F32, RTLIB::SIN_F64,
2113 RTLIB::SIN_F80, RTLIB::SIN_F128,
2114 RTLIB::SIN_PPCF128),
Lo,
Hi);
2119 ExpandFloatRes_Unary(
N,
2121 RTLIB::SINH_F64, RTLIB::SINH_F80,
2122 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
2126void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
2129 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
2130 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
2131 RTLIB::SQRT_PPCF128),
Lo,
Hi);
2141 RTLIB::SUB_PPCF128),
Lo,
Hi);
2146 ExpandFloatRes_Unary(
N,
2148 RTLIB::TAN_F64, RTLIB::TAN_F80,
2149 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
2155 ExpandFloatRes_Unary(
N,
2157 RTLIB::TANH_F64, RTLIB::TANH_F80,
2158 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
2162void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2165 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
2166 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
2167 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
2173 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2183 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2185 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2187 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2188 LD->getMemoryVT(),
LD->getMemOperand());
2198 ReplaceValueWith(
SDValue(LD, 1), Chain);
2203 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2204 EVT VT =
N->getValueType(0);
2205 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2206 bool Strict =
N->isStrictFPOpcode();
2207 SDValue Src =
N->getOperand(Strict ? 1 : 0);
2208 EVT SrcVT = Src.getValueType();
2216 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2221 if (SrcVT.
bitsLE(MVT::i32)) {
2225 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2226 {Chain, Src}, Flags);
2229 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2231 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2232 if (SrcVT.
bitsLE(MVT::i64)) {
2235 LC = RTLIB::SINTTOFP_I64_PPCF128;
2236 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2238 LC = RTLIB::SINTTOFP_I128_PPCF128;
2240 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2242 TargetLowering::MakeLibCallOptions CallOptions;
2244 std::pair<SDValue, SDValue> Tmp =
2245 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2248 GetPairElements(Tmp.first,
Lo,
Hi);
2252 if (isSigned || SrcVT.
bitsLE(MVT::i32)) {
2254 ReplaceValueWith(
SDValue(
N, 1), Chain);
2264 SrcVT = Src.getValueType();
2267 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2268 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2269 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2270 ArrayRef<uint64_t> Parts;
2287 SDValue NewLo = DAG.getConstantFP(
2291 {Chain, Hi, NewLo}, Flags);
2293 ReplaceValueWith(
SDValue(
N, 1), Chain);
2296 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2298 GetPairElements(
Lo,
Lo,
Hi);
2310bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2315 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2318 switch (
N->getOpcode()) {
2321 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2322 N->dump(&DAG);
dbgs() <<
"\n";
2330 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2338 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2340 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2341 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2345 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2351 if (!Res.
getNode())
return false;
2359 "Invalid operand expansion");
2361 ReplaceValueWith(
SDValue(
N, 0), Res);
2367void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2372 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2373 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2374 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2383 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2384 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2387 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2388 RHSLo, CCCode, OutputChain, IsSignaling);
2392 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2395 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2396 RHSHi, CCCode, OutputChain, IsSignaling);
2401 Chain = OutputChain;
2408 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2413 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2418 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2419 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2420 N->getOperand(4)), 0);
2424 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2425 "Logic only correct for ppcf128!");
2427 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2431 N->getValueType(0),
N->getOperand(0),
Hi);
2435 bool IsStrict =
N->isStrictFPOpcode();
2436 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2437 "Logic only correct for ppcf128!");
2439 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2444 N->getValueType(0),
Hi,
N->getOperand(1));
2448 if (
Hi.getValueType() ==
N->getValueType(0)) {
2450 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2456 {
N->getValueType(0), MVT::Other},
2457 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2464 EVT RVT =
N->getValueType(0);
2467 bool IsStrict =
N->isStrictFPOpcode();
2470 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2476 "Unsupported FP_TO_XINT!");
2477 TargetLowering::MakeLibCallOptions CallOptions;
2478 std::pair<SDValue, SDValue> Tmp =
2479 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2483 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2484 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2492 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2497 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2502 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2503 N->getOperand(2),
N->getOperand(3),
2504 DAG.getCondCode(CCCode)), 0);
2508 bool IsStrict =
N->isStrictFPOpcode();
2514 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2520 "Unexpected setcc expansion!");
2522 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2523 ReplaceValueWith(
SDValue(
N, 1), Chain);
2529SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2531 return ExpandOp_NormalStore(
N, OpNo);
2534 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2540 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2541 ST->getValue().getValueType());
2543 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2547 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2549 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2550 ST->getMemoryVT(),
ST->getMemOperand());
2554 EVT RVT =
N->getValueType(0);
2555 EVT RetVT =
N->getOperand(0).getValueType();
2556 TargetLowering::MakeLibCallOptions CallOptions;
2562 RTLIB::LROUND_PPCF128),
2563 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2567 EVT RVT =
N->getValueType(0);
2568 EVT RetVT =
N->getOperand(0).getValueType();
2569 TargetLowering::MakeLibCallOptions CallOptions;
2574 RTLIB::LLROUND_F128,
2575 RTLIB::LLROUND_PPCF128),
2576 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2580 EVT RVT =
N->getValueType(0);
2581 EVT RetVT =
N->getOperand(0).getValueType();
2582 TargetLowering::MakeLibCallOptions CallOptions;
2588 RTLIB::LRINT_PPCF128),
2589 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2593 EVT RVT =
N->getValueType(0);
2594 EVT RetVT =
N->getOperand(0).getValueType();
2595 TargetLowering::MakeLibCallOptions CallOptions;
2601 RTLIB::LLRINT_PPCF128),
2602 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2611 if (OpVT == MVT::f16)
2613 if (RetVT == MVT::f16)
2615 if (OpVT == MVT::bf16)
2617 if (RetVT == MVT::bf16)
2623 if (OpVT == MVT::f16)
2625 if (RetVT == MVT::f16)
2627 if (OpVT == MVT::bf16)
2629 if (RetVT == MVT::bf16)
2643 DAG.getVTList(CastVT, MVT::Other),
2644 { AM->getChain(), AM->getBasePtr(), CastVal },
2660void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2661 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2666 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2671 switch (
N->getOpcode()) {
2674 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2675 N->dump(&DAG);
dbgs() <<
"\n";
2681 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2685 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2718 R = SoftPromoteHalfRes_FABS(
N);
2721 R = SoftPromoteHalfRes_FNEG(
N);
2724 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2740 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2743 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2753 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2756 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2758 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2767 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2775 R = SoftPromoteHalfRes_VECREDUCE(
N);
2779 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2784 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2787SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2789 BitConvertToInteger(
N->getOperand(0)));
2793 return BitConvertToInteger(
N->getOperand(0));
2796SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2804SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2805 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2811SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2812 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2813 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2816 EVT LVT =
LHS.getValueType();
2817 EVT RVT =
RHS.getValueType();
2824 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2825 DAG.getConstant(RSize - 1, dl,
2826 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2834 DAG.getConstant(SizeDiff, dl,
2836 DAG.getDataLayout())));
2838 }
else if (SizeDiff < 0) {
2842 DAG.getConstant(-SizeDiff, dl,
2844 DAG.getDataLayout())));
2849 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2850 DAG.getConstant(LSize - 1, dl,
2851 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2852 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2856 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2861 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2862 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2863 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2864 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2865 SDNodeFlags
Flags =
N->getFlags();
2870 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2871 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2872 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2875 if (OVT == MVT::f16) {
2884 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2895 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2900 EVT OVT =
N->getValueType(0);
2901 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2902 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2916 EVT OVT =
N->getValueType(0);
2917 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2918 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2925 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2933SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2934 EVT OVT =
N->getValueType(0);
2935 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2936 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2945 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2947 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2948 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2954SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2955 EVT RVT =
N->getValueType(0);
2956 bool IsStrict =
N->isStrictFPOpcode();
2957 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2958 EVT SVT =
Op.getValueType();
2964 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2967 Op = GetSoftenedFloat(
Op);
2968 TargetLowering::MakeLibCallOptions CallOptions;
2970 std::pair<SDValue, SDValue> Tmp =
2971 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2973 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2974 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2979 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2994 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
2995 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
2996 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
2997 L->getMemOperand()->getFlags(),
L->getAAInfo());
3004SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3019 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3020 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3021 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1,
3025SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3026 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3027 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3029 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3033SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3034 EVT OVT =
N->getValueType(0);
3035 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3038 if (
N->isStrictFPOpcode()) {
3039 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
3040 {N->getOperand(0), N->getOperand(1)});
3042 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
3043 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3054 return DAG.getUNDEF(MVT::i16);
3058 EVT OVT =
N->getValueType(0);
3059 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3060 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3073 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3077 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
3078 DAG.getConstant(0x7fff, dl, MVT::i16));
3082 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3086 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
3087 DAG.getConstant(0x8000, dl, MVT::i16));
3090SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
3091 return GetSoftPromotedHalf(
N->getOperand(0));
3095 EVT OVT =
N->getValueType(0);
3096 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3097 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3098 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3103 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3104 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3112SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3114 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3118SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3120 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3128bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3129 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3133 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3143 switch (
N->getOpcode()) {
3146 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3147 N->dump(&DAG);
dbgs() <<
"\n";
3152 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3154 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3157 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3171 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3175 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3178 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3179 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3180 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3182 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3185 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3188 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3198 "Invalid operand expansion");
3200 ReplaceValueWith(
SDValue(
N, 0), Res);
3205 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3207 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3210SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3211 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3212 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3213 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3219 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3224 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3226 Op1 = GetSoftPromotedHalf(Op1);
3229 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3233SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3234 EVT RVT =
N->getValueType(0);
3235 bool IsStrict =
N->isStrictFPOpcode();
3236 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3237 EVT SVT =
Op.getValueType();
3238 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3242 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3244 ReplaceValueWith(
SDValue(
N, 0), Res);
3251SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3252 EVT RVT =
N->getValueType(0);
3253 bool IsStrict =
N->isStrictFPOpcode();
3254 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3255 EVT SVT =
Op.getValueType();
3258 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3259 Op = GetSoftPromotedHalf(
Op);
3263 {
N->getOperand(0),
Op});
3264 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3265 {Op.getValue(1), Op});
3266 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3272 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3275SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3276 EVT RVT =
N->getValueType(0);
3278 EVT SVT =
Op.getValueType();
3281 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3283 Op = GetSoftPromotedHalf(
Op);
3287 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3293 assert(OpNo == 0 &&
"Can only soften the comparison values");
3299 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3301 Op0 = GetSoftPromotedHalf(Op0);
3302 Op1 = GetSoftPromotedHalf(Op1);
3306 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3307 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3310 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3320 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3322 Op0 = GetSoftPromotedHalf(Op0);
3323 Op1 = GetSoftPromotedHalf(Op1);
3327 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3328 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3330 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3333SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3334 assert(OpNo == 1 &&
"Can only soften the stored value!");
3339 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3340 SDValue Promoted = GetSoftPromotedHalf(Val);
3341 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3342 ST->getMemOperand());
3345SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3347 assert(OpNo == 1 &&
"Can only soften the stored value!");
3352 SDValue Promoted = GetSoftPromotedHalf(Val);
3354 ST->getChain(), Promoted,
ST->getBasePtr(),
3355 ST->getMemOperand());
3358SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3362 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3364 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3366 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3377 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3379 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3381 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 a 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)