27#define DEBUG_TYPE "legalize-types"
31 N->getOperationName(&DAG) +
" with type " +
39 RTLIB::Libcall Call_F32,
40 RTLIB::Libcall Call_F64,
41 RTLIB::Libcall Call_F80,
42 RTLIB::Libcall Call_F128,
43 RTLIB::Libcall Call_PPCF128) {
45 VT == MVT::f32 ? Call_F32 :
46 VT == MVT::f64 ? Call_F64 :
47 VT == MVT::f80 ? Call_F80 :
48 VT == MVT::f128 ? Call_F128 :
49 VT == MVT::ppcf128 ? Call_PPCF128 :
50 RTLIB::UNKNOWN_LIBCALL;
57void DAGTypeLegalizer::SoftenFloatResult(
SDNode *
N,
unsigned ResNo) {
58 LLVM_DEBUG(
dbgs() <<
"Soften float result " << ResNo <<
": ";
N->dump(&DAG));
61 switch (
N->getOpcode()) {
65 dbgs() <<
"SoftenFloatResult #" << ResNo <<
": ";
66 N->dump(&DAG);
dbgs() <<
"\n";
77 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
80 R = SoftenFloatRes_FCANONICALIZE(
N);
break;
123 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
196 SetSoftenedFloat(
SDValue(
N, ResNo), R);
204 if (
N->isStrictFPOpcode())
205 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
206 return DAG.getPOISON(NVT);
209SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
211 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
212 unsigned Offset = IsStrict ? 1 : 0;
214 "Unexpected number of operands!");
217 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
218 if (LCImpl == RTLIB::Unsupported)
219 return SoftenFloatRes_NoLibcall(
N, NVT);
220 TargetLowering::MakeLibCallOptions CallOptions;
221 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
223 std::pair<SDValue, SDValue> Tmp =
224 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
226 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
230SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
231 bool IsStrict =
N->isStrictFPOpcode();
232 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
233 unsigned Offset = IsStrict ? 1 : 0;
235 "Unexpected number of operands!");
237 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
239 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
240 if (LCImpl == RTLIB::Unsupported)
241 return SoftenFloatRes_NoLibcall(
N, NVT);
242 TargetLowering::MakeLibCallOptions CallOptions;
243 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
244 N->getOperand(1 +
Offset).getValueType() };
246 std::pair<SDValue, SDValue> Tmp =
247 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
249 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
254 return BitConvertToInteger(
N->getOperand(0));
258 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
260 GetSoftenedFloat(
N->getOperand(0)));
264 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
266 GetSoftenedFloat(
N->getOperand(0)));
272 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
273 return BitConvertToInteger(
Op);
279 TLI.getTypeToTransformTo(*DAG.getContext(),
281 BitConvertToInteger(
N->getOperand(0)),
282 BitConvertToInteger(
N->getOperand(1)));
294 if (DAG.getDataLayout().isBigEndian() &&
298 APInt Val(128, words);
299 return DAG.getConstant(Val, SDLoc(CN),
300 TLI.getTypeToTransformTo(*DAG.getContext(),
304 TLI.getTypeToTransformTo(*DAG.getContext(),
309SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
311 assert(Src.getValueType() == MVT::ppcf128 &&
312 "In floats only ppcf128 can be extracted by element!");
314 N->getValueType(0).changeTypeToInteger(),
315 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
318SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
319 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
322 NewOp,
N->getOperand(1));
326 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
333 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
334 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
337SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
351 SDValue One = DAG.getConstantFP(1.0, dl, VT);
352 SDValue Chain = DAG.getEntryNode();
355 SDNodeFlags CanonicalizeFlags =
N->
getFlags();
358 {Chain, Operand, One}, CanonicalizeFlags);
359 return BitConvertToInteger(
Mul);
363 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
364 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
365 return SoftenFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)));
369 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
370 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
371 return SoftenFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)));
375 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)));
379 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)));
383 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM(
N->getValueType(0)));
387 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM(
N->getValueType(0)));
396 RTLIB::ADD_PPCF128));
400 return SoftenFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)));
404 return SoftenFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)));
408 return SoftenFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)));
412 return SoftenFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)));
416 return SoftenFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)));
420 return SoftenFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)));
425 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
428 EVT LVT =
LHS.getValueType();
429 EVT RVT =
RHS.getValueType();
436 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
437 DAG.getConstant(RSize - 1, dl,
438 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
446 DAG.getConstant(SizeDiff, dl,
448 DAG.getDataLayout())));
450 }
else if (SizeDiff < 0) {
454 DAG.getConstant(-SizeDiff, dl,
456 DAG.getDataLayout())));
461 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
462 DAG.getConstant(LSize - 1, dl,
463 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
464 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
468 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
472 return SoftenFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)));
476 return SoftenFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)));
485 RTLIB::DIV_PPCF128));
489 return SoftenFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)));
493 return SoftenFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)));
497 return SoftenFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)));
501 return SoftenFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)));
505 return SoftenFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)));
509 return SoftenFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)));
513 return SoftenFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)));
517 bool IsStrict =
N->isStrictFPOpcode();
518 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
519 unsigned Offset = IsStrict ? 1 : 0;
521 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
522 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
524 TargetLowering::MakeLibCallOptions CallOptions;
525 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
526 N->getOperand(1 +
Offset).getValueType(),
527 N->getOperand(2 +
Offset).getValueType() };
529 RTLIB::Libcall LC = RTLIB::getFMA(
N->getValueType(0));
530 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
531 if (LCImpl == RTLIB::Unsupported)
532 return SoftenFloatRes_NoLibcall(
N, NVT);
533 std::pair<SDValue, SDValue> Tmp =
534 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
536 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
546 RTLIB::MUL_PPCF128));
550 return SoftenFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)));
554 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
559 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
560 DAG.getConstant(SignMask, dl, NVT));
564 bool IsStrict =
N->isStrictFPOpcode();
565 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
574 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
575 N->getValueType(0) != MVT::f32) {
578 { MVT::f32, MVT::Other }, { Chain,
Op });
579 Chain =
Op.getValue(1);
585 if (
Op.getValueType() == MVT::bf16) {
587 return SoftenFloatRes_BF16_TO_FP(
N);
591 if (LC == RTLIB::UNKNOWN_LIBCALL) {
592 DAG.getContext()->emitError(
"do not know how to soften fp_extend");
594 ReplaceValueWith(
SDValue(
N, 1), Chain);
595 return DAG.getPOISON(NVT);
597 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
598 if (LCImpl == RTLIB::Unsupported)
599 return SoftenFloatRes_NoLibcall(
N, NVT);
600 TargetLowering::MakeLibCallOptions CallOptions;
601 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
603 std::pair<SDValue, SDValue> Tmp =
604 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
606 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
613 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
615 TargetLowering::MakeLibCallOptions CallOptions;
616 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
618 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
619 CallOptions, SDLoc(
N)).first;
620 if (
N->getValueType(0) == MVT::f32)
623 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
625 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
626 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
632 assert(
N->getValueType(0) == MVT::f32 &&
633 "Can only soften BF16_TO_FP with f32 result");
634 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
640 DAG.getShiftAmountConstant(16, NVT,
DL));
645 bool IsStrict =
N->isStrictFPOpcode();
646 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
650 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
651 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
652 if (LCImpl == RTLIB::Unsupported)
653 return SoftenFloatRes_NoLibcall(
N, NVT);
654 TargetLowering::MakeLibCallOptions CallOptions;
655 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
657 std::pair<SDValue, SDValue> Tmp =
658 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
660 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
665 return SoftenFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)));
669 bool IsStrict =
N->isStrictFPOpcode();
670 unsigned Offset = IsStrict ? 1 : 0;
673 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
675 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(
N->getValueType(0))
677 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
678 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
679 if (LCImpl == RTLIB::Unsupported) {
682 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
684 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
685 return DAG.getPOISON(NVT);
688 if (DAG.getLibInfo().getIntSize() !=
689 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
692 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
694 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
695 return DAG.getPOISON(NVT);
701 TargetLowering::MakeLibCallOptions CallOptions;
702 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
703 N->getOperand(1 +
Offset).getValueType() };
706 std::pair<SDValue, SDValue> Tmp =
707 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
709 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
714 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
715 EVT VT0 =
N->getValueType(0);
716 EVT VT1 =
N->getValueType(1);
717 RTLIB::Libcall LC = RTLIB::getFREXP(VT0);
718 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
719 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
722 if (LCImpl == RTLIB::Unsupported) {
724 SDValue PoisonExp = DAG.getPOISON(VT1);
725 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
726 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
733 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
734 SDValue PoisonExp = DAG.getPOISON(VT1);
735 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
736 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
739 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
742 TargetLowering::MakeLibCallOptions CallOptions;
743 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
750 .setOpsTypeOverrides(CallOpsTypeOverrides);
752 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LCImpl, NVT0,
Ops, CallOptions,
758 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
760 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
764bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
765 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
766 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
767 EVT VT =
N->getValueType(0);
769 assert(VT ==
N->getValueType(1) &&
770 "expected both return values to have the same type");
772 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
773 if (LCImpl == RTLIB::Unsupported)
776 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
783 std::array<SDValue, 2> StackSlots;
786 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
787 if (ResNum == CallRetResNo)
789 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
790 Ops.push_back(StackSlot);
792 StackSlots[ResNum] = StackSlot;
796 TargetLowering::MakeLibCallOptions CallOptions;
800 .setOpsTypeOverrides(CallOpsTypeOverrides);
802 auto [ReturnVal, Chain] =
803 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
806 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
810 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
813 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
814 if (CallRetResNo == ResNum) {
815 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
818 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
825 EVT VT =
N->getValueType(0);
826 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(VT)))
830 RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
831 RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
834 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
835 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
836 DAG.getContext()->emitError(
"do not know how to soften fsincos");
838 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
839 SoftSin = SoftCos = DAG.getPOISON(NVT);
841 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
842 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
845 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
846 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
851 EVT VT =
N->getValueType(0);
852 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(VT),
856 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
857 DAG.getContext()->emitError(
"do not know how to soften fmodf");
859 SetSoftenedFloat(
SDValue(
N, 0), Poison);
860 SetSoftenedFloat(
SDValue(
N, 1), Poison);
865 return SoftenFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)));
869 return SoftenFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)));
873 return SoftenFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)));
877 return SoftenFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)));
881 return SoftenFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)));
885 return SoftenFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)));
889 return SoftenFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)));
898 RTLIB::SUB_PPCF128));
902 return SoftenFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)));
906 return SoftenFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)));
910 return SoftenFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)));
915 EVT VT =
N->getValueType(0);
916 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
920 L->getMemOperand()->getFlags() &
927 NewL = DAG.getLoad(
L->getAddressingMode(),
ISD::EXTLOAD, NVT, dl,
928 L->getChain(),
L->getBasePtr(),
L->getOffset(),
929 L->getPointerInfo(), MemVT,
L->getBaseAlign(), MMOFlags,
930 L->getMMOMetadataForSubAccess());
939 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
940 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
941 MMOFlags,
L->getMMOMetadataForSubAccess());
946 return BitConvertToInteger(ExtendNode);
951 EVT VT =
N->getValueType(0);
952 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
958 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
972 return DAG.getSelect(SDLoc(
N),
973 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
980 LHS.getValueType(),
N->getOperand(0),
981 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
985 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
986 N->getValueType(0)));
992 EVT VT =
N->getValueType(0);
993 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
997 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
998 N->getConstantOperandVal(3));
1008 bool IsStrict =
N->isStrictFPOpcode();
1011 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1012 EVT RVT =
N->getValueType(0);
1019 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1020 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1021 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1027 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1029 EVT NRVT = TLI.getTypeToTransformTo(*DAG.getContext(), RVT);
1030 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1031 if (LCImpl == RTLIB::Unsupported)
1032 return SoftenFloatRes_NoLibcall(
N, NRVT);
1037 NVT,
N->getOperand(IsStrict ? 1 : 0));
1038 TargetLowering::MakeLibCallOptions CallOptions;
1041 std::pair<SDValue, SDValue> Tmp =
1042 TLI.makeLibCall(DAG, LCImpl, NRVT,
Op, CallOptions, dl, Chain);
1045 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1051 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1055SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1056 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1064bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1065 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1068 switch (
N->getOpcode()) {
1071 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1072 N->dump(&DAG);
dbgs() <<
"\n";
1077 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1090 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1092 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1096 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1098 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1102 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1103 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1105 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1109 Res = SoftenFloatOp_FAKE_USE(
N);
1112 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1115 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1120 if (!Res.
getNode())
return false;
1128 "Invalid operand softening");
1130 ReplaceValueWith(
SDValue(
N, 0), Res);
1135 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1137 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1149 bool IsStrict =
N->isStrictFPOpcode();
1150 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1151 EVT SVT =
Op.getValueType();
1152 EVT RVT =
N->getValueType(0);
1156 FloatRVT = MVT::f16;
1159 FloatRVT = MVT::bf16;
1162 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1165 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1166 if (LCImpl == RTLIB::Unsupported) {
1170 ReplaceValueWith(
SDValue(
N, 1), Chain);
1171 ReplaceValueWith(
SDValue(
N, 0), Poison);
1176 Op = GetSoftenedFloat(
Op);
1177 TargetLowering::MakeLibCallOptions CallOptions;
1179 std::pair<SDValue, SDValue> Tmp =
1180 TLI.makeLibCall(DAG, LCImpl, RVT,
Op, CallOptions, SDLoc(
N), Chain);
1182 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1183 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1194 NewLHS = GetSoftenedFloat(NewLHS);
1195 NewRHS = GetSoftenedFloat(NewRHS);
1196 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1197 N->getOperand(2),
N->getOperand(3));
1201 if (!NewRHS.getNode()) {
1202 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1207 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1208 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1218 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1219 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1220 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1224 if (Promoted.
bitsGE(RetVT))
1232 bool IsStrict =
N->isStrictFPOpcode();
1236 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1237 EVT SVT =
Op.getValueType();
1238 EVT RVT =
N->getValueType(0);
1248 "Unsupported FP_TO_XINT!");
1251 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1252 if (LCImpl == RTLIB::Unsupported) {
1256 ReplaceValueWith(
SDValue(
N, 1), Chain);
1257 ReplaceValueWith(
SDValue(
N, 0), Poison);
1263 Op = GetSoftenedFloat(
Op);
1264 TargetLowering::MakeLibCallOptions CallOptions;
1266 std::pair<SDValue, SDValue> Tmp =
1267 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
1275 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1276 ReplaceValueWith(
SDValue(
N, 0), Res);
1280SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1281 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1290 NewLHS = GetSoftenedFloat(NewLHS);
1291 NewRHS = GetSoftenedFloat(NewRHS);
1292 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1293 N->getOperand(0),
N->getOperand(1));
1297 if (!NewRHS.getNode()) {
1298 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1303 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1304 N->getOperand(2),
N->getOperand(3),
1305 DAG.getCondCode(CCCode)),
1310 bool IsStrict =
N->isStrictFPOpcode();
1317 SDValue NewLHS = GetSoftenedFloat(Op0);
1318 SDValue NewRHS = GetSoftenedFloat(Op1);
1319 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1326 NewRHS, DAG.getCondCode(CCCode));
1328 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1329 DAG.getCondCode(CCCode)), 0);
1334 "Unexpected setcc expansion!");
1337 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1338 ReplaceValueWith(
SDValue(
N, 1), Chain);
1344SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1346 assert(OpNo == 1 &&
"Can only soften the stored value!");
1351 if (
ST->isTruncatingStore())
1353 Val = BitConvertToInteger(
1355 DAG.getIntPtrConstant(0, dl,
true)));
1357 Val = GetSoftenedFloat(Val);
1363 return DAG.getTruncStore(
ST->getChain(), dl, Val,
ST->getBasePtr(), MemVT,
1364 ST->getMemOperand());
1367SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1368 assert(OpNo == 1 &&
"Can only soften the stored value!");
1374 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1376 SDValue NewVal = GetSoftenedFloat(Val);
1378 ST->getBasePtr(),
ST->getMemOperand());
1383 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1386 EVT LVT =
LHS.getValueType();
1388 EVT RVT =
RHS.getValueType();
1394 int SizeDiff = RSize - LSize;
1398 DAG.getConstant(SizeDiff, dl,
1399 TLI.getShiftAmountTy(
RHS.getValueType(),
1400 DAG.getDataLayout())));
1402 }
else if (SizeDiff < 0) {
1406 DAG.getConstant(-SizeDiff, dl,
1407 TLI.getShiftAmountTy(
RHS.getValueType(),
1408 DAG.getDataLayout())));
1411 RHS = DAG.getBitcast(LVT,
RHS);
1415SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1416 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1417 bool IsStrict =
N->isStrictFPOpcode();
1418 unsigned Offset = IsStrict ? 1 : 0;
1421 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1422 if (LCImpl == RTLIB::Unsupported) {
1426 ReplaceValueWith(
SDValue(
N, 1), Chain);
1427 ReplaceValueWith(
SDValue(
N, 0), Poison);
1432 TargetLowering::MakeLibCallOptions CallOptions;
1433 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1435 std::pair<SDValue, SDValue> Tmp =
1436 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
1438 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1439 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1447 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1453 RTLIB::LROUND_PPCF128));
1457 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1462 RTLIB::LLROUND_F128,
1463 RTLIB::LLROUND_PPCF128));
1467 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1473 RTLIB::LRINT_PPCF128));
1477 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1483 RTLIB::LLRINT_PPCF128));
1487 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1488 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1489 N->getOperand(0), Op1);
1492SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1495 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1496 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1499SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1502 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1503 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1514void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1520 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1523 switch (
N->getOpcode()) {
1526 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1527 N->dump(&DAG);
dbgs() <<
"\n";
1642 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1644 "Do not know how to expand this float constant!");
1648 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1649 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1656 if (
N->isStrictFPOpcode())
1657 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
1658 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1659 Lo =
Hi = DAG.getPOISON(NVT);
1662void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1664 bool IsStrict =
N->isStrictFPOpcode();
1665 unsigned Offset = IsStrict ? 1 : 0;
1668 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1669 if (LCImpl == RTLIB::Unsupported)
1670 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1671 TargetLowering::MakeLibCallOptions CallOptions;
1672 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1673 DAG, LCImpl,
N->getValueType(0),
Op, CallOptions, SDLoc(
N), Chain);
1675 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1676 GetPairElements(Tmp.first,
Lo,
Hi);
1679void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1681 bool IsStrict =
N->isStrictFPOpcode();
1682 unsigned Offset = IsStrict ? 1 : 0;
1685 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1686 if (LCImpl == RTLIB::Unsupported)
1687 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1688 TargetLowering::MakeLibCallOptions CallOptions;
1689 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1690 DAG, LCImpl,
N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1692 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1693 GetPairElements(Tmp.first,
Lo,
Hi);
1696void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1697 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(
N->getValueType(0)),
1701void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1702 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(
N->getValueType(0)));
1705void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1706 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1707 RTLIB::getSINCOSPI(
N->getValueType(0)));
1710void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1711 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1712 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1714 if (!TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo)) {
1716 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1718 for (
unsigned ResNo = 0,
E =
N->getNumValues(); ResNo !=
E; ++ResNo)
1719 SetExpandedFloat(
SDValue(
N, ResNo), Poison, Poison);
1724 GetPairElements(Res,
Lo,
Hi);
1731 assert(
N->getValueType(0) == MVT::ppcf128 &&
1732 "Logic only correct for ppcf128!");
1735 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1738 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1745 ExpandFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)),
Lo,
Hi);
1750 ExpandFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)),
Lo,
Hi);
1755 ExpandFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1760 ExpandFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1766 RTLIB::ADD_F32, RTLIB::ADD_F64,
1767 RTLIB::ADD_F80, RTLIB::ADD_F128,
1768 RTLIB::ADD_PPCF128),
Lo,
Hi);
1773 ExpandFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)),
Lo,
Hi);
1778 ExpandFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)),
Lo,
Hi);
1783 ExpandFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)),
Lo,
Hi);
1788 ExpandFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)),
Lo,
Hi);
1793 ExpandFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)),
Lo,
Hi);
1796void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1798 ExpandFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)),
Lo,
Hi);
1801void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1803 ExpandFloatRes_Binary(
N, RTLIB::getCOPYSIGN(
N->getValueType(0)),
Lo,
Hi);
1806void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1808 ExpandFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)),
Lo,
Hi);
1813 ExpandFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)),
Lo,
Hi);
1823 RTLIB::DIV_PPCF128),
Lo,
Hi);
1826void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1828 ExpandFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)),
Lo,
Hi);
1831void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1833 ExpandFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)),
Lo,
Hi);
1838 ExpandFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)),
Lo,
Hi);
1841void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1843 ExpandFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)),
Lo,
Hi);
1846void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1848 ExpandFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)),
Lo,
Hi);
1851void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1853 ExpandFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)),
Lo,
Hi);
1856void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1858 ExpandFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)),
Lo,
Hi);
1863 bool IsStrict =
N->isStrictFPOpcode();
1864 unsigned Offset = IsStrict ? 1 : 0;
1868 RTLIB::Libcall LC = RTLIB::getFMA(
N->getValueType(0));
1869 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1870 if (LCImpl == RTLIB::Unsupported)
1871 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1872 TargetLowering::MakeLibCallOptions CallOptions;
1873 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1874 DAG, LCImpl,
N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1876 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1877 GetPairElements(Tmp.first,
Lo,
Hi);
1887 RTLIB::MUL_PPCF128),
Lo,
Hi);
1890void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1892 ExpandFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)),
Lo,
Hi);
1898 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1903void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1907 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1912 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1914 bool IsStrict =
N->isStrictFPOpcode();
1919 if (NVT ==
N->getOperand(1).getValueType()) {
1920 Hi =
N->getOperand(1);
1925 {
N->getOperand(0),
N->getOperand(1) });
1935 ReplaceValueWith(
SDValue(
N, 1), Chain);
1938void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1940 ExpandFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)),
Lo,
Hi);
1943void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1945 ExpandFloatRes_Binary(
N, RTLIB::getPOWI(
N->getValueType(0)),
Lo,
Hi);
1950 ExpandFloatRes_Binary(
N, RTLIB::getLDEXP(
N->getValueType(0)),
Lo,
Hi);
1953void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1955 assert(
N->getValueType(0) == MVT::ppcf128 &&
1956 "Logic only correct for ppcf128!");
1959 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1964void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1966 ExpandFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)),
Lo,
Hi);
1969void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1971 ExpandFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)),
Lo,
Hi);
1974void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1976 ExpandFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)),
Lo,
Hi);
1979void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1981 ExpandFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)),
Lo,
Hi);
1984void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1986 ExpandFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)),
Lo,
Hi);
1991 ExpandFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)),
Lo,
Hi);
1994void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1996 ExpandFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)),
Lo,
Hi);
2006 RTLIB::SUB_PPCF128),
Lo,
Hi);
2011 ExpandFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)),
Lo,
Hi);
2016 ExpandFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)),
Lo,
Hi);
2019void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2021 ExpandFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)),
Lo,
Hi);
2027 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2037 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2039 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2041 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2042 LD->getMemoryVT(),
LD->getMemOperand());
2052 ReplaceValueWith(
SDValue(LD, 1), Chain);
2057 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2058 EVT VT =
N->getValueType(0);
2059 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2060 bool Strict =
N->isStrictFPOpcode();
2062 EVT SrcVT = Src.getValueType();
2070 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2075 if (SrcVT.
bitsLE(MVT::i32)) {
2079 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2080 {Chain, Src}, Flags);
2083 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2085 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2086 if (SrcVT.
bitsLE(MVT::i64)) {
2089 LC = RTLIB::SINTTOFP_I64_PPCF128;
2090 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2092 LC = RTLIB::SINTTOFP_I128_PPCF128;
2094 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2096 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2097 if (LCImpl == RTLIB::Unsupported)
2098 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
2100 TargetLowering::MakeLibCallOptions CallOptions;
2102 std::pair<SDValue, SDValue> Tmp =
2103 TLI.makeLibCall(DAG, LCImpl, VT, Src, CallOptions, dl, Chain);
2106 GetPairElements(Tmp.first,
Lo,
Hi);
2112 ReplaceValueWith(
SDValue(
N, 1), Chain);
2122 SrcVT = Src.getValueType();
2125 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2126 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2127 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2128 ArrayRef<uint64_t> Parts;
2145 SDValue NewLo = DAG.getConstantFP(
2149 {Chain, Hi, NewLo}, Flags);
2151 ReplaceValueWith(
SDValue(
N, 1), Chain);
2154 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2156 GetPairElements(
Lo,
Lo,
Hi);
2168bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2173 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2176 switch (
N->getOpcode()) {
2179 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2180 N->dump(&DAG);
dbgs() <<
"\n";
2188 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2196 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2198 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2199 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2203 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2209 if (!Res.
getNode())
return false;
2217 "Invalid operand expansion");
2219 ReplaceValueWith(
SDValue(
N, 0), Res);
2225void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2230 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2231 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2232 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2241 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2242 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2245 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2246 RHSLo, CCCode, OutputChain, IsSignaling);
2250 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2253 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2254 RHSHi, CCCode, OutputChain, IsSignaling);
2259 Chain = OutputChain;
2266 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2271 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2276 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2277 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2278 N->getOperand(4)), 0);
2282 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2283 "Logic only correct for ppcf128!");
2285 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2289 N->getValueType(0),
N->getOperand(0),
Hi);
2293 bool IsStrict =
N->isStrictFPOpcode();
2294 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2295 "Logic only correct for ppcf128!");
2297 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2302 N->getValueType(0),
Hi,
N->getOperand(1));
2306 if (
Hi.getValueType() ==
N->getValueType(0)) {
2308 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2314 {
N->getValueType(0), MVT::Other},
2315 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2322 EVT RVT =
N->getValueType(0);
2325 bool IsStrict =
N->isStrictFPOpcode();
2328 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2334 "Unsupported FP_TO_XINT!");
2335 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2336 if (LCImpl == RTLIB::Unsupported) {
2340 ReplaceValueWith(
SDValue(
N, 1), Chain);
2341 ReplaceValueWith(
SDValue(
N, 0), Poison);
2346 TargetLowering::MakeLibCallOptions CallOptions;
2347 std::pair<SDValue, SDValue> Tmp =
2348 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
2352 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2353 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2361 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2366 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2371 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2372 N->getOperand(2),
N->getOperand(3),
2373 DAG.getCondCode(CCCode)), 0);
2377 bool IsStrict =
N->isStrictFPOpcode();
2382 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2388 "Unexpected setcc expansion!");
2390 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2391 ReplaceValueWith(
SDValue(
N, 1), Chain);
2397SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2399 return ExpandOp_NormalStore(
N, OpNo);
2402 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2408 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2409 ST->getValue().getValueType());
2411 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2415 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2417 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2418 ST->getMemoryVT(),
ST->getMemOperand());
2422 RTLIB::Libcall LC) {
2423 EVT RVT =
N->getValueType(0);
2424 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2425 if (LCImpl == RTLIB::Unsupported) {
2427 return DAG.getPOISON(RVT);
2430 TargetLowering::MakeLibCallOptions CallOptions;
2432 .makeLibCall(DAG, LCImpl, RVT,
N->getOperand(0), CallOptions, SDLoc(
N))
2438 return ExpandFloatOp_XRINT_XROUND(
2439 N,
GetFPLibCall(RetVT, RTLIB::LROUND_F32, RTLIB::LROUND_F64,
2440 RTLIB::LROUND_F80, RTLIB::LROUND_F128,
2441 RTLIB::LROUND_PPCF128));
2445 EVT RetVT =
N->getOperand(0).getValueType();
2446 return ExpandFloatOp_XRINT_XROUND(
2447 N,
GetFPLibCall(RetVT, RTLIB::LLROUND_F32, RTLIB::LLROUND_F64,
2448 RTLIB::LLROUND_F80, RTLIB::LLROUND_F128,
2449 RTLIB::LLROUND_PPCF128));
2453 EVT RetVT =
N->getOperand(0).getValueType();
2454 return ExpandFloatOp_XRINT_XROUND(
2456 GetFPLibCall(RetVT, RTLIB::LRINT_F32, RTLIB::LRINT_F64, RTLIB::LRINT_F80,
2457 RTLIB::LRINT_F128, RTLIB::LRINT_PPCF128));
2461 EVT RetVT =
N->getOperand(0).getValueType();
2462 return ExpandFloatOp_XRINT_XROUND(
2463 N,
GetFPLibCall(RetVT, RTLIB::LLRINT_F32, RTLIB::LLRINT_F64,
2464 RTLIB::LLRINT_F80, RTLIB::LLRINT_F128,
2465 RTLIB::LLRINT_PPCF128));
2474 if (OpVT == MVT::f16)
2476 if (RetVT == MVT::f16)
2478 if (OpVT == MVT::bf16)
2480 if (RetVT == MVT::bf16)
2486 if (OpVT == MVT::f16)
2488 if (RetVT == MVT::f16)
2490 if (OpVT == MVT::bf16)
2492 if (RetVT == MVT::bf16)
2506 DAG.getVTList(CastVT, MVT::Other),
2507 { AM->getChain(), AM->getBasePtr(), CastVal },
2523void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2524 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2529 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2534 switch (
N->getOpcode()) {
2537 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2538 N->dump(&DAG);
dbgs() <<
"\n";
2544 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2548 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2581 R = SoftPromoteHalfRes_FABS(
N);
2584 R = SoftPromoteHalfRes_FNEG(
N);
2587 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2603 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2606 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2616 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2619 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2621 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2630 R = SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
N);
2633 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2643 R = SoftPromoteHalfRes_VECREDUCE(
N);
2647 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2652 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2655SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2657 BitConvertToInteger(
N->getOperand(0)));
2661 return BitConvertToInteger(
N->getOperand(0));
2664SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2672SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2673 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2679SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2680 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2681 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2684 EVT LVT =
LHS.getValueType();
2685 EVT RVT =
RHS.getValueType();
2692 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2693 DAG.getConstant(RSize - 1, dl,
2694 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2702 DAG.getConstant(SizeDiff, dl,
2704 DAG.getDataLayout())));
2706 }
else if (SizeDiff < 0) {
2710 DAG.getConstant(-SizeDiff, dl,
2712 DAG.getDataLayout())));
2717 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2718 DAG.getConstant(LSize - 1, dl,
2719 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2720 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2724 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2729 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2730 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2731 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2732 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2733 SDNodeFlags
Flags =
N->getFlags();
2738 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2739 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2740 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2743 if (OVT == MVT::f16) {
2752 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2763 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2768 EVT OVT =
N->getValueType(0);
2769 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2770 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2784 EVT OVT =
N->getValueType(0);
2785 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2786 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2793 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2801SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2802 EVT OVT =
N->getValueType(0);
2803 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2804 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2813 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2815 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2816 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2822SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2823 EVT RVT =
N->getValueType(0);
2824 bool IsStrict =
N->isStrictFPOpcode();
2825 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2826 EVT SVT =
Op.getValueType();
2830 if (RVT == MVT::bf16 && SVT == MVT::f32 &&
2831 N->getConstantOperandVal(IsStrict ? 2 : 1) == 1) {
2834 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2837 DAG.getShiftAmountConstant(16, MVT::i32,
DL));
2845 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2848 Op = GetSoftenedFloat(
Op);
2849 TargetLowering::MakeLibCallOptions CallOptions;
2851 std::pair<SDValue, SDValue> Tmp =
2852 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2854 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2855 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2860 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2874 SDValue NewL = DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(),
2875 MVT::i16, SDLoc(
N),
L->getChain(),
L->getBasePtr(),
2876 L->getOffset(),
L->getPointerInfo(), MVT::i16,
2877 L->getBaseAlign(),
L->getMemOperand()->getFlags(),
2878 L->getMMOMetadataForSubAccess());
2885SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
2900 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2901 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2902 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1, Op2,
2906SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
2907 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2908 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
2910 N->getOperand(0),
N->getOperand(1), Op2, Op3,
2914SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
2915 EVT OVT =
N->getValueType(0);
2916 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2919 if (
N->isStrictFPOpcode()) {
2920 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
2921 {N->getOperand(0), N->getOperand(1)});
2923 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
2924 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
2935DAGTypeLegalizer::SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
2936 EVT OVT =
N->getValueType(0);
2937 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2941 N->getOperand(0),
N->getOperand(1));
2948 return DAG.getUNDEF(MVT::i16);
2952 EVT OVT =
N->getValueType(0);
2953 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2954 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2967 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2971 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
2972 DAG.getConstant(0x7fff, dl, MVT::i16));
2976 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2980 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
2981 DAG.getConstant(0x8000, dl, MVT::i16));
2984SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
2985 return GetSoftPromotedHalf(
N->getOperand(0));
2989 EVT OVT =
N->getValueType(0);
2990 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2991 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2992 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2997 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2998 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3006SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3008 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3012SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3014 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3022bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3023 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3027 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3037 switch (
N->getOpcode()) {
3040 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3041 N->dump(&DAG);
dbgs() <<
"\n";
3046 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3048 Res = SoftPromoteHalfOp_BUILD_VECTOR(
N);
3051 Res = SoftPromoteHalfOp_INSERT_VECTOR_ELT(
N, OpNo);
3054 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3057 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3071 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3075 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3077 Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
N);
3081 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3083 Res = SoftPromoteHalfOp_BR_CC(
N);
3085 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3086 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3088 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3091 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3094 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3104 "Invalid operand expansion");
3106 ReplaceValueWith(
SDValue(
N, 0), Res);
3111 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3113 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3116SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BUILD_VECTOR(
SDNode *
N) {
3118 EVT VT =
N->getValueType(0);
3121 for (
unsigned I = 0,
E =
N->getNumOperands();
I !=
E; ++
I)
3122 Ops[
I] = GetSoftPromotedHalf(
N->getOperand(
I));
3125 SDValue Res = DAG.getBuildVector(IVT, dl,
Ops);
3126 return DAG.getBitcast(VT, Res);
3129SDValue DAGTypeLegalizer::SoftPromoteHalfOp_INSERT_VECTOR_ELT(
SDNode *
N,
3131 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3132 SDValue Vec = BitConvertVectorToIntegerVector(
N->getOperand(0));
3133 SDValue Elt = GetSoftPromotedHalf(
N->getOperand(OpNo));
3136 return DAG.getBitcast(
N->getValueType(0), Res);
3139SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3140 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3141 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3142 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3148 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3153 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3155 Op1 = GetSoftPromotedHalf(Op1);
3158 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3162SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3163 EVT RVT =
N->getValueType(0);
3164 bool IsStrict =
N->isStrictFPOpcode();
3165 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3166 EVT SVT =
Op.getValueType();
3167 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3171 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3173 ReplaceValueWith(
SDValue(
N, 0), Res);
3180SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3181 EVT RVT =
N->getValueType(0);
3182 bool IsStrict =
N->isStrictFPOpcode();
3183 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3184 EVT SVT =
Op.getValueType();
3187 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3188 Op = GetSoftPromotedHalf(
Op);
3192 {
N->getOperand(0),
Op});
3193 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3194 {Op.getValue(1), Op});
3195 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3201 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3204SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3205 EVT RVT =
N->getValueType(0);
3207 EVT SVT =
Op.getValueType();
3210 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3212 Op = GetSoftPromotedHalf(
Op);
3216 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3223SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
3224 EVT RVT =
N->getValueType(0);
3226 EVT SVT =
Op.getValueType();
3229 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3230 Op = GetSoftPromotedHalf(
Op);
3234 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
3245 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3248 Op0 = GetSoftPromotedHalf(Op0);
3249 Op1 = GetSoftPromotedHalf(Op1);
3253 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3254 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3257 return DAG.getNode(
ISD::BR_CC, dl, MVT::Other,
N->getOperand(0),
3258 N->getOperand(1), Op0, Op1,
N->getOperand(4));
3263 assert(OpNo == 0 &&
"Can only soften the comparison values");
3269 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3271 Op0 = GetSoftPromotedHalf(Op0);
3272 Op1 = GetSoftPromotedHalf(Op1);
3276 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3277 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3280 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3290 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3292 Op0 = GetSoftPromotedHalf(Op0);
3293 Op1 = GetSoftPromotedHalf(Op1);
3297 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3298 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3300 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3303SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3304 assert(OpNo == 1 &&
"Can only soften the stored value!");
3309 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3310 SDValue Promoted = GetSoftPromotedHalf(Val);
3311 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3312 ST->getMemOperand());
3315SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3317 assert(OpNo == 1 &&
"Can only soften the stored value!");
3322 SDValue Promoted = GetSoftPromotedHalf(Val);
3324 ST->getChain(), Promoted,
ST->getBasePtr(),
3325 ST->getMemOperand());
3328SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3332 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3334 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3336 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3347 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3349 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3351 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 void reportNoLibcall(SelectionDAG &DAG, SDNode *N, EVT VT)
static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT)
static ISD::NodeType GetPromotionOpcodeStrict(EVT OpVT, EVT RetVT)
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.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
@ 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.
ISD::CondCode getOperandCondCode(unsigned Num) const
Helper method returns the CondCode of a CondCodeSDNode.
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.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVMContext * getContext() const
void push_back(const T &Elt)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#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 - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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 - Same semantics as the llvm.minimum/maximum intrinsics.
@ 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),...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ 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 - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ 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.
Type * getValueType(Value *V, bool ReVec, bool LookThroughCmp)
Returns the "element type" of the given value/instruction V.
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.
std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
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)