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.getLibcallImpl(LC) == RTLIB::Unsupported) {
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 RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
806 if (LCImpl == RTLIB::Unsupported)
809 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
816 std::array<SDValue, 2> StackSlots;
819 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
820 if (ResNum == CallRetResNo)
822 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
823 Ops.push_back(StackSlot);
825 StackSlots[ResNum] = StackSlot;
829 TargetLowering::MakeLibCallOptions CallOptions;
833 .setOpsTypeOverrides(CallOpsTypeOverrides);
835 auto [ReturnVal, Chain] =
836 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
839 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
843 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
846 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
847 if (CallRetResNo == ResNum) {
848 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
851 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
858 EVT VT =
N->getValueType(0);
867 if (TLI.getLibcallImpl(SinLC) == RTLIB::Unsupported ||
868 TLI.getLibcallImpl(CosLC) == RTLIB::Unsupported) {
869 DAG.getContext()->emitError(
"do not know how to soften fsincos");
871 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
872 SoftSin = SoftCos = DAG.getPOISON(NVT);
874 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
875 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
878 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
879 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
884 EVT VT =
N->getValueType(0);
889 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
890 DAG.getContext()->emitError(
"do not know how to soften fmodf");
903 RTLIB::REM_PPCF128));
912 RTLIB::RINT_PPCF128));
921 RTLIB::ROUND_PPCF128));
926 RTLIB::ROUNDEVEN_F32,
927 RTLIB::ROUNDEVEN_F64,
928 RTLIB::ROUNDEVEN_F80,
929 RTLIB::ROUNDEVEN_F128,
930 RTLIB::ROUNDEVEN_PPCF128));
939 RTLIB::SIN_PPCF128));
943 return SoftenFloatRes_Unary(
944 N,
GetFPLibCall(
N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
945 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
954 RTLIB::SQRT_PPCF128));
963 RTLIB::SUB_PPCF128));
967 return SoftenFloatRes_Unary(
968 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
969 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
973 return SoftenFloatRes_Unary(
974 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
975 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
984 RTLIB::TRUNC_PPCF128));
989 EVT VT =
N->getValueType(0);
990 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
994 L->getMemOperand()->getFlags() &
998 NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
999 L->getChain(),
L->getBasePtr(),
L->getOffset(),
1000 L->getPointerInfo(), NVT,
L->getBaseAlign(), MMOFlags,
1010 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
1011 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
1012 MMOFlags,
L->getAAInfo());
1016 auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL);
1017 return BitConvertToInteger(ExtendNode);
1022 EVT VT =
N->getValueType(0);
1023 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1028 DAG.getAtomic(ISD::ATOMIC_LOAD, dl, NVT, DAG.getVTList(NVT, MVT::Other),
1029 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
1043 return DAG.getSelect(SDLoc(
N),
1044 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
1051 LHS.getValueType(),
N->getOperand(0),
1052 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
1056 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
1057 N->getValueType(0)));
1063 EVT VT =
N->getValueType(0);
1064 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
1068 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
1069 N->getConstantOperandVal(3));
1079 bool IsStrict =
N->isStrictFPOpcode();
1082 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1083 EVT RVT =
N->getValueType(0);
1090 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1091 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1092 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1098 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1103 NVT,
N->getOperand(IsStrict ? 1 : 0));
1104 TargetLowering::MakeLibCallOptions CallOptions;
1107 std::pair<SDValue, SDValue> Tmp =
1108 TLI.makeLibCall(DAG, LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT),
1109 Op, CallOptions, dl, Chain);
1112 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1118 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1122SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1123 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1131bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1132 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1135 switch (
N->getOpcode()) {
1138 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1139 N->dump(&DAG);
dbgs() <<
"\n";
1143 case ISD::BITCAST: Res = SoftenFloatOp_BITCAST(
N);
break;
1144 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1145 case ISD::STRICT_FP_TO_FP16:
1146 case ISD::FP_TO_FP16:
1147 case ISD::FP_TO_BF16:
1148 case ISD::STRICT_FP_TO_BF16:
1157 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1159 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1161 case ISD::LLROUND: Res = SoftenFloatOp_LLROUND(
N);
break;
1163 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1165 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1169 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1170 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1171 case ISD::ATOMIC_STORE:
1172 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1176 Res = SoftenFloatOp_FAKE_USE(
N);
1179 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1181 case ISD::PATCHPOINT:
1182 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1187 if (!Res.
getNode())
return false;
1195 "Invalid operand softening");
1197 ReplaceValueWith(
SDValue(
N, 0), Res);
1202 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1204 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1211 N->getOpcode() == ISD::STRICT_FP_TO_FP16 ||
1212 N->getOpcode() == ISD::FP_TO_BF16 ||
1213 N->getOpcode() == ISD::STRICT_FP_TO_BF16 ||
1216 bool IsStrict =
N->isStrictFPOpcode();
1217 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1218 EVT SVT =
Op.getValueType();
1219 EVT RVT =
N->getValueType(0);
1221 if (
N->getOpcode() == ISD::FP_TO_FP16 ||
1222 N->getOpcode() == ISD::STRICT_FP_TO_FP16)
1223 FloatRVT = MVT::f16;
1224 else if (
N->getOpcode() == ISD::FP_TO_BF16 ||
1225 N->getOpcode() == ISD::STRICT_FP_TO_BF16)
1226 FloatRVT = MVT::bf16;
1229 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1232 Op = GetSoftenedFloat(
Op);
1233 TargetLowering::MakeLibCallOptions CallOptions;
1235 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, RVT,
Op,
1236 CallOptions, SDLoc(
N),
1239 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1240 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1251 NewLHS = GetSoftenedFloat(NewLHS);
1252 NewRHS = GetSoftenedFloat(NewRHS);
1253 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1254 N->getOperand(2),
N->getOperand(3));
1258 if (!NewRHS.getNode()) {
1259 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1264 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1265 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1275 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1276 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1277 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1281 if (Promoted.
bitsGE(RetVT))
1289 bool IsStrict =
N->isStrictFPOpcode();
1293 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1294 EVT SVT =
Op.getValueType();
1295 EVT RVT =
N->getValueType(0);
1305 "Unsupported FP_TO_XINT!");
1307 Op = GetSoftenedFloat(
Op);
1309 TargetLowering::MakeLibCallOptions CallOptions;
1311 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1312 CallOptions, dl, Chain);
1320 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1321 ReplaceValueWith(
SDValue(
N, 0), Res);
1325SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1326 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1335 NewLHS = GetSoftenedFloat(NewLHS);
1336 NewRHS = GetSoftenedFloat(NewRHS);
1337 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1338 N->getOperand(0),
N->getOperand(1));
1342 if (!NewRHS.getNode()) {
1343 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1348 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1349 N->getOperand(2),
N->getOperand(3),
1350 DAG.getCondCode(CCCode)),
1355 bool IsStrict =
N->isStrictFPOpcode();
1363 SDValue NewLHS = GetSoftenedFloat(Op0);
1364 SDValue NewRHS = GetSoftenedFloat(Op1);
1365 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1372 NewRHS, DAG.getCondCode(CCCode));
1374 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1375 DAG.getCondCode(CCCode)), 0);
1380 "Unexpected setcc expansion!");
1383 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1384 ReplaceValueWith(
SDValue(
N, 1), Chain);
1390SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1392 assert(OpNo == 1 &&
"Can only soften the stored value!");
1397 if (
ST->isTruncatingStore())
1399 Val = BitConvertToInteger(
1401 DAG.getIntPtrConstant(0, dl,
true)));
1403 Val = GetSoftenedFloat(Val);
1405 return DAG.getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1406 ST->getMemOperand());
1409SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1410 assert(OpNo == 1 &&
"Can only soften the stored value!");
1416 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1418 SDValue NewVal = GetSoftenedFloat(Val);
1419 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, VT,
ST->getChain(), NewVal,
1420 ST->getBasePtr(),
ST->getMemOperand());
1425 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1428 EVT LVT =
LHS.getValueType();
1430 EVT RVT =
RHS.getValueType();
1436 int SizeDiff = RSize - LSize;
1440 DAG.getConstant(SizeDiff, dl,
1441 TLI.getShiftAmountTy(
RHS.getValueType(),
1442 DAG.getDataLayout())));
1444 }
else if (SizeDiff < 0) {
1448 DAG.getConstant(-SizeDiff, dl,
1449 TLI.getShiftAmountTy(
RHS.getValueType(),
1450 DAG.getDataLayout())));
1453 RHS = DAG.getBitcast(LVT,
RHS);
1457SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1458 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1459 bool IsStrict =
N->isStrictFPOpcode();
1460 unsigned Offset = IsStrict ? 1 : 0;
1463 TargetLowering::MakeLibCallOptions CallOptions;
1464 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1466 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, NVT,
Op,
1467 CallOptions, SDLoc(
N),
1470 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1471 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1479 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1485 RTLIB::LROUND_PPCF128));
1489 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1494 RTLIB::LLROUND_F128,
1495 RTLIB::LLROUND_PPCF128));
1499 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1505 RTLIB::LRINT_PPCF128));
1509 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1515 RTLIB::LLRINT_PPCF128));
1519 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1520 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1521 N->getOperand(0), Op1);
1524SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1527 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1528 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1531SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1534 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1535 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1546void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1552 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1555 switch (
N->getOpcode()) {
1558 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1559 N->dump(&DAG);
dbgs() <<
"\n";
1570 case ISD::BITCAST: ExpandRes_BITCAST(
N,
Lo,
Hi);
break;
1574 case ISD::VAARG: ExpandRes_VAARG(
N,
Lo,
Hi);
break;
1578 case ISD::FABS: ExpandFloatRes_FABS(
N,
Lo,
Hi);
break;
1580 case ISD::FMINNUM: ExpandFloatRes_FMINNUM(
N,
Lo,
Hi);
break;
1582 case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(
N,
Lo,
Hi);
break;
1583 case ISD::FMINIMUMNUM: ExpandFloatRes_FMINIMUMNUM(
N,
Lo,
Hi);
break;
1584 case ISD::FMAXIMUMNUM: ExpandFloatRes_FMAXIMUMNUM(
N,
Lo,
Hi);
break;
1588 case ISD::FACOS: ExpandFloatRes_FACOS(
N,
Lo,
Hi);
break;
1590 case ISD::FASIN: ExpandFloatRes_FASIN(
N,
Lo,
Hi);
break;
1592 case ISD::FATAN: ExpandFloatRes_FATAN(
N,
Lo,
Hi);
break;
1594 case ISD::FATAN2: ExpandFloatRes_FATAN2(
N,
Lo,
Hi);
break;
1595 case ISD::FCBRT: ExpandFloatRes_FCBRT(
N,
Lo,
Hi);
break;
1597 case ISD::FCEIL: ExpandFloatRes_FCEIL(
N,
Lo,
Hi);
break;
1600 case ISD::FCOS: ExpandFloatRes_FCOS(
N,
Lo,
Hi);
break;
1602 case ISD::FCOSH: ExpandFloatRes_FCOSH(
N,
Lo,
Hi);
break;
1606 case ISD::FEXP: ExpandFloatRes_FEXP(
N,
Lo,
Hi);
break;
1608 case ISD::FEXP2: ExpandFloatRes_FEXP2(
N,
Lo,
Hi);
break;
1609 case ISD::FEXP10: ExpandFloatRes_FEXP10(
N,
Lo,
Hi);
break;
1611 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(
N,
Lo,
Hi);
break;
1613 case ISD::FLOG: ExpandFloatRes_FLOG(
N,
Lo,
Hi);
break;
1615 case ISD::FLOG2: ExpandFloatRes_FLOG2(
N,
Lo,
Hi);
break;
1617 case ISD::FLOG10: ExpandFloatRes_FLOG10(
N,
Lo,
Hi);
break;
1623 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(
N,
Lo,
Hi);
break;
1624 case ISD::FNEG: ExpandFloatRes_FNEG(
N,
Lo,
Hi);
break;
1626 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(
N,
Lo,
Hi);
break;
1628 case ISD::FPOW: ExpandFloatRes_FPOW(
N,
Lo,
Hi);
break;
1630 case ISD::FPOWI: ExpandFloatRes_FPOWI(
N,
Lo,
Hi);
break;
1635 case ISD::FRINT: ExpandFloatRes_FRINT(
N,
Lo,
Hi);
break;
1637 case ISD::FROUND: ExpandFloatRes_FROUND(
N,
Lo,
Hi);
break;
1639 case ISD::FROUNDEVEN: ExpandFloatRes_FROUNDEVEN(
N,
Lo,
Hi);
break;
1641 case ISD::FSIN: ExpandFloatRes_FSIN(
N,
Lo,
Hi);
break;
1643 case ISD::FSINH: ExpandFloatRes_FSINH(
N,
Lo,
Hi);
break;
1645 case ISD::FSQRT: ExpandFloatRes_FSQRT(
N,
Lo,
Hi);
break;
1649 case ISD::FTAN: ExpandFloatRes_FTAN(
N,
Lo,
Hi);
break;
1651 case ISD::FTANH: ExpandFloatRes_FTANH(
N,
Lo,
Hi);
break;
1653 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(
N,
Lo,
Hi);
break;
1654 case ISD::LOAD: ExpandFloatRes_LOAD(
N,
Lo,
Hi);
break;
1661 case ISD::FMODF: ExpandFloatRes_FMODF(
N);
break;
1662 case ISD::FSINCOS: ExpandFloatRes_FSINCOS(
N);
break;
1663 case ISD::FSINCOSPI: ExpandFloatRes_FSINCOSPI(
N);
break;
1674 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1676 "Do not know how to expand this float constant!");
1680 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1681 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1684void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1686 bool IsStrict =
N->isStrictFPOpcode();
1687 unsigned Offset = IsStrict ? 1 : 0;
1690 TargetLowering::MakeLibCallOptions CallOptions;
1691 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1692 Op, CallOptions, SDLoc(
N),
1695 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1696 GetPairElements(Tmp.first,
Lo,
Hi);
1699void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1701 bool IsStrict =
N->isStrictFPOpcode();
1702 unsigned Offset = IsStrict ? 1 : 0;
1705 TargetLowering::MakeLibCallOptions CallOptions;
1706 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1707 Ops, CallOptions, SDLoc(
N),
1710 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1711 GetPairElements(Tmp.first,
Lo,
Hi);
1714void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1715 ExpandFloatRes_UnaryWithTwoFPResults(
N,
RTLIB::getMODF(
N->getValueType(0)),
1719void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1723void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1724 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1728void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1729 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1730 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1732 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1735 GetPairElements(Res,
Lo,
Hi);
1742 assert(
N->getValueType(0) == MVT::ppcf128 &&
1743 "Logic only correct for ppcf128!");
1746 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1749 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1750 DAG.getNode(ISD::FNEG, dl,
Lo.getValueType(),
Lo),
1757 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1758 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1759 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1765 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1766 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1767 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1772 ExpandFloatRes_Binary(
1775 RTLIB::FMINIMUM_NUM_F64, RTLIB::FMINIMUM_NUM_F80,
1776 RTLIB::FMINIMUM_NUM_F128, RTLIB::FMINIMUM_NUM_PPCF128),
1782 ExpandFloatRes_Binary(
1785 RTLIB::FMAXIMUM_NUM_F64, RTLIB::FMAXIMUM_NUM_F80,
1786 RTLIB::FMAXIMUM_NUM_F128, RTLIB::FMAXIMUM_NUM_PPCF128),
1793 RTLIB::ADD_F32, RTLIB::ADD_F64,
1794 RTLIB::ADD_F80, RTLIB::ADD_F128,
1795 RTLIB::ADD_PPCF128),
Lo,
Hi);
1800 ExpandFloatRes_Unary(
N,
1802 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1803 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1809 ExpandFloatRes_Unary(
N,
1811 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1812 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1818 ExpandFloatRes_Unary(
N,
1820 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1821 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1827 ExpandFloatRes_Binary(
N,
1829 RTLIB::ATAN2_F64, RTLIB::ATAN2_F80,
1830 RTLIB::ATAN2_F128, RTLIB::ATAN2_PPCF128),
1836 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1837 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1839 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1842void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1845 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1846 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1847 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1850void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1853 RTLIB::COPYSIGN_F32,
1854 RTLIB::COPYSIGN_F64,
1855 RTLIB::COPYSIGN_F80,
1856 RTLIB::COPYSIGN_F128,
1857 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1860void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1863 RTLIB::COS_F32, RTLIB::COS_F64,
1864 RTLIB::COS_F80, RTLIB::COS_F128,
1865 RTLIB::COS_PPCF128),
Lo,
Hi);
1870 ExpandFloatRes_Unary(
N,
1872 RTLIB::COSH_F64, RTLIB::COSH_F80,
1873 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1884 RTLIB::DIV_PPCF128),
Lo,
Hi);
1887void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1890 RTLIB::EXP_F32, RTLIB::EXP_F64,
1891 RTLIB::EXP_F80, RTLIB::EXP_F128,
1892 RTLIB::EXP_PPCF128),
Lo,
Hi);
1895void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1898 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1899 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1900 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1905 ExpandFloatRes_Unary(
N,
1907 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1908 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1912void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1915 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1916 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1917 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1920void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1923 RTLIB::LOG_F32, RTLIB::LOG_F64,
1924 RTLIB::LOG_F80, RTLIB::LOG_F128,
1925 RTLIB::LOG_PPCF128),
Lo,
Hi);
1928void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1931 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1932 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1933 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1936void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1939 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1940 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1941 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1946 bool IsStrict =
N->isStrictFPOpcode();
1947 unsigned Offset = IsStrict ? 1 : 0;
1951 TargetLowering::MakeLibCallOptions CallOptions;
1952 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG,
GetFPLibCall(
N->getValueType(0),
1957 RTLIB::FMA_PPCF128),
1958 N->getValueType(0),
Ops, CallOptions,
1961 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1962 GetPairElements(Tmp.first,
Lo,
Hi);
1972 RTLIB::MUL_PPCF128),
Lo,
Hi);
1975void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1978 RTLIB::NEARBYINT_F32,
1979 RTLIB::NEARBYINT_F64,
1980 RTLIB::NEARBYINT_F80,
1981 RTLIB::NEARBYINT_F128,
1982 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
1988 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1989 Lo = DAG.getNode(ISD::FNEG, dl,
Lo.getValueType(),
Lo);
1990 Hi = DAG.getNode(ISD::FNEG, dl,
Hi.getValueType(),
Hi);
1993void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1997 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2002 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
2004 bool IsStrict =
N->isStrictFPOpcode();
2009 if (NVT ==
N->getOperand(1).getValueType()) {
2010 Hi =
N->getOperand(1);
2015 {
N->getOperand(0),
N->getOperand(1) });
2019 Hi = DAG.getNode(ISD::FP_EXTEND, dl, NVT,
N->getOperand(0));
2025 ReplaceValueWith(
SDValue(
N, 1), Chain);
2028void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
2031 RTLIB::POW_F32, RTLIB::POW_F64,
2032 RTLIB::POW_F80, RTLIB::POW_F128,
2033 RTLIB::POW_PPCF128),
Lo,
Hi);
2036void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
2046void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
2048 assert(
N->getValueType(0) == MVT::ppcf128 &&
2049 "Logic only correct for ppcf128!");
2052 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
2057void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
2060 RTLIB::REM_F32, RTLIB::REM_F64,
2061 RTLIB::REM_F80, RTLIB::REM_F128,
2062 RTLIB::REM_PPCF128),
Lo,
Hi);
2065void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
2068 RTLIB::RINT_F32, RTLIB::RINT_F64,
2069 RTLIB::RINT_F80, RTLIB::RINT_F128,
2070 RTLIB::RINT_PPCF128),
Lo,
Hi);
2073void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
2080 RTLIB::ROUND_PPCF128),
Lo,
Hi);
2083void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
2086 RTLIB::ROUNDEVEN_F32,
2087 RTLIB::ROUNDEVEN_F64,
2088 RTLIB::ROUNDEVEN_F80,
2089 RTLIB::ROUNDEVEN_F128,
2090 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
2093void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
2096 RTLIB::SIN_F32, RTLIB::SIN_F64,
2097 RTLIB::SIN_F80, RTLIB::SIN_F128,
2098 RTLIB::SIN_PPCF128),
Lo,
Hi);
2103 ExpandFloatRes_Unary(
N,
2105 RTLIB::SINH_F64, RTLIB::SINH_F80,
2106 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
2110void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
2113 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
2114 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
2115 RTLIB::SQRT_PPCF128),
Lo,
Hi);
2125 RTLIB::SUB_PPCF128),
Lo,
Hi);
2130 ExpandFloatRes_Unary(
N,
2132 RTLIB::TAN_F64, RTLIB::TAN_F80,
2133 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
2139 ExpandFloatRes_Unary(
N,
2141 RTLIB::TANH_F64, RTLIB::TANH_F80,
2142 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
2146void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2149 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
2150 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
2151 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
2157 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2167 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2169 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2171 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2172 LD->getMemoryVT(),
LD->getMemOperand());
2182 ReplaceValueWith(
SDValue(LD, 1), Chain);
2187 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2188 EVT VT =
N->getValueType(0);
2189 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2190 bool Strict =
N->isStrictFPOpcode();
2191 SDValue Src =
N->getOperand(Strict ? 1 : 0);
2192 EVT SrcVT = Src.getValueType();
2200 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2205 if (SrcVT.
bitsLE(MVT::i32)) {
2209 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2210 {Chain, Src}, Flags);
2213 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2215 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2216 if (SrcVT.
bitsLE(MVT::i64)) {
2219 LC = RTLIB::SINTTOFP_I64_PPCF128;
2220 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2222 LC = RTLIB::SINTTOFP_I128_PPCF128;
2224 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2226 TargetLowering::MakeLibCallOptions CallOptions;
2228 std::pair<SDValue, SDValue> Tmp =
2229 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2232 GetPairElements(Tmp.first,
Lo,
Hi);
2238 ReplaceValueWith(
SDValue(
N, 1), Chain);
2248 SrcVT = Src.getValueType();
2251 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2252 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2253 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2254 ArrayRef<uint64_t> Parts;
2271 SDValue NewLo = DAG.getConstantFP(
2275 {Chain, Hi, NewLo}, Flags);
2277 ReplaceValueWith(
SDValue(
N, 1), Chain);
2280 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2282 GetPairElements(
Lo,
Lo,
Hi);
2294bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2299 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2302 switch (
N->getOpcode()) {
2305 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2306 N->dump(&DAG);
dbgs() <<
"\n";
2310 case ISD::BITCAST: Res = ExpandOp_BITCAST(
N);
break;
2314 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2322 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2323 case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(
N);
break;
2324 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2325 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2329 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2335 if (!Res.
getNode())
return false;
2343 "Invalid operand expansion");
2345 ReplaceValueWith(
SDValue(
N, 0), Res);
2351void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2356 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2357 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2358 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2367 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2368 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2371 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2372 RHSLo, CCCode, OutputChain, IsSignaling);
2376 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2379 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2380 RHSHi, CCCode, OutputChain, IsSignaling);
2385 Chain = OutputChain;
2392 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2397 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2402 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2403 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2404 N->getOperand(4)), 0);
2408 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2409 "Logic only correct for ppcf128!");
2411 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2415 N->getValueType(0),
N->getOperand(0),
Hi);
2419 bool IsStrict =
N->isStrictFPOpcode();
2420 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2421 "Logic only correct for ppcf128!");
2423 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2428 N->getValueType(0),
Hi,
N->getOperand(1));
2432 if (
Hi.getValueType() ==
N->getValueType(0)) {
2434 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2440 {
N->getValueType(0), MVT::Other},
2441 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2448 EVT RVT =
N->getValueType(0);
2451 bool IsStrict =
N->isStrictFPOpcode();
2454 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2460 "Unsupported FP_TO_XINT!");
2461 TargetLowering::MakeLibCallOptions CallOptions;
2462 std::pair<SDValue, SDValue> Tmp =
2463 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2467 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2468 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2476 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2481 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2486 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2487 N->getOperand(2),
N->getOperand(3),
2488 DAG.getCondCode(CCCode)), 0);
2492 bool IsStrict =
N->isStrictFPOpcode();
2498 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2504 "Unexpected setcc expansion!");
2506 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2507 ReplaceValueWith(
SDValue(
N, 1), Chain);
2513SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2515 return ExpandOp_NormalStore(
N, OpNo);
2518 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2524 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2525 ST->getValue().getValueType());
2527 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2531 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2533 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2534 ST->getMemoryVT(),
ST->getMemOperand());
2538 EVT RVT =
N->getValueType(0);
2539 EVT RetVT =
N->getOperand(0).getValueType();
2540 TargetLowering::MakeLibCallOptions CallOptions;
2546 RTLIB::LROUND_PPCF128),
2547 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2551 EVT RVT =
N->getValueType(0);
2552 EVT RetVT =
N->getOperand(0).getValueType();
2553 TargetLowering::MakeLibCallOptions CallOptions;
2558 RTLIB::LLROUND_F128,
2559 RTLIB::LLROUND_PPCF128),
2560 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2564 EVT RVT =
N->getValueType(0);
2565 EVT RetVT =
N->getOperand(0).getValueType();
2566 TargetLowering::MakeLibCallOptions CallOptions;
2572 RTLIB::LRINT_PPCF128),
2573 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2577 EVT RVT =
N->getValueType(0);
2578 EVT RetVT =
N->getOperand(0).getValueType();
2579 TargetLowering::MakeLibCallOptions CallOptions;
2585 RTLIB::LLRINT_PPCF128),
2586 RVT,
N->getOperand(0), CallOptions, SDLoc(
N)).first;
2595 if (OpVT == MVT::f16)
2596 return ISD::FP16_TO_FP;
2597 if (RetVT == MVT::f16)
2598 return ISD::FP_TO_FP16;
2599 if (OpVT == MVT::bf16)
2600 return ISD::BF16_TO_FP;
2601 if (RetVT == MVT::bf16)
2602 return ISD::FP_TO_BF16;
2607 if (OpVT == MVT::f16)
2608 return ISD::STRICT_FP16_TO_FP;
2609 if (RetVT == MVT::f16)
2610 return ISD::STRICT_FP_TO_FP16;
2611 if (OpVT == MVT::bf16)
2612 return ISD::STRICT_BF16_TO_FP;
2613 if (RetVT == MVT::bf16)
2614 return ISD::STRICT_FP_TO_BF16;
2618bool DAGTypeLegalizer::PromoteFloatOperand(
SDNode *
N,
unsigned OpNo) {
2619 LLVM_DEBUG(
dbgs() <<
"Promote float operand " << OpNo <<
": ";
N->dump(&DAG));
2622 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2633 switch (
N->getOpcode()) {
2636 dbgs() <<
"PromoteFloatOperand Op #" << OpNo <<
": ";
2637 N->dump(&DAG);
dbgs() <<
"\n";
2641 case ISD::BITCAST:
R = PromoteFloatOp_BITCAST(
N, OpNo);
break;
2643 R = PromoteFloatOp_FAKE_USE(
N, OpNo);
2651 case ISD::LLRINT:
R = PromoteFloatOp_UnaryOp(
N, OpNo);
break;
2655 R = PromoteFloatOp_FP_TO_XINT_SAT(
N, OpNo);
break;
2656 case ISD::FP_EXTEND:
R = PromoteFloatOp_FP_EXTEND(
N, OpNo);
break;
2658 R = PromoteFloatOp_STRICT_FP_EXTEND(
N, OpNo);
2661 case ISD::SETCC:
R = PromoteFloatOp_SETCC(
N, OpNo);
break;
2662 case ISD::STORE:
R = PromoteFloatOp_STORE(
N, OpNo);
break;
2663 case ISD::ATOMIC_STORE:
R = PromoteFloatOp_ATOMIC_STORE(
N, OpNo);
break;
2668 ReplaceValueWith(
SDValue(
N, 0), R);
2672SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(
SDNode *
N,
unsigned OpNo) {
2674 EVT OpVT =
Op->getValueType(0);
2676 SDValue Promoted = GetPromotedFloat(
N->getOperand(0));
2685 return DAG.getBitcast(
N->getValueType(0), Convert);
2688SDValue DAGTypeLegalizer::PromoteFloatOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
2689 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
2690 SDValue Op = GetPromotedFloat(
N->getOperand(OpNo));
2691 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
2697SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(
SDNode *
N,
unsigned OpNo) {
2698 assert (OpNo == 1 &&
"Only Operand 1 must need promotion here");
2699 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2701 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
2702 N->getOperand(0), Op1);
2706SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(
SDNode *
N,
unsigned OpNo) {
2707 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2708 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
Op);
2712SDValue DAGTypeLegalizer::PromoteFloatOp_AssertNoFPClass(
SDNode *
N,
2714 return GetPromotedFloat(
N->getOperand(0));
2717SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(
SDNode *
N,
2719 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2720 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
Op,
2724SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(
SDNode *
N,
unsigned OpNo) {
2725 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2726 EVT VT =
N->getValueType(0);
2729 if (VT ==
Op->getValueType(0))
2733 return DAG.getNode(ISD::FP_EXTEND, SDLoc(
N), VT,
Op);
2736SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(
SDNode *
N,
2738 assert(OpNo == 1 &&
"Promoting unpromotable operand");
2740 SDValue Op = GetPromotedFloat(
N->getOperand(1));
2741 EVT VT =
N->getValueType(0);
2744 if (VT ==
Op->getValueType(0)) {
2745 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2751 N->getOperand(0),
Op);
2759SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(
SDNode *
N,
unsigned OpNo) {
2764 LHS,
RHS,
N->getOperand(2),
N->getOperand(3),
2770SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(
SDNode *
N,
unsigned OpNo) {
2771 EVT VT =
N->getValueType(0);
2772 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2773 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2776 return DAG.getSetCC(SDLoc(
N), VT, Op0, Op1, CCCode);
2782SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2787 SDValue Promoted = GetPromotedFloat(Val);
2788 EVT VT =
ST->getOperand(1).getValueType();
2795 return DAG.getStore(
ST->getChain(),
DL, NewVal,
ST->getBasePtr(),
2796 ST->getMemOperand());
2805 SDValue Promoted = GetPromotedFloat(Val);
2806 EVT VT =
ST->getOperand(1).getValueType();
2812 return DAG.getAtomic(ISD::ATOMIC_STORE,
DL, IVT,
ST->getChain(), NewVal,
2813 ST->getBasePtr(),
ST->getMemOperand());
2820void DAGTypeLegalizer::PromoteFloatResult(
SDNode *
N,
unsigned ResNo) {
2821 LLVM_DEBUG(
dbgs() <<
"Promote float result " << ResNo <<
": ";
N->dump(&DAG));
2825 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2830 switch (
N->getOpcode()) {
2833 case ISD::FP16_TO_FP:
2834 case ISD::FP_TO_FP16:
2837 dbgs() <<
"PromoteFloatResult #" << ResNo <<
": ";
2838 N->dump(&DAG);
dbgs() <<
"\n";
2843 R = PromoteFloatRes_BITCAST(
N);
2846 R = PromoteFloatRes_FREEZE(
N);
2850 R = PromoteFloatRes_EXTRACT_VECTOR_ELT(
N);
break;
2869 case ISD::FNEARBYINT:
2873 case ISD::FROUNDEVEN:
2882 R = PromoteFloatRes_AssertNoFPClass(
N);
2890 case ISD::FMAXIMUMNUM:
2891 case ISD::FMINIMUMNUM:
2894 case ISD::FMAXNUM_IEEE:
2895 case ISD::FMINNUM_IEEE:
2900 case ISD::FSUB:
R = PromoteFloatRes_BinOp(
N);
break;
2903 case ISD::FMAD:
R = PromoteFloatRes_FMAD(
N);
break;
2906 case ISD::FLDEXP:
R = PromoteFloatRes_ExpOp(
N);
break;
2907 case ISD::FFREXP:
R = PromoteFloatRes_FFREXP(
N);
break;
2911 case ISD::FSINCOSPI:
2912 R = PromoteFloatRes_UnaryWithTwoFPResults(
N);
2916 R = PromoteFloatRes_STRICT_FP_ROUND(
N);
2918 case ISD::LOAD:
R = PromoteFloatRes_LOAD(
N);
break;
2919 case ISD::ATOMIC_LOAD:
2920 R = PromoteFloatRes_ATOMIC_LOAD(
N);
2929 case ISD::ATOMIC_SWAP:
R = BitcastToInt_ATOMIC_SWAP(
N);
break;
2930 case ISD::VECREDUCE_FADD:
2931 case ISD::VECREDUCE_FMUL:
2932 case ISD::VECREDUCE_FMIN:
2933 case ISD::VECREDUCE_FMAX:
2934 case ISD::VECREDUCE_FMAXIMUM:
2935 case ISD::VECREDUCE_FMINIMUM:
2936 R = PromoteFloatRes_VECREDUCE(
N);
2938 case ISD::VECREDUCE_SEQ_FADD:
2939 case ISD::VECREDUCE_SEQ_FMUL:
2940 R = PromoteFloatRes_VECREDUCE_SEQ(
N);
2945 SetPromotedFloat(
SDValue(
N, ResNo), R);
2954 EVT VT =
N->getValueType(0);
2955 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2959 N->getOperand(0).getValueType().getSizeInBits());
2960 SDValue Cast = DAG.getBitcast(IVT,
N->getOperand(0));
2965 EVT VT =
N->getValueType(0);
2966 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2970 N->getOperand(0).getValueType().getSizeInBits());
2971 SDValue Cast = DAG.getBitcast(IVT,
N->getOperand(0));
2973 DAG.getFreeze(Cast));
2978 EVT VT =
N->getValueType(0);
2989 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2997SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3010 switch (getTypeAction(VecVT)) {
3013 SDValue Res = GetScalarizedVector(
N->getOperand(0));
3014 ReplaceValueWith(
SDValue(
N, 0), Res);
3018 Vec = GetWidenedVector(Vec);
3020 ReplaceValueWith(
SDValue(
N, 0), Res);
3025 GetSplitVector(Vec,
Lo,
Hi);
3027 uint64_t LoElts =
Lo.getValueType().getVectorNumElements();
3029 if (IdxVal < LoElts)
3033 DAG.getConstant(IdxVal - LoElts,
DL,
3035 ReplaceValueWith(
SDValue(
N, 0), Res);
3043 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3048 NewOp,
N->getOperand(1));
3051 EVT VT =
N->getValueType(0);
3052 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3060 EVT VT =
N->getValueType(0);
3061 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3062 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3066 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1);
3073 EVT VT =
N->getValueType(0);
3074 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3075 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3076 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT,
Op);
3082SDValue DAGTypeLegalizer::PromoteFloatRes_AssertNoFPClass(
SDNode *
N) {
3083 return GetPromotedFloat(
N->getOperand(0));
3090 EVT VT =
N->getValueType(0);
3091 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3092 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3093 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
3094 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1,
N->getFlags());
3098 EVT VT =
N->getValueType(0);
3099 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3100 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3101 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
3102 SDValue Op2 = GetPromotedFloat(
N->getOperand(2));
3104 return DAG.getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1, Op2);
3109 EVT VT =
N->getValueType(0);
3110 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3111 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
3114 return DAG.
getNode(
N->getOpcode(), SDLoc(
N), NVT, Op0, Op1);
3118 EVT VT =
N->getValueType(0);
3119 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3120 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3122 DAG.
getNode(
N->getOpcode(), SDLoc(
N), {NVT,
N->getValueType(1)},
Op);
3128SDValue DAGTypeLegalizer::PromoteFloatRes_UnaryWithTwoFPResults(
SDNode *
N) {
3129 EVT VT =
N->getValueType(0);
3130 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3131 SDValue Op = GetPromotedFloat(
N->getOperand(0));
3134 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
3148 EVT VT =
N->getValueType(0);
3149 EVT OpVT =
Op->getValueType(0);
3150 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
3161SDValue DAGTypeLegalizer::PromoteFloatRes_STRICT_FP_ROUND(
SDNode *
N) {
3166 EVT VT =
N->getValueType(0);
3167 EVT OpVT =
Op->getValueType(0);
3168 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
3173 DAG.getVTList(IVT, MVT::Other), Chain,
Op);
3177 DAG.getVTList(NVT, MVT::Other), Round.
getValue(1), Round);
3184 EVT VT =
N->getValueType(0);
3189 L->getAddressingMode(),
L->getExtensionType(), IVT, SDLoc(
N),
3190 L->getChain(),
L->getBasePtr(),
L->getOffset(),
L->getPointerInfo(), IVT,
3191 L->getBaseAlign(),
L->getMemOperand()->getFlags(),
L->getAAInfo());
3197 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3201SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD(
SDNode *
N) {
3208 ISD::ATOMIC_LOAD, SDLoc(
N), IVT, DAG.getVTList(IVT, MVT::Other),
3216 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3226 N->getOperand(0), TrueVal, FalseVal);
3236 TrueVal.getNode()->getValueType(0),
N->getOperand(0),
3237 N->getOperand(1), TrueVal, FalseVal,
N->getOperand(4));
3244 EVT VT =
N->getValueType(0);
3245 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3246 SDValue NV = DAG.getNode(
N->getOpcode(),
DL, NVT,
N->getOperand(0));
3249 ISD::FP_EXTEND,
DL, NVT,
3251 DAG.getIntPtrConstant(0,
DL,
true)));
3255 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
3256 N->getValueType(0)));
3264 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3268SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
3269 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3274 EVT VT =
N->getValueType(0);
3283 = DAG.getAtomic(ISD::ATOMIC_SWAP, SL, CastVT,
3284 DAG.getVTList(CastVT, MVT::Other),
3285 { AM->getChain(), AM->getBasePtr(), CastVal },
3291 EVT NFPVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3308void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
3309 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
3314 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
3319 switch (
N->getOpcode()) {
3322 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
3323 N->dump(&DAG);
dbgs() <<
"\n";
3328 case ISD::ARITH_FENCE:
3329 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
3330 case ISD::BITCAST:
R = SoftPromoteHalfRes_BITCAST(
N);
break;
3333 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
3353 case ISD::FNEARBYINT:
3357 case ISD::FROUNDEVEN:
3366 R = SoftPromoteHalfRes_FABS(
N);
3369 R = SoftPromoteHalfRes_FNEG(
N);
3372 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
3380 case ISD::FMAXIMUMNUM:
3381 case ISD::FMINIMUMNUM:
3388 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
3391 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
3394 case ISD::FLDEXP:
R = SoftPromoteHalfRes_ExpOp(
N);
break;
3396 case ISD::FFREXP:
R = SoftPromoteHalfRes_FFREXP(
N);
break;
3400 case ISD::FSINCOSPI:
3401 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
3404 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
3405 case ISD::ATOMIC_LOAD:
3406 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
3415 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
3416 case ISD::ATOMIC_SWAP:
R = BitcastToInt_ATOMIC_SWAP(
N);
break;
3417 case ISD::VECREDUCE_FADD:
3418 case ISD::VECREDUCE_FMUL:
3419 case ISD::VECREDUCE_FMIN:
3420 case ISD::VECREDUCE_FMAX:
3421 case ISD::VECREDUCE_FMAXIMUM:
3422 case ISD::VECREDUCE_FMINIMUM:
3423 R = SoftPromoteHalfRes_VECREDUCE(
N);
3425 case ISD::VECREDUCE_SEQ_FADD:
3426 case ISD::VECREDUCE_SEQ_FMUL:
3427 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
3432 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
3435SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
3436 return DAG.
getNode(ISD::ARITH_FENCE, SDLoc(
N), MVT::i16,
3437 BitConvertToInteger(
N->getOperand(0)));
3441 return BitConvertToInteger(
N->getOperand(0));
3444SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
3452SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3453 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3459SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
3460 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
3461 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
3464 EVT LVT =
LHS.getValueType();
3465 EVT RVT =
RHS.getValueType();
3472 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
3473 DAG.getConstant(RSize - 1, dl,
3474 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
3482 DAG.getConstant(SizeDiff, dl,
3484 DAG.getDataLayout())));
3486 }
else if (SizeDiff < 0) {
3490 DAG.getConstant(-SizeDiff, dl,
3492 DAG.getDataLayout())));
3497 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
3498 DAG.getConstant(LSize - 1, dl,
3499 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
3500 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
3504 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
3509 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3510 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3511 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3512 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3517 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3518 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3519 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
3528 EVT OVT =
N->getValueType(0);
3529 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3530 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3544 EVT OVT =
N->getValueType(0);
3545 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3546 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3553 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
3561SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
3562 EVT OVT =
N->getValueType(0);
3563 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3564 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3573 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
3575 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
3576 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
3582SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
3583 EVT RVT =
N->getValueType(0);
3584 bool IsStrict =
N->isStrictFPOpcode();
3585 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3586 EVT SVT =
Op.getValueType();
3592 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
3595 Op = GetSoftenedFloat(
Op);
3596 TargetLowering::MakeLibCallOptions CallOptions;
3598 std::pair<SDValue, SDValue> Tmp =
3599 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
3601 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
3602 return DAG.getNode(ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
3607 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
3622 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
3623 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
3624 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
3625 L->getMemOperand()->getFlags(),
L->getAAInfo());
3632SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3637 ISD::ATOMIC_LOAD, SDLoc(
N), MVT::i16, DAG.getVTList(MVT::i16, MVT::Other),
3647 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3648 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3649 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1,
3653SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3654 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3655 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3657 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3661SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3662 EVT OVT =
N->getValueType(0);
3663 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3666 if (
N->isStrictFPOpcode()) {
3667 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
3668 {N->getOperand(0), N->getOperand(1)});
3670 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
3671 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3682 return DAG.getUNDEF(MVT::i16);
3686 EVT OVT =
N->getValueType(0);
3687 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3688 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3701 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3705 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
3706 DAG.getConstant(0x7fff, dl, MVT::i16));
3710 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3714 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
3715 DAG.getConstant(0x8000, dl, MVT::i16));
3718SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
3719 return GetSoftPromotedHalf(
N->getOperand(0));
3723 EVT OVT =
N->getValueType(0);
3724 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
3725 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3726 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3731 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3732 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3740SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3742 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3746SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3748 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3756bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3757 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3761 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3771 switch (
N->getOpcode()) {
3774 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3775 N->dump(&DAG);
dbgs() <<
"\n";
3780 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3782 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3784 case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
break;
3793 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3797 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3799 case ISD::FP_EXTEND: Res = SoftPromoteHalfOp_FP_EXTEND(
N);
break;
3800 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3801 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3802 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3803 case ISD::ATOMIC_STORE:
3804 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3807 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3809 case ISD::PATCHPOINT:
3810 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3820 "Invalid operand expansion");
3822 ReplaceValueWith(
SDValue(
N, 0), Res);
3827 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3829 return DAG.getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3832SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3833 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3834 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3835 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3841 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3846 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3848 Op1 = GetSoftPromotedHalf(Op1);
3851 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3855SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3856 EVT RVT =
N->getValueType(0);
3857 bool IsStrict =
N->isStrictFPOpcode();
3858 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3859 EVT SVT =
Op.getValueType();
3860 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3864 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3866 ReplaceValueWith(
SDValue(
N, 0), Res);
3873SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3874 EVT RVT =
N->getValueType(0);
3875 bool IsStrict =
N->isStrictFPOpcode();
3876 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3877 EVT SVT =
Op.getValueType();
3880 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3881 Op = GetSoftPromotedHalf(
Op);
3885 {
N->getOperand(0),
Op});
3886 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3887 {Op.getValue(1), Op});
3888 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3894 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3897SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3898 EVT RVT =
N->getValueType(0);
3900 EVT SVT =
Op.getValueType();
3903 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3905 Op = GetSoftPromotedHalf(
Op);
3909 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3915 assert(OpNo == 0 &&
"Can only soften the comparison values");
3921 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3923 Op0 = GetSoftPromotedHalf(Op0);
3924 Op1 = GetSoftPromotedHalf(Op1);
3928 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3929 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3932 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3942 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3944 Op0 = GetSoftPromotedHalf(Op0);
3945 Op1 = GetSoftPromotedHalf(Op1);
3949 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3950 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3952 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3955SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3956 assert(OpNo == 1 &&
"Can only soften the stored value!");
3961 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3962 SDValue Promoted = GetSoftPromotedHalf(Val);
3963 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3964 ST->getMemOperand());
3967SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3969 assert(OpNo == 1 &&
"Can only soften the stored value!");
3974 SDValue Promoted = GetSoftPromotedHalf(Val);
3975 return DAG.getAtomic(ISD::ATOMIC_STORE, dl, Promoted.
getValueType(),
3976 ST->getChain(), Promoted,
ST->getBasePtr(),
3977 ST->getMemOperand());
3980SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3984 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3986 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3988 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3999 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
4001 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
4003 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 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.
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)