27#define DEBUG_TYPE "legalize-types"
33 RTLIB::Libcall Call_F32,
34 RTLIB::Libcall Call_F64,
35 RTLIB::Libcall Call_F80,
36 RTLIB::Libcall Call_F128,
37 RTLIB::Libcall Call_PPCF128) {
39 VT == MVT::f32 ? Call_F32 :
40 VT == MVT::f64 ? Call_F64 :
41 VT == MVT::f80 ? Call_F80 :
42 VT == MVT::f128 ? Call_F128 :
43 VT == MVT::ppcf128 ? Call_PPCF128 :
44 RTLIB::UNKNOWN_LIBCALL;
51void DAGTypeLegalizer::SoftenFloatResult(
SDNode *
N,
unsigned ResNo) {
52 LLVM_DEBUG(
dbgs() <<
"Soften float result " << ResNo <<
": ";
N->dump(&DAG));
55 switch (
N->getOpcode()) {
59 dbgs() <<
"SoftenFloatResult #" << ResNo <<
": ";
60 N->dump(&DAG);
dbgs() <<
"\n";
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
74 R = SoftenFloatRes_FCANONICALIZE(
N);
break;
117 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
190 SetSoftenedFloat(
SDValue(
N, ResNo), R);
197 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
198 N->getOperationName(&DAG));
199 if (
N->isStrictFPOpcode())
200 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
201 return DAG.getPOISON(NVT);
204SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
206 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
207 unsigned Offset = IsStrict ? 1 : 0;
209 "Unexpected number of operands!");
212 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
213 if (LCImpl == RTLIB::Unsupported)
214 return SoftenFloatRes_NoLibcall(
N, NVT);
215 TargetLowering::MakeLibCallOptions CallOptions;
216 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
218 std::pair<SDValue, SDValue> Tmp =
219 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
221 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
225SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
226 bool IsStrict =
N->isStrictFPOpcode();
227 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
228 unsigned Offset = IsStrict ? 1 : 0;
230 "Unexpected number of operands!");
232 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
234 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
235 if (LCImpl == RTLIB::Unsupported)
236 return SoftenFloatRes_NoLibcall(
N, NVT);
237 TargetLowering::MakeLibCallOptions CallOptions;
238 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
239 N->getOperand(1 +
Offset).getValueType() };
241 std::pair<SDValue, SDValue> Tmp =
242 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
244 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
249 return BitConvertToInteger(
N->getOperand(0));
253 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
255 GetSoftenedFloat(
N->getOperand(0)));
259 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
261 GetSoftenedFloat(
N->getOperand(0)));
267 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
268 return BitConvertToInteger(
Op);
274 TLI.getTypeToTransformTo(*DAG.getContext(),
276 BitConvertToInteger(
N->getOperand(0)),
277 BitConvertToInteger(
N->getOperand(1)));
289 if (DAG.getDataLayout().isBigEndian() &&
293 APInt Val(128, words);
294 return DAG.getConstant(Val, SDLoc(CN),
295 TLI.getTypeToTransformTo(*DAG.getContext(),
299 TLI.getTypeToTransformTo(*DAG.getContext(),
304SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
306 assert(Src.getValueType() == MVT::ppcf128 &&
307 "In floats only ppcf128 can be extracted by element!");
309 N->getValueType(0).changeTypeToInteger(),
310 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
313SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
314 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
317 NewOp,
N->getOperand(1));
321 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
328 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
329 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
332SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
346 SDValue One = DAG.getConstantFP(1.0, dl, VT);
347 SDValue Chain = DAG.getEntryNode();
350 SDNodeFlags CanonicalizeFlags =
N->
getFlags();
353 {Chain, Operand, One}, CanonicalizeFlags);
354 return BitConvertToInteger(
Mul);
358 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
359 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
360 return SoftenFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)));
364 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
365 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
366 return SoftenFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)));
370 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)));
374 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)));
378 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM(
N->getValueType(0)));
382 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM(
N->getValueType(0)));
391 RTLIB::ADD_PPCF128));
395 return SoftenFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)));
399 return SoftenFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)));
403 return SoftenFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)));
407 return SoftenFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)));
411 return SoftenFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)));
415 return SoftenFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)));
420 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
423 EVT LVT =
LHS.getValueType();
424 EVT RVT =
RHS.getValueType();
431 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
432 DAG.getConstant(RSize - 1, dl,
433 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
441 DAG.getConstant(SizeDiff, dl,
443 DAG.getDataLayout())));
445 }
else if (SizeDiff < 0) {
449 DAG.getConstant(-SizeDiff, dl,
451 DAG.getDataLayout())));
456 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
457 DAG.getConstant(LSize - 1, dl,
458 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
459 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
463 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
467 return SoftenFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)));
471 return SoftenFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)));
480 RTLIB::DIV_PPCF128));
484 return SoftenFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)));
488 return SoftenFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)));
492 return SoftenFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)));
496 return SoftenFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)));
500 return SoftenFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)));
504 return SoftenFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)));
508 return SoftenFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)));
512 bool IsStrict =
N->isStrictFPOpcode();
513 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
514 unsigned Offset = IsStrict ? 1 : 0;
516 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
517 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
519 TargetLowering::MakeLibCallOptions CallOptions;
520 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
521 N->getOperand(1 +
Offset).getValueType(),
522 N->getOperand(2 +
Offset).getValueType() };
524 std::pair<SDValue, SDValue> Tmp =
525 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)), NVT,
Ops,
526 CallOptions, SDLoc(
N), Chain);
528 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
538 RTLIB::MUL_PPCF128));
542 return SoftenFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)));
546 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
551 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
552 DAG.getConstant(SignMask, dl, NVT));
556 bool IsStrict =
N->isStrictFPOpcode();
557 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
566 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
567 N->getValueType(0) != MVT::f32) {
570 { MVT::f32, MVT::Other }, { Chain,
Op });
571 Chain =
Op.getValue(1);
577 if (
Op.getValueType() == MVT::bf16) {
579 return SoftenFloatRes_BF16_TO_FP(
N);
583 if (LC == RTLIB::UNKNOWN_LIBCALL) {
584 DAG.getContext()->emitError(
"do not know how to soften fp_extend");
586 ReplaceValueWith(
SDValue(
N, 1), Chain);
587 return DAG.getPOISON(NVT);
589 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
590 if (LCImpl == RTLIB::Unsupported)
591 return SoftenFloatRes_NoLibcall(
N, NVT);
592 TargetLowering::MakeLibCallOptions CallOptions;
593 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
595 std::pair<SDValue, SDValue> Tmp =
596 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
598 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
605 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
607 TargetLowering::MakeLibCallOptions CallOptions;
608 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
610 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
611 CallOptions, SDLoc(
N)).first;
612 if (
N->getValueType(0) == MVT::f32)
615 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
617 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
618 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
624 assert(
N->getValueType(0) == MVT::f32 &&
625 "Can only soften BF16_TO_FP with f32 result");
626 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
632 DAG.getShiftAmountConstant(16, NVT,
DL));
637 bool IsStrict =
N->isStrictFPOpcode();
638 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
642 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
643 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
644 if (LCImpl == RTLIB::Unsupported)
645 return SoftenFloatRes_NoLibcall(
N, NVT);
646 TargetLowering::MakeLibCallOptions CallOptions;
647 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
649 std::pair<SDValue, SDValue> Tmp =
650 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
652 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
657 return SoftenFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)));
661 bool IsStrict =
N->isStrictFPOpcode();
662 unsigned Offset = IsStrict ? 1 : 0;
665 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
667 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(
N->getValueType(0))
669 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
670 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
671 if (LCImpl == RTLIB::Unsupported) {
674 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
676 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
677 return DAG.getPOISON(NVT);
680 if (DAG.getLibInfo().getIntSize() !=
681 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
684 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
686 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
687 return DAG.getPOISON(NVT);
693 TargetLowering::MakeLibCallOptions CallOptions;
694 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
695 N->getOperand(1 +
Offset).getValueType() };
697 std::pair<SDValue, SDValue> Tmp =
698 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
700 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
705 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
706 EVT VT0 =
N->getValueType(0);
707 EVT VT1 =
N->getValueType(1);
708 RTLIB::Libcall LC = RTLIB::getFREXP(VT0);
709 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
710 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
713 if (LCImpl == RTLIB::Unsupported) {
714 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
715 N->getOperationName(&DAG));
716 SDValue PoisonExp = DAG.getPOISON(VT1);
717 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
718 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
725 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
726 SDValue PoisonExp = DAG.getPOISON(VT1);
727 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
728 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
731 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
734 TargetLowering::MakeLibCallOptions CallOptions;
735 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
742 .setOpsTypeOverrides(CallOpsTypeOverrides);
744 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LCImpl, NVT0,
Ops, CallOptions,
750 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
752 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
756bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
757 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
758 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
759 EVT VT =
N->getValueType(0);
761 assert(VT ==
N->getValueType(1) &&
762 "expected both return values to have the same type");
764 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
765 if (LCImpl == RTLIB::Unsupported)
768 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
775 std::array<SDValue, 2> StackSlots;
778 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
779 if (ResNum == CallRetResNo)
781 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
782 Ops.push_back(StackSlot);
784 StackSlots[ResNum] = StackSlot;
788 TargetLowering::MakeLibCallOptions CallOptions;
792 .setOpsTypeOverrides(CallOpsTypeOverrides);
794 auto [ReturnVal, Chain] =
795 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
798 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
802 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
805 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
806 if (CallRetResNo == ResNum) {
807 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
810 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
817 EVT VT =
N->getValueType(0);
818 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(VT)))
822 RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
823 RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
826 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
827 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
828 DAG.getContext()->emitError(
"do not know how to soften fsincos");
830 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
831 SoftSin = SoftCos = DAG.getPOISON(NVT);
833 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
834 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
837 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
838 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
843 EVT VT =
N->getValueType(0);
844 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(VT),
848 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
849 DAG.getContext()->emitError(
"do not know how to soften fmodf");
857 return SoftenFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)));
861 return SoftenFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)));
865 return SoftenFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)));
869 return SoftenFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)));
873 return SoftenFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)));
877 return SoftenFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)));
881 return SoftenFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)));
890 RTLIB::SUB_PPCF128));
894 return SoftenFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)));
898 return SoftenFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)));
902 return SoftenFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)));
907 EVT VT =
N->getValueType(0);
908 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
912 L->getMemOperand()->getFlags() &
919 NewL = DAG.getLoad(
L->getAddressingMode(),
ISD::EXTLOAD, NVT, dl,
920 L->getChain(),
L->getBasePtr(),
L->getOffset(),
921 L->getPointerInfo(), MemVT,
L->getBaseAlign(), MMOFlags,
931 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
932 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
933 MMOFlags,
L->getAAInfo());
938 return BitConvertToInteger(ExtendNode);
943 EVT VT =
N->getValueType(0);
944 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
950 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
964 return DAG.getSelect(SDLoc(
N),
965 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
972 LHS.getValueType(),
N->getOperand(0),
973 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
977 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
978 N->getValueType(0)));
984 EVT VT =
N->getValueType(0);
985 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
989 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
990 N->getConstantOperandVal(3));
1000 bool IsStrict =
N->isStrictFPOpcode();
1003 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1004 EVT RVT =
N->getValueType(0);
1011 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1012 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1013 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1019 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1021 EVT NRVT = TLI.getTypeToTransformTo(*DAG.getContext(), RVT);
1022 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1023 if (LCImpl == RTLIB::Unsupported)
1024 return SoftenFloatRes_NoLibcall(
N, NRVT);
1029 NVT,
N->getOperand(IsStrict ? 1 : 0));
1030 TargetLowering::MakeLibCallOptions CallOptions;
1033 std::pair<SDValue, SDValue> Tmp =
1034 TLI.makeLibCall(DAG, LCImpl, NRVT,
Op, CallOptions, dl, Chain);
1037 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1043 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1047SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1048 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1056bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1057 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1060 switch (
N->getOpcode()) {
1063 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1064 N->dump(&DAG);
dbgs() <<
"\n";
1069 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1082 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1084 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1088 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1090 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1094 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1095 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1097 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1101 Res = SoftenFloatOp_FAKE_USE(
N);
1104 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1107 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1112 if (!Res.
getNode())
return false;
1120 "Invalid operand softening");
1122 ReplaceValueWith(
SDValue(
N, 0), Res);
1127 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1129 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1141 bool IsStrict =
N->isStrictFPOpcode();
1142 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1143 EVT SVT =
Op.getValueType();
1144 EVT RVT =
N->getValueType(0);
1148 FloatRVT = MVT::f16;
1151 FloatRVT = MVT::bf16;
1154 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1157 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1158 if (LCImpl == RTLIB::Unsupported) {
1159 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1160 N->getOperationName(&DAG));
1163 ReplaceValueWith(
SDValue(
N, 1), Chain);
1169 Op = GetSoftenedFloat(
Op);
1170 TargetLowering::MakeLibCallOptions CallOptions;
1172 std::pair<SDValue, SDValue> Tmp =
1173 TLI.makeLibCall(DAG, LCImpl, RVT,
Op, CallOptions, SDLoc(
N), Chain);
1175 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1176 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1187 NewLHS = GetSoftenedFloat(NewLHS);
1188 NewRHS = GetSoftenedFloat(NewRHS);
1189 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1190 N->getOperand(2),
N->getOperand(3));
1194 if (!NewRHS.getNode()) {
1195 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1200 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1201 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1211 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1212 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1213 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1217 if (Promoted.
bitsGE(RetVT))
1225 bool IsStrict =
N->isStrictFPOpcode();
1229 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1230 EVT SVT =
Op.getValueType();
1231 EVT RVT =
N->getValueType(0);
1241 "Unsupported FP_TO_XINT!");
1244 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1245 if (LCImpl == RTLIB::Unsupported) {
1246 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1247 N->getOperationName(&DAG));
1250 ReplaceValueWith(
SDValue(
N, 1), Chain);
1257 Op = GetSoftenedFloat(
Op);
1258 TargetLowering::MakeLibCallOptions CallOptions;
1260 std::pair<SDValue, SDValue> Tmp =
1261 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
1269 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1270 ReplaceValueWith(
SDValue(
N, 0), Res);
1274SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1275 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1284 NewLHS = GetSoftenedFloat(NewLHS);
1285 NewRHS = GetSoftenedFloat(NewRHS);
1286 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1287 N->getOperand(0),
N->getOperand(1));
1291 if (!NewRHS.getNode()) {
1292 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1297 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1298 N->getOperand(2),
N->getOperand(3),
1299 DAG.getCondCode(CCCode)),
1304 bool IsStrict =
N->isStrictFPOpcode();
1312 SDValue NewLHS = GetSoftenedFloat(Op0);
1313 SDValue NewRHS = GetSoftenedFloat(Op1);
1314 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1321 NewRHS, DAG.getCondCode(CCCode));
1323 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1324 DAG.getCondCode(CCCode)), 0);
1329 "Unexpected setcc expansion!");
1332 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1333 ReplaceValueWith(
SDValue(
N, 1), Chain);
1339SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1341 assert(OpNo == 1 &&
"Can only soften the stored value!");
1346 if (
ST->isTruncatingStore())
1348 Val = BitConvertToInteger(
1350 DAG.getIntPtrConstant(0, dl,
true)));
1352 Val = GetSoftenedFloat(Val);
1358 return DAG.getTruncStore(
ST->getChain(), dl, Val,
ST->getBasePtr(), MemVT,
1359 ST->getMemOperand());
1362SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1363 assert(OpNo == 1 &&
"Can only soften the stored value!");
1369 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1371 SDValue NewVal = GetSoftenedFloat(Val);
1373 ST->getBasePtr(),
ST->getMemOperand());
1378 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1381 EVT LVT =
LHS.getValueType();
1383 EVT RVT =
RHS.getValueType();
1389 int SizeDiff = RSize - LSize;
1393 DAG.getConstant(SizeDiff, dl,
1394 TLI.getShiftAmountTy(
RHS.getValueType(),
1395 DAG.getDataLayout())));
1397 }
else if (SizeDiff < 0) {
1401 DAG.getConstant(-SizeDiff, dl,
1402 TLI.getShiftAmountTy(
RHS.getValueType(),
1403 DAG.getDataLayout())));
1406 RHS = DAG.getBitcast(LVT,
RHS);
1410SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1411 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1412 bool IsStrict =
N->isStrictFPOpcode();
1413 unsigned Offset = IsStrict ? 1 : 0;
1416 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1417 if (LCImpl == RTLIB::Unsupported) {
1418 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1419 N->getOperationName(&DAG));
1422 ReplaceValueWith(
SDValue(
N, 1), Chain);
1428 TargetLowering::MakeLibCallOptions CallOptions;
1429 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1431 std::pair<SDValue, SDValue> Tmp =
1432 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
1434 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1435 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1443 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1449 RTLIB::LROUND_PPCF128));
1453 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1458 RTLIB::LLROUND_F128,
1459 RTLIB::LLROUND_PPCF128));
1463 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1469 RTLIB::LRINT_PPCF128));
1473 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1479 RTLIB::LLRINT_PPCF128));
1483 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1484 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1485 N->getOperand(0), Op1);
1488SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1491 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1492 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1495SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1498 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1499 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1510void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1516 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1519 switch (
N->getOpcode()) {
1522 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1523 N->dump(&DAG);
dbgs() <<
"\n";
1638 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1640 "Do not know how to expand this float constant!");
1644 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1645 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1648void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1650 bool IsStrict =
N->isStrictFPOpcode();
1651 unsigned Offset = IsStrict ? 1 : 0;
1654 TargetLowering::MakeLibCallOptions CallOptions;
1655 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1656 Op, CallOptions, SDLoc(
N),
1659 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1660 GetPairElements(Tmp.first,
Lo,
Hi);
1663void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1665 bool IsStrict =
N->isStrictFPOpcode();
1666 unsigned Offset = IsStrict ? 1 : 0;
1669 TargetLowering::MakeLibCallOptions CallOptions;
1670 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1671 Ops, CallOptions, SDLoc(
N),
1674 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1675 GetPairElements(Tmp.first,
Lo,
Hi);
1678void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1679 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(
N->getValueType(0)),
1683void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1684 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(
N->getValueType(0)));
1687void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1688 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1689 RTLIB::getSINCOSPI(
N->getValueType(0)));
1692void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1693 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1694 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1696 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1699 GetPairElements(Res,
Lo,
Hi);
1706 assert(
N->getValueType(0) == MVT::ppcf128 &&
1707 "Logic only correct for ppcf128!");
1710 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1713 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1720 ExpandFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)),
Lo,
Hi);
1725 ExpandFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)),
Lo,
Hi);
1730 ExpandFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1735 ExpandFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1741 RTLIB::ADD_F32, RTLIB::ADD_F64,
1742 RTLIB::ADD_F80, RTLIB::ADD_F128,
1743 RTLIB::ADD_PPCF128),
Lo,
Hi);
1748 ExpandFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)),
Lo,
Hi);
1753 ExpandFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)),
Lo,
Hi);
1758 ExpandFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)),
Lo,
Hi);
1763 ExpandFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)),
Lo,
Hi);
1768 ExpandFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)),
Lo,
Hi);
1771void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1773 ExpandFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)),
Lo,
Hi);
1776void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1778 ExpandFloatRes_Binary(
N, RTLIB::getCOPYSIGN(
N->getValueType(0)),
Lo,
Hi);
1781void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1783 ExpandFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)),
Lo,
Hi);
1788 ExpandFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)),
Lo,
Hi);
1798 RTLIB::DIV_PPCF128),
Lo,
Hi);
1801void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1803 ExpandFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)),
Lo,
Hi);
1806void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1808 ExpandFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)),
Lo,
Hi);
1813 ExpandFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)),
Lo,
Hi);
1816void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1818 ExpandFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)),
Lo,
Hi);
1821void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1823 ExpandFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)),
Lo,
Hi);
1826void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1828 ExpandFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)),
Lo,
Hi);
1831void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1833 ExpandFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)),
Lo,
Hi);
1838 bool IsStrict =
N->isStrictFPOpcode();
1839 unsigned Offset = IsStrict ? 1 : 0;
1843 TargetLowering::MakeLibCallOptions CallOptions;
1844 std::pair<SDValue, SDValue> Tmp =
1845 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)),
1846 N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1848 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1849 GetPairElements(Tmp.first,
Lo,
Hi);
1859 RTLIB::MUL_PPCF128),
Lo,
Hi);
1862void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1864 ExpandFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)),
Lo,
Hi);
1870 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1875void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1879 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1884 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1886 bool IsStrict =
N->isStrictFPOpcode();
1891 if (NVT ==
N->getOperand(1).getValueType()) {
1892 Hi =
N->getOperand(1);
1897 {
N->getOperand(0),
N->getOperand(1) });
1907 ReplaceValueWith(
SDValue(
N, 1), Chain);
1910void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1912 ExpandFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)),
Lo,
Hi);
1915void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1917 ExpandFloatRes_Binary(
N, RTLIB::getPOWI(
N->getValueType(0)),
Lo,
Hi);
1922 ExpandFloatRes_Binary(
N, RTLIB::getLDEXP(
N->getValueType(0)),
Lo,
Hi);
1925void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1927 assert(
N->getValueType(0) == MVT::ppcf128 &&
1928 "Logic only correct for ppcf128!");
1931 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1936void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1938 ExpandFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)),
Lo,
Hi);
1941void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1943 ExpandFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)),
Lo,
Hi);
1946void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1948 ExpandFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)),
Lo,
Hi);
1951void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1953 ExpandFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)),
Lo,
Hi);
1956void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1958 ExpandFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)),
Lo,
Hi);
1963 ExpandFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)),
Lo,
Hi);
1966void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1968 ExpandFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)),
Lo,
Hi);
1978 RTLIB::SUB_PPCF128),
Lo,
Hi);
1983 ExpandFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)),
Lo,
Hi);
1988 ExpandFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)),
Lo,
Hi);
1991void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
1993 ExpandFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)),
Lo,
Hi);
1999 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2009 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2011 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2013 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2014 LD->getMemoryVT(),
LD->getMemOperand());
2024 ReplaceValueWith(
SDValue(LD, 1), Chain);
2029 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2030 EVT VT =
N->getValueType(0);
2031 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2032 bool Strict =
N->isStrictFPOpcode();
2034 EVT SrcVT = Src.getValueType();
2042 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2047 if (SrcVT.
bitsLE(MVT::i32)) {
2051 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2052 {Chain, Src}, Flags);
2055 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2057 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2058 if (SrcVT.
bitsLE(MVT::i64)) {
2061 LC = RTLIB::SINTTOFP_I64_PPCF128;
2062 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2064 LC = RTLIB::SINTTOFP_I128_PPCF128;
2066 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2068 TargetLowering::MakeLibCallOptions CallOptions;
2070 std::pair<SDValue, SDValue> Tmp =
2071 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2074 GetPairElements(Tmp.first,
Lo,
Hi);
2080 ReplaceValueWith(
SDValue(
N, 1), Chain);
2090 SrcVT = Src.getValueType();
2093 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2094 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2095 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2096 ArrayRef<uint64_t> Parts;
2113 SDValue NewLo = DAG.getConstantFP(
2117 {Chain, Hi, NewLo}, Flags);
2119 ReplaceValueWith(
SDValue(
N, 1), Chain);
2122 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2124 GetPairElements(
Lo,
Lo,
Hi);
2136bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2141 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2144 switch (
N->getOpcode()) {
2147 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2148 N->dump(&DAG);
dbgs() <<
"\n";
2156 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2164 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2166 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2167 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2171 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2177 if (!Res.
getNode())
return false;
2185 "Invalid operand expansion");
2187 ReplaceValueWith(
SDValue(
N, 0), Res);
2193void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2198 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2199 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2200 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2209 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2210 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2213 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2214 RHSLo, CCCode, OutputChain, IsSignaling);
2218 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2221 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2222 RHSHi, CCCode, OutputChain, IsSignaling);
2227 Chain = OutputChain;
2234 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2239 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2244 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2245 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2246 N->getOperand(4)), 0);
2250 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2251 "Logic only correct for ppcf128!");
2253 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2257 N->getValueType(0),
N->getOperand(0),
Hi);
2261 bool IsStrict =
N->isStrictFPOpcode();
2262 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2263 "Logic only correct for ppcf128!");
2265 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2270 N->getValueType(0),
Hi,
N->getOperand(1));
2274 if (
Hi.getValueType() ==
N->getValueType(0)) {
2276 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2282 {
N->getValueType(0), MVT::Other},
2283 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2290 EVT RVT =
N->getValueType(0);
2293 bool IsStrict =
N->isStrictFPOpcode();
2296 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2302 "Unsupported FP_TO_XINT!");
2303 TargetLowering::MakeLibCallOptions CallOptions;
2304 std::pair<SDValue, SDValue> Tmp =
2305 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2309 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2310 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2318 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2323 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2328 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2329 N->getOperand(2),
N->getOperand(3),
2330 DAG.getCondCode(CCCode)), 0);
2334 bool IsStrict =
N->isStrictFPOpcode();
2340 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2346 "Unexpected setcc expansion!");
2348 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2349 ReplaceValueWith(
SDValue(
N, 1), Chain);
2355SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2357 return ExpandOp_NormalStore(
N, OpNo);
2360 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2366 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2367 ST->getValue().getValueType());
2369 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2373 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2375 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2376 ST->getMemoryVT(),
ST->getMemOperand());
2380 RTLIB::Libcall LC) {
2381 EVT RVT =
N->getValueType(0);
2382 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2383 if (LCImpl == RTLIB::Unsupported) {
2384 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
2385 N->getOperationName(&DAG));
2386 return DAG.getPOISON(RVT);
2389 TargetLowering::MakeLibCallOptions CallOptions;
2391 .makeLibCall(DAG, LCImpl, RVT,
N->getOperand(0), CallOptions, SDLoc(
N))
2397 return ExpandFloatOp_XRINT_XROUND(
2398 N,
GetFPLibCall(RetVT, RTLIB::LROUND_F32, RTLIB::LROUND_F64,
2399 RTLIB::LROUND_F80, RTLIB::LROUND_F128,
2400 RTLIB::LROUND_PPCF128));
2404 EVT RetVT =
N->getOperand(0).getValueType();
2405 return ExpandFloatOp_XRINT_XROUND(
2406 N,
GetFPLibCall(RetVT, RTLIB::LLROUND_F32, RTLIB::LLROUND_F64,
2407 RTLIB::LLROUND_F80, RTLIB::LLROUND_F128,
2408 RTLIB::LLROUND_PPCF128));
2412 EVT RetVT =
N->getOperand(0).getValueType();
2413 return ExpandFloatOp_XRINT_XROUND(
2415 GetFPLibCall(RetVT, RTLIB::LRINT_F32, RTLIB::LRINT_F64, RTLIB::LRINT_F80,
2416 RTLIB::LRINT_F128, RTLIB::LRINT_PPCF128));
2420 EVT RetVT =
N->getOperand(0).getValueType();
2421 return ExpandFloatOp_XRINT_XROUND(
2422 N,
GetFPLibCall(RetVT, RTLIB::LLRINT_F32, RTLIB::LLRINT_F64,
2423 RTLIB::LLRINT_F80, RTLIB::LLRINT_F128,
2424 RTLIB::LLRINT_PPCF128));
2433 if (OpVT == MVT::f16)
2435 if (RetVT == MVT::f16)
2437 if (OpVT == MVT::bf16)
2439 if (RetVT == MVT::bf16)
2445 if (OpVT == MVT::f16)
2447 if (RetVT == MVT::f16)
2449 if (OpVT == MVT::bf16)
2451 if (RetVT == MVT::bf16)
2465 DAG.getVTList(CastVT, MVT::Other),
2466 { AM->getChain(), AM->getBasePtr(), CastVal },
2482void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2483 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2488 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2493 switch (
N->getOpcode()) {
2496 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2497 N->dump(&DAG);
dbgs() <<
"\n";
2503 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2507 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2540 R = SoftPromoteHalfRes_FABS(
N);
2543 R = SoftPromoteHalfRes_FNEG(
N);
2546 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2562 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2565 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2575 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2578 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2580 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2589 R = SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
N);
2592 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2602 R = SoftPromoteHalfRes_VECREDUCE(
N);
2606 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2611 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2614SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2616 BitConvertToInteger(
N->getOperand(0)));
2620 return BitConvertToInteger(
N->getOperand(0));
2623SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2631SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2632 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2638SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2639 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2640 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2643 EVT LVT =
LHS.getValueType();
2644 EVT RVT =
RHS.getValueType();
2651 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2652 DAG.getConstant(RSize - 1, dl,
2653 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2661 DAG.getConstant(SizeDiff, dl,
2663 DAG.getDataLayout())));
2665 }
else if (SizeDiff < 0) {
2669 DAG.getConstant(-SizeDiff, dl,
2671 DAG.getDataLayout())));
2676 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2677 DAG.getConstant(LSize - 1, dl,
2678 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2679 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2683 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2688 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2689 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2690 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2691 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2692 SDNodeFlags
Flags =
N->getFlags();
2697 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2698 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2699 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2702 if (OVT == MVT::f16) {
2711 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2722 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2727 EVT OVT =
N->getValueType(0);
2728 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2729 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2743 EVT OVT =
N->getValueType(0);
2744 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2745 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2752 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2760SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2761 EVT OVT =
N->getValueType(0);
2762 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2763 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2772 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2774 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2775 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2781SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2782 EVT RVT =
N->getValueType(0);
2783 bool IsStrict =
N->isStrictFPOpcode();
2784 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2785 EVT SVT =
Op.getValueType();
2791 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2794 Op = GetSoftenedFloat(
Op);
2795 TargetLowering::MakeLibCallOptions CallOptions;
2797 std::pair<SDValue, SDValue> Tmp =
2798 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2800 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2801 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2806 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2821 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
2822 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
2823 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
2824 L->getMemOperand()->getFlags(),
L->getAAInfo());
2831SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
2846 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2847 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2848 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1, Op2,
2852SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
2853 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2854 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
2856 N->getOperand(0),
N->getOperand(1), Op2, Op3,
2860SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
2861 EVT OVT =
N->getValueType(0);
2862 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2865 if (
N->isStrictFPOpcode()) {
2866 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
2867 {N->getOperand(0), N->getOperand(1)});
2869 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
2870 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
2881DAGTypeLegalizer::SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
2882 EVT OVT =
N->getValueType(0);
2883 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2887 N->getOperand(0),
N->getOperand(1));
2894 return DAG.getUNDEF(MVT::i16);
2898 EVT OVT =
N->getValueType(0);
2899 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2900 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2913 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2917 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
2918 DAG.getConstant(0x7fff, dl, MVT::i16));
2922 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2926 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
2927 DAG.getConstant(0x8000, dl, MVT::i16));
2930SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
2931 return GetSoftPromotedHalf(
N->getOperand(0));
2935 EVT OVT =
N->getValueType(0);
2936 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2937 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2938 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2943 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2944 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2952SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
2954 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
2958SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
2960 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
2968bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
2969 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
2973 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2983 switch (
N->getOpcode()) {
2986 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
2987 N->dump(&DAG);
dbgs() <<
"\n";
2992 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
2994 Res = SoftPromoteHalfOp_BUILD_VECTOR(
N);
2997 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3000 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3014 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3018 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3020 Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
N);
3024 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3026 Res = SoftPromoteHalfOp_BR_CC(
N);
3028 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3029 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3031 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3034 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3037 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3047 "Invalid operand expansion");
3049 ReplaceValueWith(
SDValue(
N, 0), Res);
3054 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3056 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3059SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BUILD_VECTOR(
SDNode *
N) {
3061 EVT VT =
N->getValueType(0);
3064 for (
unsigned I = 0,
E =
N->getNumOperands();
I !=
E; ++
I)
3065 Ops[
I] = GetSoftPromotedHalf(
N->getOperand(
I));
3068 SDValue Res = DAG.getBuildVector(IVT, dl,
Ops);
3069 return DAG.getBitcast(VT, Res);
3072SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3073 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3074 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3075 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3081 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3086 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3088 Op1 = GetSoftPromotedHalf(Op1);
3091 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3095SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3096 EVT RVT =
N->getValueType(0);
3097 bool IsStrict =
N->isStrictFPOpcode();
3098 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3099 EVT SVT =
Op.getValueType();
3100 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3104 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3106 ReplaceValueWith(
SDValue(
N, 0), Res);
3113SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3114 EVT RVT =
N->getValueType(0);
3115 bool IsStrict =
N->isStrictFPOpcode();
3116 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3117 EVT SVT =
Op.getValueType();
3120 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3121 Op = GetSoftPromotedHalf(
Op);
3125 {
N->getOperand(0),
Op});
3126 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3127 {Op.getValue(1), Op});
3128 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3134 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3137SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3138 EVT RVT =
N->getValueType(0);
3140 EVT SVT =
Op.getValueType();
3143 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3145 Op = GetSoftPromotedHalf(
Op);
3149 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3156SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
3157 EVT RVT =
N->getValueType(0);
3159 EVT SVT =
Op.getValueType();
3162 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3163 Op = GetSoftPromotedHalf(
Op);
3167 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
3178 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3181 Op0 = GetSoftPromotedHalf(Op0);
3182 Op1 = GetSoftPromotedHalf(Op1);
3186 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3187 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3190 return DAG.getNode(
ISD::BR_CC, dl, MVT::Other,
N->getOperand(0),
3191 N->getOperand(1), Op0, Op1,
N->getOperand(4));
3196 assert(OpNo == 0 &&
"Can only soften the comparison values");
3202 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3204 Op0 = GetSoftPromotedHalf(Op0);
3205 Op1 = GetSoftPromotedHalf(Op1);
3209 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3210 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3213 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3223 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3225 Op0 = GetSoftPromotedHalf(Op0);
3226 Op1 = GetSoftPromotedHalf(Op1);
3230 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3231 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3233 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3236SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3237 assert(OpNo == 1 &&
"Can only soften the stored value!");
3242 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3243 SDValue Promoted = GetSoftPromotedHalf(Val);
3244 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3245 ST->getMemOperand());
3248SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3250 assert(OpNo == 1 &&
"Can only soften the stored value!");
3255 SDValue Promoted = GetSoftPromotedHalf(Val);
3257 ST->getChain(), Promoted,
ST->getBasePtr(),
3258 ST->getMemOperand());
3261SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3265 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3267 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3269 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3280 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3282 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3284 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 GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isSigned(unsigned 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, bool LookThroughCmp=false)
Returns the "element type" of the given value/instruction V.
static const fltSemantics & PPCDoubleDouble()
APInt bitcastToAPInt() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
const SDValue & getVal() const
const APFloat & getValueAPF() const
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ PATCHPOINT
The llvm.experimental.patchpoint.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ STACKMAP
The llvm.experimental.stackmap intrinsic.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* 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 getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* 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.
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Mul
Product of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
bool isByteSized() const
Return true if the bit size is a multiple of 8.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
bool bitsGE(EVT VT) const
Return true if this has no less bits than VT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
LLVM_ABI const fltSemantics & getFltSemantics() const
Returns an APFloat semantics tag appropriate for the value type.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
void setNoFPExcept(bool b)
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT)
MakeLibCallOptions & setIsSigned(bool Value=true)