27#define DEBUG_TYPE "legalize-types"
33 RTLIB::Libcall Call_F32,
34 RTLIB::Libcall Call_F64,
35 RTLIB::Libcall Call_F80,
36 RTLIB::Libcall Call_F128,
37 RTLIB::Libcall Call_PPCF128) {
39 VT == MVT::f32 ? Call_F32 :
40 VT == MVT::f64 ? Call_F64 :
41 VT == MVT::f80 ? Call_F80 :
42 VT == MVT::f128 ? Call_F128 :
43 VT == MVT::ppcf128 ? Call_PPCF128 :
44 RTLIB::UNKNOWN_LIBCALL;
51void DAGTypeLegalizer::SoftenFloatResult(
SDNode *
N,
unsigned ResNo) {
52 LLVM_DEBUG(
dbgs() <<
"Soften float result " << ResNo <<
": ";
N->dump(&DAG));
55 switch (
N->getOpcode()) {
59 dbgs() <<
"SoftenFloatResult #" << ResNo <<
": ";
60 N->dump(&DAG);
dbgs() <<
"\n";
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
74 R = SoftenFloatRes_FCANONICALIZE(
N);
break;
117 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
188 SetSoftenedFloat(
SDValue(
N, ResNo), R);
195 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
196 N->getOperationName(&DAG));
197 if (
N->isStrictFPOpcode())
198 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
199 return DAG.getPOISON(NVT);
202SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
204 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
205 unsigned Offset = IsStrict ? 1 : 0;
207 "Unexpected number of operands!");
210 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
211 if (LCImpl == RTLIB::Unsupported)
212 return SoftenFloatRes_NoLibcall(
N, NVT);
213 TargetLowering::MakeLibCallOptions CallOptions;
214 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
216 std::pair<SDValue, SDValue> Tmp =
217 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
219 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
223SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
224 bool IsStrict =
N->isStrictFPOpcode();
225 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
226 unsigned Offset = IsStrict ? 1 : 0;
228 "Unexpected number of operands!");
230 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
232 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
233 if (LCImpl == RTLIB::Unsupported)
234 return SoftenFloatRes_NoLibcall(
N, NVT);
235 TargetLowering::MakeLibCallOptions CallOptions;
236 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
237 N->getOperand(1 +
Offset).getValueType() };
239 std::pair<SDValue, SDValue> Tmp =
240 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
242 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
247 return BitConvertToInteger(
N->getOperand(0));
251 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
253 GetSoftenedFloat(
N->getOperand(0)));
257 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
259 GetSoftenedFloat(
N->getOperand(0)));
265 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
266 return BitConvertToInteger(
Op);
272 TLI.getTypeToTransformTo(*DAG.getContext(),
274 BitConvertToInteger(
N->getOperand(0)),
275 BitConvertToInteger(
N->getOperand(1)));
287 if (DAG.getDataLayout().isBigEndian() &&
291 APInt Val(128, words);
292 return DAG.getConstant(Val, SDLoc(CN),
293 TLI.getTypeToTransformTo(*DAG.getContext(),
297 TLI.getTypeToTransformTo(*DAG.getContext(),
302SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
304 assert(Src.getValueType() == MVT::ppcf128 &&
305 "In floats only ppcf128 can be extracted by element!");
307 N->getValueType(0).changeTypeToInteger(),
308 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
311SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
312 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
315 NewOp,
N->getOperand(1));
319 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
326 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
327 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
330SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
344 SDValue One = DAG.getConstantFP(1.0, dl, VT);
345 SDValue Chain = DAG.getEntryNode();
348 SDNodeFlags CanonicalizeFlags =
N->
getFlags();
351 {Chain, Operand, One}, CanonicalizeFlags);
352 return BitConvertToInteger(
Mul);
356 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
357 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
358 return SoftenFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)));
362 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
363 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
364 return SoftenFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)));
368 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)));
372 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)));
376 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM(
N->getValueType(0)));
380 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM(
N->getValueType(0)));
389 RTLIB::ADD_PPCF128));
393 return SoftenFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)));
397 return SoftenFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)));
401 return SoftenFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)));
405 return SoftenFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)));
409 return SoftenFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)));
413 return SoftenFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)));
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);
465 return SoftenFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)));
469 return SoftenFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)));
478 RTLIB::DIV_PPCF128));
482 return SoftenFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)));
486 return SoftenFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)));
490 return SoftenFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)));
494 return SoftenFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)));
498 return SoftenFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)));
502 return SoftenFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)));
506 return SoftenFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)));
510 bool IsStrict =
N->isStrictFPOpcode();
511 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
512 unsigned Offset = IsStrict ? 1 : 0;
514 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
515 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
517 TargetLowering::MakeLibCallOptions CallOptions;
518 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
519 N->getOperand(1 +
Offset).getValueType(),
520 N->getOperand(2 +
Offset).getValueType() };
522 std::pair<SDValue, SDValue> Tmp =
523 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)), NVT,
Ops,
524 CallOptions, SDLoc(
N), Chain);
526 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
536 RTLIB::MUL_PPCF128));
540 return SoftenFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)));
544 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
549 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
550 DAG.getConstant(SignMask, dl, NVT));
554 bool IsStrict =
N->isStrictFPOpcode();
555 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
564 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
565 N->getValueType(0) != MVT::f32) {
568 { MVT::f32, MVT::Other }, { Chain,
Op });
569 Chain =
Op.getValue(1);
575 if (
Op.getValueType() == MVT::bf16) {
577 return SoftenFloatRes_BF16_TO_FP(
N);
581 if (LC == RTLIB::UNKNOWN_LIBCALL) {
582 DAG.getContext()->emitError(
"do not know how to soften fp_extend");
584 ReplaceValueWith(
SDValue(
N, 1), Chain);
585 return DAG.getPOISON(NVT);
587 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
588 if (LCImpl == RTLIB::Unsupported)
589 return SoftenFloatRes_NoLibcall(
N, NVT);
590 TargetLowering::MakeLibCallOptions CallOptions;
591 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
593 std::pair<SDValue, SDValue> Tmp =
594 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
596 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
603 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
605 TargetLowering::MakeLibCallOptions CallOptions;
606 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
608 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
609 CallOptions, SDLoc(
N)).first;
610 if (
N->getValueType(0) == MVT::f32)
613 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
615 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
616 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
622 assert(
N->getValueType(0) == MVT::f32 &&
623 "Can only soften BF16_TO_FP with f32 result");
624 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
630 DAG.getShiftAmountConstant(16, NVT,
DL));
635 bool IsStrict =
N->isStrictFPOpcode();
636 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
640 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
641 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
642 if (LCImpl == RTLIB::Unsupported)
643 return SoftenFloatRes_NoLibcall(
N, NVT);
644 TargetLowering::MakeLibCallOptions CallOptions;
645 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
647 std::pair<SDValue, SDValue> Tmp =
648 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
650 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
655 return SoftenFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)));
659 bool IsStrict =
N->isStrictFPOpcode();
660 unsigned Offset = IsStrict ? 1 : 0;
663 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
665 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(
N->getValueType(0))
667 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
668 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
669 if (LCImpl == RTLIB::Unsupported) {
672 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
674 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
675 return DAG.getPOISON(NVT);
678 if (DAG.getLibInfo().getIntSize() !=
679 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
682 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
684 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
685 return DAG.getPOISON(NVT);
691 TargetLowering::MakeLibCallOptions CallOptions;
692 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
693 N->getOperand(1 +
Offset).getValueType() };
695 std::pair<SDValue, SDValue> Tmp =
696 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
698 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
703 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
704 EVT VT0 =
N->getValueType(0);
705 EVT VT1 =
N->getValueType(1);
706 RTLIB::Libcall LC = RTLIB::getFREXP(VT0);
707 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
708 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
711 if (LCImpl == RTLIB::Unsupported) {
712 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
713 N->getOperationName(&DAG));
714 SDValue PoisonExp = DAG.getPOISON(VT1);
715 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
716 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
723 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
724 SDValue PoisonExp = DAG.getPOISON(VT1);
725 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
726 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
729 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
732 TargetLowering::MakeLibCallOptions CallOptions;
733 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
740 .setOpsTypeOverrides(CallOpsTypeOverrides);
742 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LCImpl, NVT0,
Ops, CallOptions,
748 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
750 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
754bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
755 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
756 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
757 EVT VT =
N->getValueType(0);
759 assert(VT ==
N->getValueType(1) &&
760 "expected both return values to have the same type");
762 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
763 if (LCImpl == RTLIB::Unsupported)
766 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
773 std::array<SDValue, 2> StackSlots;
776 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
777 if (ResNum == CallRetResNo)
779 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
780 Ops.push_back(StackSlot);
782 StackSlots[ResNum] = StackSlot;
786 TargetLowering::MakeLibCallOptions CallOptions;
790 .setOpsTypeOverrides(CallOpsTypeOverrides);
792 auto [ReturnVal, Chain] =
793 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
796 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
800 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
803 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
804 if (CallRetResNo == ResNum) {
805 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
808 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
815 EVT VT =
N->getValueType(0);
816 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(VT)))
820 RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
821 RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
824 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
825 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
826 DAG.getContext()->emitError(
"do not know how to soften fsincos");
828 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
829 SoftSin = SoftCos = DAG.getPOISON(NVT);
831 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
832 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
835 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
836 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
841 EVT VT =
N->getValueType(0);
842 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(VT),
846 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
847 DAG.getContext()->emitError(
"do not know how to soften fmodf");
855 return SoftenFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)));
859 return SoftenFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)));
863 return SoftenFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)));
867 return SoftenFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)));
871 return SoftenFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)));
875 return SoftenFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)));
879 return SoftenFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)));
888 RTLIB::SUB_PPCF128));
892 return SoftenFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)));
896 return SoftenFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)));
900 return SoftenFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)));
905 EVT VT =
N->getValueType(0);
906 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
910 L->getMemOperand()->getFlags() &
914 NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
915 L->getChain(),
L->getBasePtr(),
L->getOffset(),
916 L->getPointerInfo(), NVT,
L->getBaseAlign(), MMOFlags,
926 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
927 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
928 MMOFlags,
L->getAAInfo());
933 return BitConvertToInteger(ExtendNode);
938 EVT VT =
N->getValueType(0);
939 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
945 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
959 return DAG.getSelect(SDLoc(
N),
960 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
967 LHS.getValueType(),
N->getOperand(0),
968 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
972 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
973 N->getValueType(0)));
979 EVT VT =
N->getValueType(0);
980 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
984 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
985 N->getConstantOperandVal(3));
995 bool IsStrict =
N->isStrictFPOpcode();
998 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
999 EVT RVT =
N->getValueType(0);
1006 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1007 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1008 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1014 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1016 EVT NRVT = TLI.getTypeToTransformTo(*DAG.getContext(), RVT);
1017 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1018 if (LCImpl == RTLIB::Unsupported)
1019 return SoftenFloatRes_NoLibcall(
N, NRVT);
1024 NVT,
N->getOperand(IsStrict ? 1 : 0));
1025 TargetLowering::MakeLibCallOptions CallOptions;
1028 std::pair<SDValue, SDValue> Tmp =
1029 TLI.makeLibCall(DAG, LCImpl, NRVT,
Op, CallOptions, dl, Chain);
1032 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1038 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1042SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1043 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1051bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1052 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1055 switch (
N->getOpcode()) {
1058 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1059 N->dump(&DAG);
dbgs() <<
"\n";
1064 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1077 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1079 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1083 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1085 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1089 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1090 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1092 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1096 Res = SoftenFloatOp_FAKE_USE(
N);
1099 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1102 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1107 if (!Res.
getNode())
return false;
1115 "Invalid operand softening");
1117 ReplaceValueWith(
SDValue(
N, 0), Res);
1122 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1124 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1136 bool IsStrict =
N->isStrictFPOpcode();
1137 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1138 EVT SVT =
Op.getValueType();
1139 EVT RVT =
N->getValueType(0);
1143 FloatRVT = MVT::f16;
1146 FloatRVT = MVT::bf16;
1149 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1152 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1153 if (LCImpl == RTLIB::Unsupported) {
1154 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1155 N->getOperationName(&DAG));
1158 ReplaceValueWith(
SDValue(
N, 1), Chain);
1164 Op = GetSoftenedFloat(
Op);
1165 TargetLowering::MakeLibCallOptions CallOptions;
1167 std::pair<SDValue, SDValue> Tmp =
1168 TLI.makeLibCall(DAG, LCImpl, RVT,
Op, CallOptions, SDLoc(
N), Chain);
1170 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1171 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1182 NewLHS = GetSoftenedFloat(NewLHS);
1183 NewRHS = GetSoftenedFloat(NewRHS);
1184 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1185 N->getOperand(2),
N->getOperand(3));
1189 if (!NewRHS.getNode()) {
1190 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1195 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1196 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1206 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1207 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1208 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1212 if (Promoted.
bitsGE(RetVT))
1220 bool IsStrict =
N->isStrictFPOpcode();
1224 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1225 EVT SVT =
Op.getValueType();
1226 EVT RVT =
N->getValueType(0);
1236 "Unsupported FP_TO_XINT!");
1239 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1240 if (LCImpl == RTLIB::Unsupported) {
1241 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1242 N->getOperationName(&DAG));
1245 ReplaceValueWith(
SDValue(
N, 1), Chain);
1252 Op = GetSoftenedFloat(
Op);
1253 TargetLowering::MakeLibCallOptions CallOptions;
1255 std::pair<SDValue, SDValue> Tmp =
1256 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
1264 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1265 ReplaceValueWith(
SDValue(
N, 0), Res);
1269SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1270 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1279 NewLHS = GetSoftenedFloat(NewLHS);
1280 NewRHS = GetSoftenedFloat(NewRHS);
1281 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1282 N->getOperand(0),
N->getOperand(1));
1286 if (!NewRHS.getNode()) {
1287 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1292 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1293 N->getOperand(2),
N->getOperand(3),
1294 DAG.getCondCode(CCCode)),
1299 bool IsStrict =
N->isStrictFPOpcode();
1307 SDValue NewLHS = GetSoftenedFloat(Op0);
1308 SDValue NewRHS = GetSoftenedFloat(Op1);
1309 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1316 NewRHS, DAG.getCondCode(CCCode));
1318 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1319 DAG.getCondCode(CCCode)), 0);
1324 "Unexpected setcc expansion!");
1327 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1328 ReplaceValueWith(
SDValue(
N, 1), Chain);
1334SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1336 assert(OpNo == 1 &&
"Can only soften the stored value!");
1341 if (
ST->isTruncatingStore())
1343 Val = BitConvertToInteger(
1345 DAG.getIntPtrConstant(0, dl,
true)));
1347 Val = GetSoftenedFloat(Val);
1349 return DAG.getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1350 ST->getMemOperand());
1353SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1354 assert(OpNo == 1 &&
"Can only soften the stored value!");
1360 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1362 SDValue NewVal = GetSoftenedFloat(Val);
1364 ST->getBasePtr(),
ST->getMemOperand());
1369 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1372 EVT LVT =
LHS.getValueType();
1374 EVT RVT =
RHS.getValueType();
1380 int SizeDiff = RSize - LSize;
1384 DAG.getConstant(SizeDiff, dl,
1385 TLI.getShiftAmountTy(
RHS.getValueType(),
1386 DAG.getDataLayout())));
1388 }
else if (SizeDiff < 0) {
1392 DAG.getConstant(-SizeDiff, dl,
1393 TLI.getShiftAmountTy(
RHS.getValueType(),
1394 DAG.getDataLayout())));
1397 RHS = DAG.getBitcast(LVT,
RHS);
1401SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1402 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1403 bool IsStrict =
N->isStrictFPOpcode();
1404 unsigned Offset = IsStrict ? 1 : 0;
1407 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1408 if (LCImpl == RTLIB::Unsupported) {
1409 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1410 N->getOperationName(&DAG));
1413 ReplaceValueWith(
SDValue(
N, 1), Chain);
1419 TargetLowering::MakeLibCallOptions CallOptions;
1420 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1422 std::pair<SDValue, SDValue> Tmp =
1423 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
1425 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1426 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1434 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1440 RTLIB::LROUND_PPCF128));
1444 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1449 RTLIB::LLROUND_F128,
1450 RTLIB::LLROUND_PPCF128));
1454 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1460 RTLIB::LRINT_PPCF128));
1464 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1470 RTLIB::LLRINT_PPCF128));
1474 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1475 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1476 N->getOperand(0), Op1);
1479SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1482 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1483 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1486SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1489 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1490 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1501void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1507 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1510 switch (
N->getOpcode()) {
1513 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1514 N->dump(&DAG);
dbgs() <<
"\n";
1629 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1631 "Do not know how to expand this float constant!");
1635 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1636 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1639void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1641 bool IsStrict =
N->isStrictFPOpcode();
1642 unsigned Offset = IsStrict ? 1 : 0;
1645 TargetLowering::MakeLibCallOptions CallOptions;
1646 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1647 Op, CallOptions, SDLoc(
N),
1650 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1651 GetPairElements(Tmp.first,
Lo,
Hi);
1654void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1656 bool IsStrict =
N->isStrictFPOpcode();
1657 unsigned Offset = IsStrict ? 1 : 0;
1660 TargetLowering::MakeLibCallOptions CallOptions;
1661 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1662 Ops, CallOptions, SDLoc(
N),
1665 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1666 GetPairElements(Tmp.first,
Lo,
Hi);
1669void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1670 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(
N->getValueType(0)),
1674void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1675 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(
N->getValueType(0)));
1678void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1679 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1680 RTLIB::getSINCOSPI(
N->getValueType(0)));
1683void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1684 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1685 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1687 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1690 GetPairElements(Res,
Lo,
Hi);
1697 assert(
N->getValueType(0) == MVT::ppcf128 &&
1698 "Logic only correct for ppcf128!");
1701 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1704 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1711 ExpandFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)),
Lo,
Hi);
1716 ExpandFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)),
Lo,
Hi);
1721 ExpandFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1726 ExpandFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1732 RTLIB::ADD_F32, RTLIB::ADD_F64,
1733 RTLIB::ADD_F80, RTLIB::ADD_F128,
1734 RTLIB::ADD_PPCF128),
Lo,
Hi);
1739 ExpandFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)),
Lo,
Hi);
1744 ExpandFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)),
Lo,
Hi);
1749 ExpandFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)),
Lo,
Hi);
1754 ExpandFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)),
Lo,
Hi);
1759 ExpandFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)),
Lo,
Hi);
1762void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1764 ExpandFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)),
Lo,
Hi);
1767void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1769 ExpandFloatRes_Binary(
N, RTLIB::getCOPYSIGN(
N->getValueType(0)),
Lo,
Hi);
1772void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1774 ExpandFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)),
Lo,
Hi);
1779 ExpandFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)),
Lo,
Hi);
1789 RTLIB::DIV_PPCF128),
Lo,
Hi);
1792void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1794 ExpandFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)),
Lo,
Hi);
1797void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1799 ExpandFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)),
Lo,
Hi);
1804 ExpandFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)),
Lo,
Hi);
1807void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1809 ExpandFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)),
Lo,
Hi);
1812void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1814 ExpandFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)),
Lo,
Hi);
1817void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1819 ExpandFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)),
Lo,
Hi);
1822void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1824 ExpandFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)),
Lo,
Hi);
1829 bool IsStrict =
N->isStrictFPOpcode();
1830 unsigned Offset = IsStrict ? 1 : 0;
1834 TargetLowering::MakeLibCallOptions CallOptions;
1835 std::pair<SDValue, SDValue> Tmp =
1836 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)),
1837 N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1839 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1840 GetPairElements(Tmp.first,
Lo,
Hi);
1850 RTLIB::MUL_PPCF128),
Lo,
Hi);
1853void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1855 ExpandFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)),
Lo,
Hi);
1861 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1866void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1870 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1875 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1877 bool IsStrict =
N->isStrictFPOpcode();
1882 if (NVT ==
N->getOperand(1).getValueType()) {
1883 Hi =
N->getOperand(1);
1888 {
N->getOperand(0),
N->getOperand(1) });
1898 ReplaceValueWith(
SDValue(
N, 1), Chain);
1901void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1903 ExpandFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)),
Lo,
Hi);
1906void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1908 ExpandFloatRes_Binary(
N, RTLIB::getPOWI(
N->getValueType(0)),
Lo,
Hi);
1913 ExpandFloatRes_Binary(
N, RTLIB::getLDEXP(
N->getValueType(0)),
Lo,
Hi);
1916void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1918 assert(
N->getValueType(0) == MVT::ppcf128 &&
1919 "Logic only correct for ppcf128!");
1922 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1927void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1929 ExpandFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)),
Lo,
Hi);
1932void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1934 ExpandFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)),
Lo,
Hi);
1937void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1939 ExpandFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)),
Lo,
Hi);
1942void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1944 ExpandFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)),
Lo,
Hi);
1947void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1949 ExpandFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)),
Lo,
Hi);
1954 ExpandFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)),
Lo,
Hi);
1957void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1959 ExpandFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)),
Lo,
Hi);
1969 RTLIB::SUB_PPCF128),
Lo,
Hi);
1974 ExpandFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)),
Lo,
Hi);
1979 ExpandFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)),
Lo,
Hi);
1982void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
1984 ExpandFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)),
Lo,
Hi);
1990 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2000 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2002 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2004 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2005 LD->getMemoryVT(),
LD->getMemOperand());
2015 ReplaceValueWith(
SDValue(LD, 1), Chain);
2020 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2021 EVT VT =
N->getValueType(0);
2022 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2023 bool Strict =
N->isStrictFPOpcode();
2025 EVT SrcVT = Src.getValueType();
2033 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2038 if (SrcVT.
bitsLE(MVT::i32)) {
2042 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2043 {Chain, Src}, Flags);
2046 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2048 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2049 if (SrcVT.
bitsLE(MVT::i64)) {
2052 LC = RTLIB::SINTTOFP_I64_PPCF128;
2053 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2055 LC = RTLIB::SINTTOFP_I128_PPCF128;
2057 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2059 TargetLowering::MakeLibCallOptions CallOptions;
2061 std::pair<SDValue, SDValue> Tmp =
2062 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2065 GetPairElements(Tmp.first,
Lo,
Hi);
2071 ReplaceValueWith(
SDValue(
N, 1), Chain);
2081 SrcVT = Src.getValueType();
2084 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2085 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2086 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2087 ArrayRef<uint64_t> Parts;
2104 SDValue NewLo = DAG.getConstantFP(
2108 {Chain, Hi, NewLo}, Flags);
2110 ReplaceValueWith(
SDValue(
N, 1), Chain);
2113 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2115 GetPairElements(
Lo,
Lo,
Hi);
2127bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2132 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2135 switch (
N->getOpcode()) {
2138 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2139 N->dump(&DAG);
dbgs() <<
"\n";
2147 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2155 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2157 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2158 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2162 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2168 if (!Res.
getNode())
return false;
2176 "Invalid operand expansion");
2178 ReplaceValueWith(
SDValue(
N, 0), Res);
2184void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2189 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2190 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2191 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2200 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2201 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2204 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2205 RHSLo, CCCode, OutputChain, IsSignaling);
2209 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2212 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2213 RHSHi, CCCode, OutputChain, IsSignaling);
2218 Chain = OutputChain;
2225 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2230 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2235 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2236 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2237 N->getOperand(4)), 0);
2241 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2242 "Logic only correct for ppcf128!");
2244 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2248 N->getValueType(0),
N->getOperand(0),
Hi);
2252 bool IsStrict =
N->isStrictFPOpcode();
2253 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2254 "Logic only correct for ppcf128!");
2256 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2261 N->getValueType(0),
Hi,
N->getOperand(1));
2265 if (
Hi.getValueType() ==
N->getValueType(0)) {
2267 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2273 {
N->getValueType(0), MVT::Other},
2274 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2281 EVT RVT =
N->getValueType(0);
2284 bool IsStrict =
N->isStrictFPOpcode();
2287 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2293 "Unsupported FP_TO_XINT!");
2294 TargetLowering::MakeLibCallOptions CallOptions;
2295 std::pair<SDValue, SDValue> Tmp =
2296 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2300 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2301 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2309 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2314 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2319 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2320 N->getOperand(2),
N->getOperand(3),
2321 DAG.getCondCode(CCCode)), 0);
2325 bool IsStrict =
N->isStrictFPOpcode();
2331 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2337 "Unexpected setcc expansion!");
2339 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2340 ReplaceValueWith(
SDValue(
N, 1), Chain);
2346SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2348 return ExpandOp_NormalStore(
N, OpNo);
2351 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2357 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2358 ST->getValue().getValueType());
2360 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2364 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2366 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2367 ST->getMemoryVT(),
ST->getMemOperand());
2371 RTLIB::Libcall LC) {
2372 EVT RVT =
N->getValueType(0);
2373 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2374 if (LCImpl == RTLIB::Unsupported) {
2375 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
2376 N->getOperationName(&DAG));
2377 return DAG.getPOISON(RVT);
2380 TargetLowering::MakeLibCallOptions CallOptions;
2382 .makeLibCall(DAG, LCImpl, RVT,
N->getOperand(0), CallOptions, SDLoc(
N))
2388 return ExpandFloatOp_XRINT_XROUND(
2389 N,
GetFPLibCall(RetVT, RTLIB::LROUND_F32, RTLIB::LROUND_F64,
2390 RTLIB::LROUND_F80, RTLIB::LROUND_F128,
2391 RTLIB::LROUND_PPCF128));
2395 EVT RetVT =
N->getOperand(0).getValueType();
2396 return ExpandFloatOp_XRINT_XROUND(
2397 N,
GetFPLibCall(RetVT, RTLIB::LLROUND_F32, RTLIB::LLROUND_F64,
2398 RTLIB::LLROUND_F80, RTLIB::LLROUND_F128,
2399 RTLIB::LLROUND_PPCF128));
2403 EVT RetVT =
N->getOperand(0).getValueType();
2404 return ExpandFloatOp_XRINT_XROUND(
2406 GetFPLibCall(RetVT, RTLIB::LRINT_F32, RTLIB::LRINT_F64, RTLIB::LRINT_F80,
2407 RTLIB::LRINT_F128, RTLIB::LRINT_PPCF128));
2411 EVT RetVT =
N->getOperand(0).getValueType();
2412 return ExpandFloatOp_XRINT_XROUND(
2413 N,
GetFPLibCall(RetVT, RTLIB::LLRINT_F32, RTLIB::LLRINT_F64,
2414 RTLIB::LLRINT_F80, RTLIB::LLRINT_F128,
2415 RTLIB::LLRINT_PPCF128));
2424 if (OpVT == MVT::f16)
2426 if (RetVT == MVT::f16)
2428 if (OpVT == MVT::bf16)
2430 if (RetVT == MVT::bf16)
2436 if (OpVT == MVT::f16)
2438 if (RetVT == MVT::f16)
2440 if (OpVT == MVT::bf16)
2442 if (RetVT == MVT::bf16)
2456 DAG.getVTList(CastVT, MVT::Other),
2457 { AM->getChain(), AM->getBasePtr(), CastVal },
2473void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2474 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2479 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2484 switch (
N->getOpcode()) {
2487 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2488 N->dump(&DAG);
dbgs() <<
"\n";
2494 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2498 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2531 R = SoftPromoteHalfRes_FABS(
N);
2534 R = SoftPromoteHalfRes_FNEG(
N);
2537 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2553 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2556 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2566 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2569 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2571 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2580 R = SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
N);
2583 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2591 R = SoftPromoteHalfRes_VECREDUCE(
N);
2595 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2600 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2603SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2605 BitConvertToInteger(
N->getOperand(0)));
2609 return BitConvertToInteger(
N->getOperand(0));
2612SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2620SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2621 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2627SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2628 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2629 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2632 EVT LVT =
LHS.getValueType();
2633 EVT RVT =
RHS.getValueType();
2640 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2641 DAG.getConstant(RSize - 1, dl,
2642 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2650 DAG.getConstant(SizeDiff, dl,
2652 DAG.getDataLayout())));
2654 }
else if (SizeDiff < 0) {
2658 DAG.getConstant(-SizeDiff, dl,
2660 DAG.getDataLayout())));
2665 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2666 DAG.getConstant(LSize - 1, dl,
2667 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2668 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2672 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2677 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2678 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2679 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2680 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2681 SDNodeFlags
Flags =
N->getFlags();
2686 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2687 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2688 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2691 if (OVT == MVT::f16) {
2700 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2711 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2716 EVT OVT =
N->getValueType(0);
2717 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2718 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2732 EVT OVT =
N->getValueType(0);
2733 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2734 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2741 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2749SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2750 EVT OVT =
N->getValueType(0);
2751 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2752 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2761 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2763 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2764 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2770SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2771 EVT RVT =
N->getValueType(0);
2772 bool IsStrict =
N->isStrictFPOpcode();
2773 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2774 EVT SVT =
Op.getValueType();
2780 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2783 Op = GetSoftenedFloat(
Op);
2784 TargetLowering::MakeLibCallOptions CallOptions;
2786 std::pair<SDValue, SDValue> Tmp =
2787 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2789 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2790 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2795 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2810 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
2811 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
2812 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
2813 L->getMemOperand()->getFlags(),
L->getAAInfo());
2820SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
2835 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2836 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2837 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1, Op2,
2841SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
2842 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2843 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
2845 N->getOperand(0),
N->getOperand(1), Op2, Op3,
2849SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
2850 EVT OVT =
N->getValueType(0);
2851 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2854 if (
N->isStrictFPOpcode()) {
2855 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
2856 {N->getOperand(0), N->getOperand(1)});
2858 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
2859 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
2870DAGTypeLegalizer::SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
2871 EVT OVT =
N->getValueType(0);
2872 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2876 N->getOperand(0),
N->getOperand(1));
2883 return DAG.getUNDEF(MVT::i16);
2887 EVT OVT =
N->getValueType(0);
2888 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2889 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2902 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2906 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
2907 DAG.getConstant(0x7fff, dl, MVT::i16));
2911 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2915 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
2916 DAG.getConstant(0x8000, dl, MVT::i16));
2919SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
2920 return GetSoftPromotedHalf(
N->getOperand(0));
2924 EVT OVT =
N->getValueType(0);
2925 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2926 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2927 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2932 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2933 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2941SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
2943 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
2947SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
2949 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
2957bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
2958 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
2962 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2972 switch (
N->getOpcode()) {
2975 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
2976 N->dump(&DAG);
dbgs() <<
"\n";
2981 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
2983 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
2986 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3000 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3004 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3006 Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
N);
3010 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3012 Res = SoftPromoteHalfOp_BR_CC(
N);
3014 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3015 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3017 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3020 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3023 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3033 "Invalid operand expansion");
3035 ReplaceValueWith(
SDValue(
N, 0), Res);
3040 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3042 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3045SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3046 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3047 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3048 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3054 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3059 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3061 Op1 = GetSoftPromotedHalf(Op1);
3064 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3068SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3069 EVT RVT =
N->getValueType(0);
3070 bool IsStrict =
N->isStrictFPOpcode();
3071 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3072 EVT SVT =
Op.getValueType();
3073 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3077 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3079 ReplaceValueWith(
SDValue(
N, 0), Res);
3086SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3087 EVT RVT =
N->getValueType(0);
3088 bool IsStrict =
N->isStrictFPOpcode();
3089 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3090 EVT SVT =
Op.getValueType();
3093 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3094 Op = GetSoftPromotedHalf(
Op);
3098 {
N->getOperand(0),
Op});
3099 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3100 {Op.getValue(1), Op});
3101 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3107 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3110SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3111 EVT RVT =
N->getValueType(0);
3113 EVT SVT =
Op.getValueType();
3116 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3118 Op = GetSoftPromotedHalf(
Op);
3122 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3129SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
3130 EVT RVT =
N->getValueType(0);
3132 EVT SVT =
Op.getValueType();
3135 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3136 Op = GetSoftPromotedHalf(
Op);
3140 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
3151 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3154 Op0 = GetSoftPromotedHalf(Op0);
3155 Op1 = GetSoftPromotedHalf(Op1);
3159 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3160 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3163 return DAG.getNode(
ISD::BR_CC, dl, MVT::Other,
N->getOperand(0),
3164 N->getOperand(1), Op0, Op1,
N->getOperand(4));
3169 assert(OpNo == 0 &&
"Can only soften the comparison values");
3175 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3177 Op0 = GetSoftPromotedHalf(Op0);
3178 Op1 = GetSoftPromotedHalf(Op1);
3182 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3183 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3186 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3196 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3198 Op0 = GetSoftPromotedHalf(Op0);
3199 Op1 = GetSoftPromotedHalf(Op1);
3203 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3204 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3206 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3209SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3210 assert(OpNo == 1 &&
"Can only soften the stored value!");
3215 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3216 SDValue Promoted = GetSoftPromotedHalf(Val);
3217 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3218 ST->getMemOperand());
3221SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3223 assert(OpNo == 1 &&
"Can only soften the stored value!");
3228 SDValue Promoted = GetSoftPromotedHalf(Val);
3230 ST->getChain(), Promoted,
ST->getBasePtr(),
3231 ST->getMemOperand());
3234SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3238 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3240 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3242 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3253 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3255 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3257 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 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.
@ 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.
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)