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";
65 case ISD::ARITH_FENCE:
R = SoftenFloatRes_ARITH_FENCE(
N);
break;
67 case ISD::BITCAST:
R = SoftenFloatRes_BITCAST(
N);
break;
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
72 case ISD::FABS:
R = SoftenFloatRes_FABS(
N);
break;
74 case ISD::FMINNUM:
R = SoftenFloatRes_FMINNUM(
N);
break;
76 case ISD::FMAXNUM:
R = SoftenFloatRes_FMAXNUM(
N);
break;
77 case ISD::FMINIMUMNUM:
R = SoftenFloatRes_FMINIMUMNUM(
N);
break;
78 case ISD::FMAXIMUMNUM:
R = SoftenFloatRes_FMAXIMUMNUM(
N);
break;
79 case ISD::FMINIMUM:
R = SoftenFloatRes_FMINIMUM(
N);
break;
80 case ISD::FMAXIMUM:
R = SoftenFloatRes_FMAXIMUM(
N);
break;
84 case ISD::FACOS:
R = SoftenFloatRes_FACOS(
N);
break;
86 case ISD::FASIN:
R = SoftenFloatRes_FASIN(
N);
break;
88 case ISD::FATAN:
R = SoftenFloatRes_FATAN(
N);
break;
90 case ISD::FATAN2:
R = SoftenFloatRes_FATAN2(
N);
break;
91 case ISD::FCBRT:
R = SoftenFloatRes_FCBRT(
N);
break;
93 case ISD::FCEIL:
R = SoftenFloatRes_FCEIL(
N);
break;
96 case ISD::FCOS:
R = SoftenFloatRes_FCOS(
N);
break;
98 case ISD::FCOSH:
R = SoftenFloatRes_FCOSH(
N);
break;
102 case ISD::FEXP:
R = SoftenFloatRes_FEXP(
N);
break;
104 case ISD::FEXP2:
R = SoftenFloatRes_FEXP2(
N);
break;
105 case ISD::FEXP10:
R = SoftenFloatRes_FEXP10(
N);
break;
107 case ISD::FFLOOR:
R = SoftenFloatRes_FFLOOR(
N);
break;
109 case ISD::FLOG:
R = SoftenFloatRes_FLOG(
N);
break;
111 case ISD::FLOG2:
R = SoftenFloatRes_FLOG2(
N);
break;
113 case ISD::FLOG10:
R = SoftenFloatRes_FLOG10(
N);
break;
115 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
119 case ISD::FNEARBYINT:
R = SoftenFloatRes_FNEARBYINT(
N);
break;
120 case ISD::FNEG:
R = SoftenFloatRes_FNEG(
N);
break;
122 case ISD::FP_EXTEND:
R = SoftenFloatRes_FP_EXTEND(
N);
break;
125 case ISD::FP16_TO_FP:
R = SoftenFloatRes_FP16_TO_FP(
N);
break;
126 case ISD::BF16_TO_FP:
R = SoftenFloatRes_BF16_TO_FP(
N);
break;
128 case ISD::FPOW:
R = SoftenFloatRes_FPOW(
N);
break;
133 case ISD::FFREXP:
R = SoftenFloatRes_FFREXP(
N);
break;
134 case ISD::FSINCOS:
R = SoftenFloatRes_FSINCOS(
N);
break;
135 case ISD::FMODF:
R = SoftenFloatRes_FMODF(
N);
break;
139 case ISD::FRINT:
R = SoftenFloatRes_FRINT(
N);
break;
141 case ISD::FROUND:
R = SoftenFloatRes_FROUND(
N);
break;
143 case ISD::FROUNDEVEN:
R = SoftenFloatRes_FROUNDEVEN(
N);
break;
145 case ISD::FSIN:
R = SoftenFloatRes_FSIN(
N);
break;
147 case ISD::FSINH:
R = SoftenFloatRes_FSINH(
N);
break;
149 case ISD::FSQRT:
R = SoftenFloatRes_FSQRT(
N);
break;
153 case ISD::FTAN:
R = SoftenFloatRes_FTAN(
N);
break;
155 case ISD::FTANH:
R = SoftenFloatRes_FTANH(
N);
break;
157 case ISD::FTRUNC:
R = SoftenFloatRes_FTRUNC(
N);
break;
158 case ISD::LOAD:
R = SoftenFloatRes_LOAD(
N);
break;
159 case ISD::ATOMIC_LOAD:
R = SoftenFloatRes_ATOMIC_LOAD(
N);
break;
160 case ISD::ATOMIC_SWAP:
R = BitcastToInt_ATOMIC_SWAP(
N);
break;
170 case ISD::VAARG:
R = SoftenFloatRes_VAARG(
N);
break;
172 case ISD::VECREDUCE_FADD:
173 case ISD::VECREDUCE_FMUL:
174 case ISD::VECREDUCE_FMIN:
175 case ISD::VECREDUCE_FMAX:
176 case ISD::VECREDUCE_FMAXIMUM:
177 case ISD::VECREDUCE_FMINIMUM:
R = SoftenFloatRes_VECREDUCE(
N);
break;
178 case ISD::VECREDUCE_SEQ_FADD:
179 case ISD::VECREDUCE_SEQ_FMUL:
R = SoftenFloatRes_VECREDUCE_SEQ(
N);
break;
186 SetSoftenedFloat(
SDValue(
N, ResNo), R);
190SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
192 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
193 unsigned Offset = IsStrict ? 1 : 0;
195 "Unexpected number of operands!");
198 TargetLowering::MakeLibCallOptions CallOptions;
199 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
201 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
202 CallOptions, SDLoc(
N),
205 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
209SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
210 bool IsStrict =
N->isStrictFPOpcode();
211 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
212 unsigned Offset = IsStrict ? 1 : 0;
214 "Unexpected number of operands!");
216 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
218 TargetLowering::MakeLibCallOptions CallOptions;
219 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
220 N->getOperand(1 +
Offset).getValueType() };
222 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Ops,
223 CallOptions, SDLoc(
N),
226 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
231 return BitConvertToInteger(
N->getOperand(0));
235 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
237 GetSoftenedFloat(
N->getOperand(0)));
241 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
242 SDValue NewFence = DAG.getNode(ISD::ARITH_FENCE, SDLoc(
N), Ty,
243 GetSoftenedFloat(
N->getOperand(0)));
249 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
250 return BitConvertToInteger(
Op);
256 TLI.getTypeToTransformTo(*DAG.getContext(),
258 BitConvertToInteger(
N->getOperand(0)),
259 BitConvertToInteger(
N->getOperand(1)));
271 if (DAG.getDataLayout().isBigEndian() &&
275 APInt Val(128, words);
276 return DAG.getConstant(Val, SDLoc(CN),
277 TLI.getTypeToTransformTo(*DAG.getContext(),
281 TLI.getTypeToTransformTo(*DAG.getContext(),
286SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
288 assert(Src.getValueType() == MVT::ppcf128 &&
289 "In floats only ppcf128 can be extracted by element!");
291 N->getValueType(0).changeTypeToInteger(),
292 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
295SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
296 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
299 NewOp,
N->getOperand(1));
303 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
310 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
311 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
315 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
316 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
322 RTLIB::FMIN_PPCF128));
326 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
327 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
333 RTLIB::FMAX_PPCF128));
337 return SoftenFloatRes_Binary(
339 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
340 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128));
344 return SoftenFloatRes_Binary(
346 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
347 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128));
351 return SoftenFloatRes_Binary(
353 RTLIB::FMINIMUM_F64, RTLIB::FMINIMUM_F80,
354 RTLIB::FMINIMUM_F128, RTLIB::FMINIMUM_PPCF128));
358 return SoftenFloatRes_Binary(
360 RTLIB::FMAXIMUM_F64, RTLIB::FMAXIMUM_F80,
361 RTLIB::FMAXIMUM_F128, RTLIB::FMAXIMUM_PPCF128));
370 RTLIB::ADD_PPCF128));
374 return SoftenFloatRes_Unary(
375 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ACOS_F32, RTLIB::ACOS_F64,
376 RTLIB::ACOS_F80, RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128));
380 return SoftenFloatRes_Unary(
381 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ASIN_F32, RTLIB::ASIN_F64,
382 RTLIB::ASIN_F80, RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128));
386 return SoftenFloatRes_Unary(
387 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ATAN_F32, RTLIB::ATAN_F64,
388 RTLIB::ATAN_F80, RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128));
392 return SoftenFloatRes_Binary(
394 GetFPLibCall(
N->getValueType(0), RTLIB::ATAN2_F32, RTLIB::ATAN2_F64,
395 RTLIB::ATAN2_F80, RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128));
404 RTLIB::CBRT_PPCF128));
413 RTLIB::CEIL_PPCF128));
418 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
421 EVT LVT =
LHS.getValueType();
422 EVT RVT =
RHS.getValueType();
429 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
430 DAG.getConstant(RSize - 1, dl,
431 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
439 DAG.getConstant(SizeDiff, dl,
441 DAG.getDataLayout())));
443 }
else if (SizeDiff < 0) {
447 DAG.getConstant(-SizeDiff, dl,
449 DAG.getDataLayout())));
454 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
455 DAG.getConstant(LSize - 1, dl,
456 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
457 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
461 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
470 RTLIB::COS_PPCF128));
474 return SoftenFloatRes_Unary(
475 N,
GetFPLibCall(
N->getValueType(0), RTLIB::COSH_F32, RTLIB::COSH_F64,
476 RTLIB::COSH_F80, RTLIB::COSH_F128, RTLIB::COSH_PPCF128));
485 RTLIB::DIV_PPCF128));
494 RTLIB::EXP_PPCF128));
503 RTLIB::EXP2_PPCF128));
507 return SoftenFloatRes_Unary(
509 GetFPLibCall(
N->getValueType(0), RTLIB::EXP10_F32, RTLIB::EXP10_F64,
510 RTLIB::EXP10_F80, RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128));
519 RTLIB::FLOOR_PPCF128));
528 RTLIB::LOG_PPCF128));
537 RTLIB::LOG2_PPCF128));
546 RTLIB::LOG10_PPCF128));
550 bool IsStrict =
N->isStrictFPOpcode();
551 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
552 unsigned Offset = IsStrict ? 1 : 0;
554 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
555 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
557 TargetLowering::MakeLibCallOptions CallOptions;
558 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
559 N->getOperand(1 +
Offset).getValueType(),
560 N->getOperand(2 +
Offset).getValueType() };
562 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
569 NVT,
Ops, CallOptions, SDLoc(
N), Chain);
571 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
581 RTLIB::MUL_PPCF128));
586 RTLIB::NEARBYINT_F32,
587 RTLIB::NEARBYINT_F64,
588 RTLIB::NEARBYINT_F80,
589 RTLIB::NEARBYINT_F128,
590 RTLIB::NEARBYINT_PPCF128));
594 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
599 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
600 DAG.getConstant(SignMask, dl, NVT));
604 bool IsStrict =
N->isStrictFPOpcode();
605 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
611 Op = GetPromotedFloat(
Op);
614 if (
Op.getValueType() ==
N->getValueType(0)) {
616 ReplaceValueWith(
SDValue(
N, 1), Chain);
617 return BitConvertToInteger(
Op);
625 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
626 N->getValueType(0) != MVT::f32) {
629 { MVT::f32, MVT::Other }, { Chain,
Op });
630 Chain =
Op.getValue(1);
632 Op = DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), MVT::f32,
Op);
636 if (
Op.getValueType() == MVT::bf16) {
638 return SoftenFloatRes_BF16_TO_FP(
N);
642 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
643 TargetLowering::MakeLibCallOptions CallOptions;
644 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
646 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
647 CallOptions, SDLoc(
N),
650 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
657 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
659 TargetLowering::MakeLibCallOptions CallOptions;
660 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
662 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
663 CallOptions, SDLoc(
N)).first;
664 if (
N->getValueType(0) == MVT::f32)
667 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
669 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
670 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
676 assert(
N->getValueType(0) == MVT::f32 &&
677 "Can only soften BF16_TO_FP with f32 result");
678 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
682 DAG.getNode(ISD::BITCAST,
DL, MVT::i16,
Op));
684 DAG.getShiftAmountConstant(16, NVT,
DL));
689 bool IsStrict =
N->isStrictFPOpcode();
690 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
694 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
695 TargetLowering::MakeLibCallOptions CallOptions;
696 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
698 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
699 CallOptions, SDLoc(
N),
702 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
711 bool IsStrict =
N->isStrictFPOpcode();
712 unsigned Offset = IsStrict ? 1 : 0;
715 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
719 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
720 if (!TLI.getLibcallName(LC)) {
723 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
725 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
726 return DAG.getPOISON(NVT);
729 if (DAG.getLibInfo().getIntSize() !=
730 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
733 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
735 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
736 return DAG.getPOISON(NVT);
742 TargetLowering::MakeLibCallOptions CallOptions;
743 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
744 N->getOperand(1 +
Offset).getValueType() };
746 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Ops,
747 CallOptions, SDLoc(
N),
750 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
755 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
756 EVT VT0 =
N->getValueType(0);
757 EVT VT1 =
N->getValueType(1);
759 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
766 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
767 SDValue PoisonExp = DAG.getPOISON(VT1);
768 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
769 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
772 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
775 TargetLowering::MakeLibCallOptions CallOptions;
776 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
783 .setOpsTypeOverrides(CallOpsTypeOverrides);
785 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0,
Ops, CallOptions,
DL,
791 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
793 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
797bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
798 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
799 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
800 EVT VT =
N->getValueType(0);
802 assert(VT ==
N->getValueType(1) &&
803 "expected both return values to have the same type");
805 if (!TLI.getLibcallName(LC))
808 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
815 std::array<SDValue, 2> StackSlots;
818 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
819 if (ResNum == CallRetResNo)
821 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
822 Ops.push_back(StackSlot);
824 StackSlots[ResNum] = StackSlot;
828 TargetLowering::MakeLibCallOptions CallOptions;
832 .setOpsTypeOverrides(CallOpsTypeOverrides);
834 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT,
Ops, CallOptions,
DL,
837 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
841 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
844 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
845 if (CallRetResNo == ResNum) {
846 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
849 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
856 EVT VT =
N->getValueType(0);
865 if (!TLI.getLibcallName(SinLC) || !TLI.getLibcallName(CosLC)) {
866 DAG.getContext()->emitError(
"do not know how to soften fsincos");
868 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
869 SoftSin = SoftCos = DAG.getPOISON(NVT);
871 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
872 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
875 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
876 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
881 EVT VT =
N->getValueType(0);
886 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
887 DAG.getContext()->emitError(
"do not know how to soften fmodf");
900 RTLIB::REM_PPCF128));
909 RTLIB::RINT_PPCF128));
918 RTLIB::ROUND_PPCF128));
923 RTLIB::ROUNDEVEN_F32,
924 RTLIB::ROUNDEVEN_F64,
925 RTLIB::ROUNDEVEN_F80,
926 RTLIB::ROUNDEVEN_F128,
927 RTLIB::ROUNDEVEN_PPCF128));
936 RTLIB::SIN_PPCF128));
940 return SoftenFloatRes_Unary(
941 N,
GetFPLibCall(
N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
942 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
951 RTLIB::SQRT_PPCF128));
960 RTLIB::SUB_PPCF128));
964 return SoftenFloatRes_Unary(
965 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
966 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
970 return SoftenFloatRes_Unary(
971 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
972 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
981 RTLIB::TRUNC_PPCF128));
986 EVT VT =
N->getValueType(0);
987 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
991 L->getMemOperand()->getFlags() &
995 NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
996 L->getChain(),
L->getBasePtr(),
L->getOffset(),
997 L->getPointerInfo(), NVT,
L->getBaseAlign(), MMOFlags,
1007 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
1008 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
1009 MMOFlags,
L->getAAInfo());
1013 auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL);
1014 return BitConvertToInteger(ExtendNode);
1019 EVT VT =
N->getValueType(0);
1020 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1025 DAG.getAtomic(ISD::ATOMIC_LOAD, dl, NVT, DAG.getVTList(NVT, MVT::Other),
1026 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
1040 return DAG.getSelect(SDLoc(
N),
1041 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
1048 LHS.getValueType(),
N->getOperand(0),
1049 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
1053 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1054 N->getValueType(0)));
1060 EVT VT =
N->getValueType(0);
1061 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1065 NewVAARG = DAG.getVAArg(NVT, dl, Chain,
Ptr,
N->getOperand(2),
1066 N->getConstantOperandVal(3));
1076 bool IsStrict =
N->isStrictFPOpcode();
1079 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1080 EVT RVT =
N->getValueType(0);
1087 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1088 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1089 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1095 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1100 NVT,
N->getOperand(IsStrict ? 1 : 0));
1101 TargetLowering::MakeLibCallOptions CallOptions;
1104 std::pair<SDValue, SDValue> Tmp =
1105 TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
1106 Op, CallOptions, dl, Chain);
1109 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1115 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1119SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1120 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1128bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1129 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1132 switch (
N->getOpcode()) {
1135 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1136 N->dump(&DAG);
dbgs() <<
"\n";
1140 case ISD::BITCAST: Res = SoftenFloatOp_BITCAST(
N);
break;
1141 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1142 case ISD::STRICT_FP_TO_FP16:
1143 case ISD::FP_TO_FP16:
1144 case ISD::FP_TO_BF16:
1145 case ISD::STRICT_FP_TO_BF16:
1154 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1156 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1158 case ISD::LLROUND: Res = SoftenFloatOp_LLROUND(
N);
break;
1160 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1162 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1166 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1167 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1168 case ISD::ATOMIC_STORE:
1169 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1173 Res = SoftenFloatOp_FAKE_USE(
N);
1176 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1178 case ISD::PATCHPOINT:
1179 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1184 if (!Res.
getNode())
return false;
1192 "Invalid operand softening");
1194 ReplaceValueWith(
SDValue(
N, 0), Res);
1199 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1201 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1208 N->getOpcode() == ISD::STRICT_FP_TO_FP16 ||
1209 N->getOpcode() == ISD::FP_TO_BF16 ||
1210 N->getOpcode() == ISD::STRICT_FP_TO_BF16 ||
1213 bool IsStrict =
N->isStrictFPOpcode();
1214 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1215 EVT SVT =
Op.getValueType();
1216 EVT RVT =
N->getValueType(0);
1218 if (
N->getOpcode() == ISD::FP_TO_FP16 ||
1219 N->getOpcode() == ISD::STRICT_FP_TO_FP16)
1220 FloatRVT = MVT::f16;
1221 else if (
N->getOpcode() == ISD::FP_TO_BF16 ||
1222 N->getOpcode() == ISD::STRICT_FP_TO_BF16)
1223 FloatRVT = MVT::bf16;
1226 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1229 Op = GetSoftenedFloat(
Op);
1230 TargetLowering::MakeLibCallOptions CallOptions;
1232 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT,
Op,
1233 CallOptions, SDLoc(
N),
1236 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1237 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1248 NewLHS = GetSoftenedFloat(NewLHS);
1249 NewRHS = GetSoftenedFloat(NewRHS);
1250 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1251 N->getOperand(2),
N->getOperand(3));
1255 if (!NewRHS.getNode()) {
1256 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1261 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1262 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1272 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1273 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1274 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1278 if (Promoted.
bitsGE(RetVT))
1286 bool IsStrict =
N->isStrictFPOpcode();
1290 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1291 EVT SVT =
Op.getValueType();
1292 EVT RVT =
N->getValueType(0);
1302 "Unsupported FP_TO_XINT!");
1304 Op = GetSoftenedFloat(
Op);
1306 TargetLowering::MakeLibCallOptions CallOptions;
1308 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1309 CallOptions, dl, Chain);
1317 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1318 ReplaceValueWith(
SDValue(
N, 0), Res);
1322SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1323 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1332 NewLHS = GetSoftenedFloat(NewLHS);
1333 NewRHS = GetSoftenedFloat(NewRHS);
1334 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1335 N->getOperand(0),
N->getOperand(1));
1339 if (!NewRHS.getNode()) {
1340 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1345 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1346 N->getOperand(2),
N->getOperand(3),
1347 DAG.getCondCode(CCCode)),
1352 bool IsStrict =
N->isStrictFPOpcode();
1360 SDValue NewLHS = GetSoftenedFloat(Op0);
1361 SDValue NewRHS = GetSoftenedFloat(Op1);
1362 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1369 NewRHS, DAG.getCondCode(CCCode));
1371 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1372 DAG.getCondCode(CCCode)), 0);
1377 "Unexpected setcc expansion!");
1380 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1381 ReplaceValueWith(
SDValue(
N, 1), Chain);
1387SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1389 assert(OpNo == 1 &&
"Can only soften the stored value!");
1394 if (
ST->isTruncatingStore())
1396 Val = BitConvertToInteger(
1398 DAG.getIntPtrConstant(0, dl,
true)));
1400 Val = GetSoftenedFloat(Val);
1402 return DAG.getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1403 ST->getMemOperand());
1406SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1407 assert(OpNo == 1 &&
"Can only soften the stored value!");
1413 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1415 SDValue NewVal = GetSoftenedFloat(Val);
1416 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, VT,
ST->getChain(), NewVal,
1417 ST->getBasePtr(),
ST->getMemOperand());
1422 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1425 EVT LVT =
LHS.getValueType();
1427 EVT RVT =
RHS.getValueType();
1433 int SizeDiff = RSize - LSize;
1437 DAG.getConstant(SizeDiff, dl,
1438 TLI.getShiftAmountTy(
RHS.getValueType(),
1439 DAG.getDataLayout())));
1441 }
else if (SizeDiff < 0) {
1445 DAG.getConstant(-SizeDiff, dl,
1446 TLI.getShiftAmountTy(
RHS.getValueType(),
1447 DAG.getDataLayout())));
1450 RHS = DAG.getBitcast(LVT,
RHS);
1454SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1455 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1456 bool IsStrict =
N->isStrictFPOpcode();
1457 unsigned Offset = IsStrict ? 1 : 0;
1460 TargetLowering::MakeLibCallOptions CallOptions;
1461 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1463 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1464 CallOptions, SDLoc(
N),
1467 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1468 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1476 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1482 RTLIB::LROUND_PPCF128));
1486 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1491 RTLIB::LLROUND_F128,
1492 RTLIB::LLROUND_PPCF128));
1496 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1502 RTLIB::LRINT_PPCF128));
1506 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1512 RTLIB::LLRINT_PPCF128));
1516 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1517 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1518 N->getOperand(0), Op1);
1521SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1524 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1525 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1528SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1531 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1532 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1543void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1549 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1552 switch (
N->getOpcode()) {
1555 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1556 N->dump(&DAG);
dbgs() <<
"\n";
1567 case ISD::BITCAST: ExpandRes_BITCAST(
N,
Lo,
Hi);
break;
1571 case ISD::VAARG: ExpandRes_VAARG(
N,
Lo,
Hi);
break;
1575 case ISD::FABS: ExpandFloatRes_FABS(
N,
Lo,
Hi);
break;
1577 case ISD::FMINNUM: ExpandFloatRes_FMINNUM(
N,
Lo,
Hi);
break;
1579 case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(
N,
Lo,
Hi);
break;
1580 case ISD::FMINIMUMNUM: ExpandFloatRes_FMINIMUMNUM(
N,
Lo,
Hi);
break;
1581 case ISD::FMAXIMUMNUM: ExpandFloatRes_FMAXIMUMNUM(
N,
Lo,
Hi);
break;
1585 case ISD::FACOS: ExpandFloatRes_FACOS(
N,
Lo,
Hi);
break;
1587 case ISD::FASIN: ExpandFloatRes_FASIN(
N,
Lo,
Hi);
break;
1589 case ISD::FATAN: ExpandFloatRes_FATAN(
N,
Lo,
Hi);
break;
1591 case ISD::FATAN2: ExpandFloatRes_FATAN2(
N,
Lo,
Hi);
break;
1592 case ISD::FCBRT: ExpandFloatRes_FCBRT(
N,
Lo,
Hi);
break;
1594 case ISD::FCEIL: ExpandFloatRes_FCEIL(
N,
Lo,
Hi);
break;
1597 case ISD::FCOS: ExpandFloatRes_FCOS(
N,
Lo,
Hi);
break;
1599 case ISD::FCOSH: ExpandFloatRes_FCOSH(
N,
Lo,
Hi);
break;
1603 case ISD::FEXP: ExpandFloatRes_FEXP(
N,
Lo,
Hi);
break;
1605 case ISD::FEXP2: ExpandFloatRes_FEXP2(
N,
Lo,
Hi);
break;
1606 case ISD::FEXP10: ExpandFloatRes_FEXP10(
N,
Lo,
Hi);
break;
1608 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(
N,
Lo,
Hi);
break;
1610 case ISD::FLOG: ExpandFloatRes_FLOG(
N,
Lo,
Hi);
break;
1612 case ISD::FLOG2: ExpandFloatRes_FLOG2(
N,
Lo,
Hi);
break;
1614 case ISD::FLOG10: ExpandFloatRes_FLOG10(
N,
Lo,
Hi);
break;
1620 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(
N,
Lo,
Hi);
break;
1621 case ISD::FNEG: ExpandFloatRes_FNEG(
N,
Lo,
Hi);
break;
1623 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(
N,
Lo,
Hi);
break;
1625 case ISD::FPOW: ExpandFloatRes_FPOW(
N,
Lo,
Hi);
break;
1627 case ISD::FPOWI: ExpandFloatRes_FPOWI(
N,
Lo,
Hi);
break;
1632 case ISD::FRINT: ExpandFloatRes_FRINT(
N,
Lo,
Hi);
break;
1634 case ISD::FROUND: ExpandFloatRes_FROUND(
N,
Lo,
Hi);
break;
1636 case ISD::FROUNDEVEN: ExpandFloatRes_FROUNDEVEN(
N,
Lo,
Hi);
break;
1638 case ISD::FSIN: ExpandFloatRes_FSIN(
N,
Lo,
Hi);
break;
1640 case ISD::FSINH: ExpandFloatRes_FSINH(
N,
Lo,
Hi);
break;
1642 case ISD::FSQRT: ExpandFloatRes_FSQRT(
N,
Lo,
Hi);
break;
1646 case ISD::FTAN: ExpandFloatRes_FTAN(
N,
Lo,
Hi);
break;
1648 case ISD::FTANH: ExpandFloatRes_FTANH(
N,
Lo,
Hi);
break;
1650 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(
N,
Lo,
Hi);
break;
1651 case ISD::LOAD: ExpandFloatRes_LOAD(
N,
Lo,
Hi);
break;
1658 case ISD::FMODF: ExpandFloatRes_FMODF(
N);
break;
1659 case ISD::FSINCOS: ExpandFloatRes_FSINCOS(
N);
break;
1660 case ISD::FSINCOSPI: ExpandFloatRes_FSINCOSPI(
N);
break;
1671 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1673 "Do not know how to expand this float constant!");
1677 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1678 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1681void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1683 bool IsStrict =
N->isStrictFPOpcode();
1684 unsigned Offset = IsStrict ? 1 : 0;
1687 TargetLowering::MakeLibCallOptions CallOptions;
1688 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1689 Op, CallOptions, SDLoc(
N),
1692 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1693 GetPairElements(Tmp.first,
Lo,
Hi);
1696void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1698 bool IsStrict =
N->isStrictFPOpcode();
1699 unsigned Offset = IsStrict ? 1 : 0;
1702 TargetLowering::MakeLibCallOptions CallOptions;
1703 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1704 Ops, CallOptions, SDLoc(
N),
1707 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1708 GetPairElements(Tmp.first,
Lo,
Hi);
1711void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1712 ExpandFloatRes_UnaryWithTwoFPResults(
N,
RTLIB::getMODF(
N->getValueType(0)),
1716void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1720void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1721 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1725void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1726 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1727 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1729 DAG.expandMultipleResultFPLibCall(LC,
N,
Results, CallRetResNo);
1732 GetPairElements(Res,
Lo,
Hi);
1739 assert(
N->getValueType(0) == MVT::ppcf128 &&
1740 "Logic only correct for ppcf128!");
1743 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1746 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1747 DAG.getNode(ISD::FNEG, dl,
Lo.getValueType(),
Lo),
1754 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1755 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1756 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1762 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1763 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1764 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1769 ExpandFloatRes_Binary(
1772 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
1773 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128),
1779 ExpandFloatRes_Binary(
1782 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
1783 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128),
1790 RTLIB::ADD_F32, RTLIB::ADD_F64,
1791 RTLIB::ADD_F80, RTLIB::ADD_F128,
1792 RTLIB::ADD_PPCF128),
Lo,
Hi);
1797 ExpandFloatRes_Unary(
N,
1799 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1800 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1806 ExpandFloatRes_Unary(
N,
1808 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1809 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1815 ExpandFloatRes_Unary(
N,
1817 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1818 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1824 ExpandFloatRes_Binary(
N,
1826 RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
1827 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128),
1833 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1834 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1836 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1839void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1842 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1843 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1844 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1847void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1850 RTLIB::COPYSIGN_F32,
1851 RTLIB::COPYSIGN_F64,
1852 RTLIB::COPYSIGN_F80,
1853 RTLIB::COPYSIGN_F128,
1854 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1857void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1860 RTLIB::COS_F32, RTLIB::COS_F64,
1861 RTLIB::COS_F80, RTLIB::COS_F128,
1862 RTLIB::COS_PPCF128),
Lo,
Hi);
1867 ExpandFloatRes_Unary(
N,
1869 RTLIB::COSH_F64, RTLIB::COSH_F80,
1870 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1881 RTLIB::DIV_PPCF128),
Lo,
Hi);
1884void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1887 RTLIB::EXP_F32, RTLIB::EXP_F64,
1888 RTLIB::EXP_F80, RTLIB::EXP_F128,
1889 RTLIB::EXP_PPCF128),
Lo,
Hi);
1892void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1895 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1896 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1897 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1902 ExpandFloatRes_Unary(
N,
1904 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1905 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1909void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1912 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1913 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1914 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1917void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1920 RTLIB::LOG_F32, RTLIB::LOG_F64,
1921 RTLIB::LOG_F80, RTLIB::LOG_F128,
1922 RTLIB::LOG_PPCF128),
Lo,
Hi);
1925void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1928 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1929 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1930 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1933void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1936 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1937 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1938 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1943 bool IsStrict =
N->isStrictFPOpcode();
1944 unsigned Offset = IsStrict ? 1 : 0;
1948 TargetLowering::MakeLibCallOptions CallOptions;
1949 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
GetFPLibCall(
N->getValueType(0),
1954 RTLIB::FMA_PPCF128),
1955 N->getValueType(0),
Ops, CallOptions,
1958 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1959 GetPairElements(Tmp.first,
Lo,
Hi);
1969 RTLIB::MUL_PPCF128),
Lo,
Hi);
1972void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1975 RTLIB::NEARBYINT_F32,
1976 RTLIB::NEARBYINT_F64,
1977 RTLIB::NEARBYINT_F80,
1978 RTLIB::NEARBYINT_F128,
1979 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
1985 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1986 Lo = DAG.getNode(ISD::FNEG, dl,
Lo.getValueType(),
Lo);
1987 Hi = DAG.getNode(ISD::FNEG, dl,
Hi.getValueType(),
Hi);
1990void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1994 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1999 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
2001 bool IsStrict =
N->isStrictFPOpcode();
2006 if (NVT ==
N->getOperand(1).getValueType()) {
2007 Hi =
N->getOperand(1);
2012 {
N->getOperand(0),
N->getOperand(1) });
2016 Hi = DAG.getNode(ISD::FP_EXTEND, dl, NVT,
N->getOperand(0));
2022 ReplaceValueWith(
SDValue(
N, 1), Chain);
2025void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
2028 RTLIB::POW_F32, RTLIB::POW_F64,
2029 RTLIB::POW_F80, RTLIB::POW_F128,
2030 RTLIB::POW_PPCF128),
Lo,
Hi);
2033void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
2043void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
2045 assert(
N->getValueType(0) == MVT::ppcf128 &&
2046 "Logic only correct for ppcf128!");
2049 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2054void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
2057 RTLIB::REM_F32, RTLIB::REM_F64,
2058 RTLIB::REM_F80, RTLIB::REM_F128,
2059 RTLIB::REM_PPCF128),
Lo,
Hi);
2062void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
2065 RTLIB::RINT_F32, RTLIB::RINT_F64,
2066 RTLIB::RINT_F80, RTLIB::RINT_F128,
2067 RTLIB::RINT_PPCF128),
Lo,
Hi);
2070void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
2077 RTLIB::ROUND_PPCF128),
Lo,
Hi);
2080void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
2083 RTLIB::ROUNDEVEN_F32,
2084 RTLIB::ROUNDEVEN_F64,
2085 RTLIB::ROUNDEVEN_F80,
2086 RTLIB::ROUNDEVEN_F128,
2087 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
2090void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
2093 RTLIB::SIN_F32, RTLIB::SIN_F64,
2094 RTLIB::SIN_F80, RTLIB::SIN_F128,
2095 RTLIB::SIN_PPCF128),
Lo,
Hi);
2100 ExpandFloatRes_Unary(
N,
2102 RTLIB::SINH_F64, RTLIB::SINH_F80,
2103 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
2107void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
2110 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
2111 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
2112 RTLIB::SQRT_PPCF128),
Lo,
Hi);
2122 RTLIB::SUB_PPCF128),
Lo,
Hi);
2127 ExpandFloatRes_Unary(
N,
2129 RTLIB::TAN_F64, RTLIB::TAN_F80,
2130 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
2136 ExpandFloatRes_Unary(
N,
2138 RTLIB::TANH_F64, RTLIB::TANH_F80,
2139 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
2143void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2146 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
2147 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
2148 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
2154 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2164 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2166 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2168 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain,
Ptr,
2169 LD->getMemoryVT(),
LD->getMemOperand());
2179 ReplaceValueWith(
SDValue(LD, 1), Chain);
2184 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2185 EVT VT =
N->getValueType(0);
2186 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2187 bool Strict =
N->isStrictFPOpcode();
2188 SDValue Src =
N->getOperand(Strict ? 1 : 0);
2189 EVT SrcVT = Src.getValueType();
2197 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2202 if (SrcVT.
bitsLE(MVT::i32)) {
2206 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2207 {Chain, Src}, Flags);
2210 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2212 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2213 if (SrcVT.
bitsLE(MVT::i64)) {
2216 LC = RTLIB::SINTTOFP_I64_PPCF128;
2217 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2219 LC = RTLIB::SINTTOFP_I128_PPCF128;
2221 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2223 TargetLowering::MakeLibCallOptions CallOptions;
2225 std::pair<SDValue, SDValue> Tmp =
2226 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2229 GetPairElements(Tmp.first,
Lo,
Hi);
2235 ReplaceValueWith(
SDValue(
N, 1), Chain);
2245 SrcVT = Src.getValueType();
2248 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2249 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2250 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2251 ArrayRef<uint64_t> Parts;
2268 SDValue NewLo = DAG.getConstantFP(
2272 {Chain, Hi, NewLo}, Flags);
2274 ReplaceValueWith(
SDValue(
N, 1), Chain);
2277 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2279 GetPairElements(
Lo,
Lo,
Hi);
2291bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2296 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2299 switch (
N->getOpcode()) {
2302 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2303 N->dump(&DAG);
dbgs() <<
"\n";
2307 case ISD::BITCAST: Res = ExpandOp_BITCAST(
N);
break;
2311 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2319 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2320 case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(
N);
break;
2321 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2322 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2326 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2332 if (!Res.
getNode())
return false;
2340 "Invalid operand expansion");
2342 ReplaceValueWith(
SDValue(
N, 0), Res);
2348void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2353 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2354 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2355 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2364 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2365 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2368 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2369 RHSLo, CCCode, OutputChain, IsSignaling);
2373 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2376 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2377 RHSHi, CCCode, OutputChain, IsSignaling);
2382 Chain = OutputChain;
2389 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2394 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2399 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2400 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2401 N->getOperand(4)), 0);
2405 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2406 "Logic only correct for ppcf128!");
2408 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2412 N->getValueType(0),
N->getOperand(0),
Hi);
2416 bool IsStrict =
N->isStrictFPOpcode();
2417 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2418 "Logic only correct for ppcf128!");
2420 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2425 N->getValueType(0),
Hi,
N->getOperand(1));
2429 if (
Hi.getValueType() ==
N->getValueType(0)) {
2431 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2437 {
N->getValueType(0), MVT::Other},
2438 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2445 EVT RVT =
N->getValueType(0);
2448 bool IsStrict =
N->isStrictFPOpcode();
2451 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2457 "Unsupported FP_TO_XINT!");
2458 TargetLowering::MakeLibCallOptions CallOptions;
2459 std::pair<SDValue, SDValue> Tmp =
2460 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2464 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2465 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2473 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2478 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2483 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2484 N->getOperand(2),
N->getOperand(3),
2485 DAG.getCondCode(CCCode)), 0);
2489 bool IsStrict =
N->isStrictFPOpcode();
2495 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2501 "Unexpected setcc expansion!");
2503 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2504 ReplaceValueWith(
SDValue(
N, 1), Chain);
2510SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2512 return ExpandOp_NormalStore(
N, OpNo);
2515 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2521 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2522 ST->getValue().getValueType());
2524 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2528 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2530 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi,
Ptr,
2531 ST->getMemoryVT(),
ST->getMemOperand());
2535 EVT RVT =
N->getValueType(0);
2536 EVT RetVT =
N->getOperand(0).getValueType();
2537 TargetLowering::MakeLibCallOptions CallOptions;
2543 RTLIB::LROUND_PPCF128),
2544 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2548 EVT RVT =
N->getValueType(0);
2549 EVT RetVT =
N->getOperand(0).getValueType();
2550 TargetLowering::MakeLibCallOptions CallOptions;
2555 RTLIB::LLROUND_F128,
2556 RTLIB::LLROUND_PPCF128),
2557 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2561 EVT RVT =
N->getValueType(0);
2562 EVT RetVT =
N->getOperand(0).getValueType();
2563 TargetLowering::MakeLibCallOptions CallOptions;
2569 RTLIB::LRINT_PPCF128),
2570 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2574 EVT RVT =
N->getValueType(0);
2575 EVT RetVT =
N->getOperand(0).getValueType();
2576 TargetLowering::MakeLibCallOptions CallOptions;
2582 RTLIB::LLRINT_PPCF128),
2583 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2592 if (OpVT == MVT::f16)
2593 return ISD::FP16_TO_FP;
2594 if (RetVT == MVT::f16)
2595 return ISD::FP_TO_FP16;
2596 if (OpVT == MVT::bf16)
2597 return ISD::BF16_TO_FP;
2598 if (RetVT == MVT::bf16)
2599 return ISD::FP_TO_BF16;
2604 if (OpVT == MVT::f16)
2605 return ISD::STRICT_FP16_TO_FP;
2606 if (RetVT == MVT::f16)
2607 return ISD::STRICT_FP_TO_FP16;
2608 if (OpVT == MVT::bf16)
2609 return ISD::STRICT_BF16_TO_FP;
2610 if (RetVT == MVT::bf16)
2611 return ISD::STRICT_FP_TO_BF16;
2615bool DAGTypeLegalizer::PromoteFloatOperand(
SDNode *
N,
unsigned OpNo) {
2616 LLVM_DEBUG(
dbgs() <<
"Promote float operand " << OpNo <<
": ";
N->dump(&DAG));
2619 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2630 switch (
N->getOpcode()) {
2633 dbgs() <<
"PromoteFloatOperand Op #" << OpNo <<
": ";
2634 N->dump(&DAG);
dbgs() <<
"\n";
2638 case ISD::BITCAST:
R = PromoteFloatOp_BITCAST(
N, OpNo);
break;
2640 R = PromoteFloatOp_FAKE_USE(
N, OpNo);
2648 case ISD::LLRINT:
R = PromoteFloatOp_UnaryOp(
N, OpNo);
break;
2652 R = PromoteFloatOp_FP_TO_XINT_SAT(
N, OpNo);
break;
2653 case ISD::FP_EXTEND:
R = PromoteFloatOp_FP_EXTEND(
N, OpNo);
break;
2655 R = PromoteFloatOp_STRICT_FP_EXTEND(
N, OpNo);
2658 case ISD::SETCC:
R = PromoteFloatOp_SETCC(
N, OpNo);
break;
2659 case ISD::STORE:
R = PromoteFloatOp_STORE(
N, OpNo);
break;
2660 case ISD::ATOMIC_STORE:
R = PromoteFloatOp_ATOMIC_STORE(
N, OpNo);
break;
2665 ReplaceValueWith(
SDValue(
N, 0), R);
2669SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(
SDNode *
N,
unsigned OpNo) {
2671 EVT OpVT =
Op->getValueType(0);
2673 SDValue Promoted = GetPromotedFloat(
N->getOperand(0));
2682 return DAG.getBitcast(
N->getValueType(0), Convert);
2685SDValue DAGTypeLegalizer::PromoteFloatOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
2686 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
2687 SDValue Op = GetPromotedFloat(
N->getOperand(OpNo));
2688 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
2694SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(
SDNode *
N,
unsigned OpNo) {
2695 assert (OpNo == 1 &&
"Only Operand 1 must need promotion here");
2696 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2698 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
2699 N->getOperand(0), Op1);
2703SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(
SDNode *
N,
unsigned OpNo) {
2704 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2705 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
Op);
2709SDValue DAGTypeLegalizer::PromoteFloatOp_AssertNoFPClass(
SDNode *
N,
2711 return GetPromotedFloat(
N->getOperand(0));
2714SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(
SDNode *
N,
2716 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2717 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
Op,
2721SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(
SDNode *
N,
unsigned OpNo) {
2722 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2723 EVT VT =
N->getValueType(0);
2726 if (VT ==
Op->getValueType(0))
2730 return DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT,
Op);
2733SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(
SDNode *
N,
2735 assert(OpNo == 1 &&
"Promoting unpromotable operand");
2737 SDValue Op = GetPromotedFloat(
N->getOperand(1));
2738 EVT VT =
N->getValueType(0);
2741 if (VT ==
Op->getValueType(0)) {
2742 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2748 N->getOperand(0),
Op);
2756SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(
SDNode *
N,
unsigned OpNo) {
2761 LHS,
RHS,
N->getOperand(2),
N->getOperand(3),
2767SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(
SDNode *
N,
unsigned OpNo) {
2768 EVT VT =
N->getValueType(0);
2769 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2770 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2773 return DAG.getSetCC(SDLoc(
N), VT, Op0, Op1, CCCode);
2779SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2784 SDValue Promoted = GetPromotedFloat(Val);
2785 EVT VT =
ST->getOperand(1).getValueType();
2792 return DAG.getStore(
ST->getChain(),
DL, NewVal,
ST->getBasePtr(),
2793 ST->getMemOperand());
2802 SDValue Promoted = GetPromotedFloat(Val);
2803 EVT VT =
ST->getOperand(1).getValueType();
2809 return DAG.getAtomic(ISD::ATOMIC_STORE,
DL, IVT,
ST->getChain(), NewVal,
2810 ST->getBasePtr(),
ST->getMemOperand());
2817void DAGTypeLegalizer::PromoteFloatResult(
SDNode *
N,
unsigned ResNo) {
2818 LLVM_DEBUG(
dbgs() <<
"Promote float result " << ResNo <<
": ";
N->dump(&DAG));
2822 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2827 switch (
N->getOpcode()) {
2830 case ISD::FP16_TO_FP:
2831 case ISD::FP_TO_FP16:
2834 dbgs() <<
"PromoteFloatResult #" << ResNo <<
": ";
2835 N->dump(&DAG);
dbgs() <<
"\n";
2840 R = PromoteFloatRes_BITCAST(
N);
2843 R = PromoteFloatRes_FREEZE(
N);
2847 R = PromoteFloatRes_EXTRACT_VECTOR_ELT(
N);
break;
2866 case ISD::FNEARBYINT:
2870 case ISD::FROUNDEVEN:
2879 R = PromoteFloatRes_AssertNoFPClass(
N);
2887 case ISD::FMAXIMUMNUM:
2888 case ISD::FMINIMUMNUM:
2891 case ISD::FMAXNUM_IEEE:
2892 case ISD::FMINNUM_IEEE:
2897 case ISD::FSUB:
R = PromoteFloatRes_BinOp(
N);
break;
2900 case ISD::FMAD:
R = PromoteFloatRes_FMAD(
N);
break;
2903 case ISD::FLDEXP:
R = PromoteFloatRes_ExpOp(
N);
break;
2904 case ISD::FFREXP:
R = PromoteFloatRes_FFREXP(
N);
break;
2908 case ISD::FSINCOSPI:
2909 R = PromoteFloatRes_UnaryWithTwoFPResults(
N);
2913 R = PromoteFloatRes_STRICT_FP_ROUND(
N);
2915 case ISD::LOAD:
R = PromoteFloatRes_LOAD(
N);
break;
2916 case ISD::ATOMIC_LOAD:
2917 R = PromoteFloatRes_ATOMIC_LOAD(
N);
2926 case ISD::ATOMIC_SWAP:
R = BitcastToInt_ATOMIC_SWAP(
N);
break;
2927 case ISD::VECREDUCE_FADD:
2928 case ISD::VECREDUCE_FMUL:
2929 case ISD::VECREDUCE_FMIN:
2930 case ISD::VECREDUCE_FMAX:
2931 case ISD::VECREDUCE_FMAXIMUM:
2932 case ISD::VECREDUCE_FMINIMUM:
2933 R = PromoteFloatRes_VECREDUCE(
N);
2935 case ISD::VECREDUCE_SEQ_FADD:
2936 case ISD::VECREDUCE_SEQ_FMUL:
2937 R = PromoteFloatRes_VECREDUCE_SEQ(
N);
2942 SetPromotedFloat(
SDValue(
N, ResNo), R);
2951 EVT VT =
N->getValueType(0);
2952 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2956 N->getOperand(0).getValueType().getSizeInBits());
2957 SDValue Cast = DAG.getBitcast(IVT,
N->getOperand(0));
2962 EVT VT =
N->getValueType(0);
2963 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2967 N->getOperand(0).getValueType().getSizeInBits());
2968 SDValue Cast = DAG.getBitcast(IVT,
N->getOperand(0));
2970 DAG.getFreeze(Cast));
2975 EVT VT =
N->getValueType(0);
2986 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2994SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3007 switch (getTypeAction(VecVT)) {
3010 SDValue Res = GetScalarizedVector(
N->getOperand(0));
3011 ReplaceValueWith(
SDValue(
N, 0), Res);
3015 Vec = GetWidenedVector(Vec);
3017 ReplaceValueWith(
SDValue(
N, 0), Res);
3022 GetSplitVector(Vec,
Lo,
Hi);
3024 uint64_t LoElts =
Lo.getValueType().getVectorNumElements();
3026 if (IdxVal < LoElts)
3030 DAG.getConstant(IdxVal - LoElts,
DL,
3032 ReplaceValueWith(
SDValue(
N, 0), Res);
3040 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3045 NewOp,
N->getOperand(1));
3048 EVT VT =
N->getValueType(0);
3049 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3057 EVT VT =
N->getValueType(0);
3058 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3059 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3063 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1);
3070 EVT VT =
N->getValueType(0);
3071 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3072 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3073 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT,
Op);
3079SDValue DAGTypeLegalizer::PromoteFloatRes_AssertNoFPClass(
SDNode *
N) {
3080 return GetPromotedFloat(
N->getOperand(0));
3087 EVT VT =
N->getValueType(0);
3088 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3089 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3090 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
3091 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1,
N->getFlags());
3095 EVT VT =
N->getValueType(0);
3096 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3097 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3098 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
3099 SDValue Op2 = GetPromotedFloat(
N->getOperand(2));
3101 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1, Op2);
3106 EVT VT =
N->getValueType(0);
3107 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3108 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3111 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1);
3115 EVT VT =
N->getValueType(0);
3116 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3117 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3119 DAG.
getNode(
N->getOpcode(), SDLoc(
N), {NVT,
N->getValueType(1)},
Op);
3125SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryWithTwoFPResults(
SDNode *
N) {
3126 EVT VT =
N->getValueType(0);
3127 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3128 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3131 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
3145 EVT VT =
N->getValueType(0);
3146 EVT OpVT =
Op->getValueType(0);
3147 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
3158SDValue DAGTypeLegalizer::PromoteFloatRes_STRICT_FP_ROUND(
SDNode *
N) {
3163 EVT VT =
N->getValueType(0);
3164 EVT OpVT =
Op->getValueType(0);
3165 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
3170 DAG.getVTList(IVT, MVT::Other), Chain,
Op);
3174 DAG.getVTList(NVT, MVT::Other), Round.
getValue(1), Round);
3181 EVT VT =
N->getValueType(0);
3186 L->getAddressingMode(),
L->getExtensionType(), IVT, SDLoc(
N),
3187 L->getChain(),
L->getBasePtr(),
L->getOffset(),
L->getPointerInfo(), IVT,
3188 L->getBaseAlign(),
L->getMemOperand()->getFlags(),
L->getAAInfo());
3194 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3198SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD(
SDNode *
N) {
3205 ISD::ATOMIC_LOAD, SDLoc(
N), IVT, DAG.getVTList(IVT, MVT::Other),
3213 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3223 N->getOperand(0), TrueVal, FalseVal);
3233 TrueVal.getNode()->getValueType(0),
N->getOperand(0),
3234 N->getOperand(1), TrueVal, FalseVal,
N->getOperand(4));
3241 EVT VT =
N->getValueType(0);
3242 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3243 SDValue NV = DAG.getNode(
N->getOpcode(),
DL, NVT,
N->getOperand(0));
3246 ISD::FP_EXTEND,
DL, NVT,
3248 DAG.getIntPtrConstant(0,
DL,
true)));
3252 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
3253 N->getValueType(0)));
3261 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3265SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
3266 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3271 EVT VT =
N->getValueType(0);
3280 = DAG.getAtomic(ISD::ATOMIC_SWAP, SL, CastVT,
3281 DAG.getVTList(CastVT, MVT::Other),
3282 { AM->getChain(), AM->getBasePtr(), CastVal },
3288 EVT NFPVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3305void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
3306 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
3311 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
3316 switch (
N->getOpcode()) {
3319 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
3320 N->dump(&DAG);
dbgs() <<
"\n";
3325 case ISD::ARITH_FENCE:
3326 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
3327 case ISD::BITCAST:
R = SoftPromoteHalfRes_BITCAST(
N);
break;
3330 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
3350 case ISD::FNEARBYINT:
3354 case ISD::FROUNDEVEN:
3363 R = SoftPromoteHalfRes_FABS(
N);
3366 R = SoftPromoteHalfRes_FNEG(
N);
3369 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
3377 case ISD::FMAXIMUMNUM:
3378 case ISD::FMINIMUMNUM:
3385 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
3388 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
3391 case ISD::FLDEXP:
R = SoftPromoteHalfRes_ExpOp(
N);
break;
3393 case ISD::FFREXP:
R = SoftPromoteHalfRes_FFREXP(
N);
break;
3397 case ISD::FSINCOSPI:
3398 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
3401 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
3402 case ISD::ATOMIC_LOAD:
3403 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
3412 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
3413 case ISD::ATOMIC_SWAP:
R = BitcastToInt_ATOMIC_SWAP(
N);
break;
3414 case ISD::VECREDUCE_FADD:
3415 case ISD::VECREDUCE_FMUL:
3416 case ISD::VECREDUCE_FMIN:
3417 case ISD::VECREDUCE_FMAX:
3418 case ISD::VECREDUCE_FMAXIMUM:
3419 case ISD::VECREDUCE_FMINIMUM:
3420 R = SoftPromoteHalfRes_VECREDUCE(
N);
3422 case ISD::VECREDUCE_SEQ_FADD:
3423 case ISD::VECREDUCE_SEQ_FMUL:
3424 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
3429 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
3432SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
3433 return DAG.
getNode(ISD::ARITH_FENCE, SDLoc(
N), MVT::i16,
3434 BitConvertToInteger(
N->getOperand(0)));
3438 return BitConvertToInteger(
N->getOperand(0));
3441SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
3449SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3450 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3456SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
3457 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
3458 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
3461 EVT LVT =
LHS.getValueType();
3462 EVT RVT =
RHS.getValueType();
3469 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
3470 DAG.getConstant(RSize - 1, dl,
3471 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
3479 DAG.getConstant(SizeDiff, dl,
3481 DAG.getDataLayout())));
3483 }
else if (SizeDiff < 0) {
3487 DAG.getConstant(-SizeDiff, dl,
3489 DAG.getDataLayout())));
3494 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
3495 DAG.getConstant(LSize - 1, dl,
3496 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
3497 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
3501 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
3506 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3507 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3508 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3509 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3514 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3515 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3516 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
3525 EVT OVT =
N->getValueType(0);
3526 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3527 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3541 EVT OVT =
N->getValueType(0);
3542 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3543 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3550 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
3558SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
3559 EVT OVT =
N->getValueType(0);
3560 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3561 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3570 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
3572 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
3573 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
3579SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
3580 EVT RVT =
N->getValueType(0);
3581 bool IsStrict =
N->isStrictFPOpcode();
3582 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3583 EVT SVT =
Op.getValueType();
3589 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
3592 Op = GetSoftenedFloat(
Op);
3593 TargetLowering::MakeLibCallOptions CallOptions;
3595 std::pair<SDValue, SDValue> Tmp =
3596 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
3598 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
3599 return DAG.getNode(ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
3604 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
3619 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
3620 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
3621 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
3622 L->getMemOperand()->getFlags(),
L->getAAInfo());
3629SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3634 ISD::ATOMIC_LOAD, SDLoc(
N), MVT::i16, DAG.getVTList(MVT::i16, MVT::Other),
3644 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3645 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3646 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1,
3650SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3651 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3652 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3654 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3658SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3659 EVT OVT =
N->getValueType(0);
3660 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3663 if (
N->isStrictFPOpcode()) {
3664 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
3665 {N->getOperand(0), N->getOperand(1)});
3667 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
3668 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3679 return DAG.getUNDEF(MVT::i16);
3683 EVT OVT =
N->getValueType(0);
3684 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3685 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3698 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3702 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
3703 DAG.getConstant(0x7fff, dl, MVT::i16));
3707 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3711 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
3712 DAG.getConstant(0x8000, dl, MVT::i16));
3715SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
3716 return GetSoftPromotedHalf(
N->getOperand(0));
3720 EVT OVT =
N->getValueType(0);
3721 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3722 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3723 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3728 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3729 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3737SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3739 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3743SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3745 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3753bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3754 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3758 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3768 switch (
N->getOpcode()) {
3771 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3772 N->dump(&DAG);
dbgs() <<
"\n";
3777 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3779 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3781 case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
break;
3790 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3794 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3796 case ISD::FP_EXTEND: Res = SoftPromoteHalfOp_FP_EXTEND(
N);
break;
3797 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3798 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3799 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3800 case ISD::ATOMIC_STORE:
3801 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3804 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3806 case ISD::PATCHPOINT:
3807 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3817 "Invalid operand expansion");
3819 ReplaceValueWith(
SDValue(
N, 0), Res);
3824 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3826 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3829SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3830 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3831 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3832 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3838 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3843 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3845 Op1 = GetSoftPromotedHalf(Op1);
3848 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3852SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3853 EVT RVT =
N->getValueType(0);
3854 bool IsStrict =
N->isStrictFPOpcode();
3855 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3856 EVT SVT =
Op.getValueType();
3857 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3861 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3863 ReplaceValueWith(
SDValue(
N, 0), Res);
3870SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3871 EVT RVT =
N->getValueType(0);
3872 bool IsStrict =
N->isStrictFPOpcode();
3873 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3874 EVT SVT =
Op.getValueType();
3877 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3878 Op = GetSoftPromotedHalf(
Op);
3882 {
N->getOperand(0),
Op});
3883 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3884 {Op.getValue(1), Op});
3885 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3891 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3894SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3895 EVT RVT =
N->getValueType(0);
3897 EVT SVT =
Op.getValueType();
3900 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3902 Op = GetSoftPromotedHalf(
Op);
3906 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3912 assert(OpNo == 0 &&
"Can only soften the comparison values");
3918 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3920 Op0 = GetSoftPromotedHalf(Op0);
3921 Op1 = GetSoftPromotedHalf(Op1);
3925 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3926 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3929 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3939 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3941 Op0 = GetSoftPromotedHalf(Op0);
3942 Op1 = GetSoftPromotedHalf(Op1);
3946 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3947 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3949 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3952SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3953 assert(OpNo == 1 &&
"Can only soften the stored value!");
3958 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3959 SDValue Promoted = GetSoftPromotedHalf(Val);
3960 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3961 ST->getMemOperand());
3964SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3966 assert(OpNo == 1 &&
"Can only soften the stored value!");
3971 SDValue Promoted = GetSoftPromotedHalf(Val);
3972 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, Promoted.
getValueType(),
3973 ST->getChain(), Promoted,
ST->getBasePtr(),
3974 ST->getMemOperand());
3977SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3981 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3983 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3985 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3996 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3998 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
4000 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
static bool isSigned(unsigned int Opcode)
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.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
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.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ 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) ...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ 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.
@ 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.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ 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.
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ 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 getMODF(EVT RetVT)
getMODF - Return the MODF_* 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 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.
DiagnosticInfoOptimizationBase::Argument NV
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...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT)
MakeLibCallOptions & setIsSigned(bool Value=true)