27#define DEBUG_TYPE "legalize-types"
33 RTLIB::Libcall Call_F32,
34 RTLIB::Libcall Call_F64,
35 RTLIB::Libcall Call_F80,
36 RTLIB::Libcall Call_F128,
37 RTLIB::Libcall Call_PPCF128) {
39 VT == MVT::f32 ? Call_F32 :
40 VT == MVT::f64 ? Call_F64 :
41 VT == MVT::f80 ? Call_F80 :
42 VT == MVT::f128 ? Call_F128 :
43 VT == MVT::ppcf128 ? Call_PPCF128 :
44 RTLIB::UNKNOWN_LIBCALL;
51void DAGTypeLegalizer::SoftenFloatResult(
SDNode *
N,
unsigned ResNo) {
52 LLVM_DEBUG(
dbgs() <<
"Soften float result " << ResNo <<
": ";
N->dump(&DAG));
55 switch (
N->getOpcode()) {
59 dbgs() <<
"SoftenFloatResult #" << ResNo <<
": ";
60 N->dump(&DAG);
dbgs() <<
"\n";
71 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(
N, ResNo);
break;
74 R = SoftenFloatRes_FCANONICALIZE(
N);
break;
117 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
190 SetSoftenedFloat(
SDValue(
N, ResNo), R);
197 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
198 N->getOperationName(&DAG));
199 if (
N->isStrictFPOpcode())
200 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
201 return DAG.getPOISON(NVT);
204SDValue DAGTypeLegalizer::SoftenFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC) {
206 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
207 unsigned Offset = IsStrict ? 1 : 0;
209 "Unexpected number of operands!");
212 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
213 if (LCImpl == RTLIB::Unsupported)
214 return SoftenFloatRes_NoLibcall(
N, NVT);
215 TargetLowering::MakeLibCallOptions CallOptions;
216 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
218 std::pair<SDValue, SDValue> Tmp =
219 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
221 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
225SDValue DAGTypeLegalizer::SoftenFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC) {
226 bool IsStrict =
N->isStrictFPOpcode();
227 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
228 unsigned Offset = IsStrict ? 1 : 0;
230 "Unexpected number of operands!");
232 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
234 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
235 if (LCImpl == RTLIB::Unsupported)
236 return SoftenFloatRes_NoLibcall(
N, NVT);
237 TargetLowering::MakeLibCallOptions CallOptions;
238 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
239 N->getOperand(1 +
Offset).getValueType() };
241 std::pair<SDValue, SDValue> Tmp =
242 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
244 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
249 return BitConvertToInteger(
N->getOperand(0));
253 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
255 GetSoftenedFloat(
N->getOperand(0)));
259 EVT Ty = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
261 GetSoftenedFloat(
N->getOperand(0)));
267 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
268 return BitConvertToInteger(
Op);
274 TLI.getTypeToTransformTo(*DAG.getContext(),
276 BitConvertToInteger(
N->getOperand(0)),
277 BitConvertToInteger(
N->getOperand(1)));
289 if (DAG.getDataLayout().isBigEndian() &&
293 APInt Val(128, words);
294 return DAG.getConstant(Val, SDLoc(CN),
295 TLI.getTypeToTransformTo(*DAG.getContext(),
299 TLI.getTypeToTransformTo(*DAG.getContext(),
304SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
306 assert(Src.getValueType() == MVT::ppcf128 &&
307 "In floats only ppcf128 can be extracted by element!");
309 N->getValueType(0).changeTypeToInteger(),
310 DAG.getBitcast(MVT::i128, Src),
N->getOperand(1));
313SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
314 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
317 NewOp,
N->getOperand(1));
321 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
328 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
329 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
332SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
346 SDValue One = DAG.getConstantFP(1.0, dl, VT);
347 SDValue Chain = DAG.getEntryNode();
350 SDNodeFlags CanonicalizeFlags =
N->
getFlags();
353 {Chain, Operand, One}, CanonicalizeFlags);
354 return BitConvertToInteger(
Mul);
358 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
359 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
360 return SoftenFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)));
364 if (
SDValue SelCC = TLI.createSelectForFMINNUM_FMAXNUM(
N, DAG))
365 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
366 return SoftenFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)));
370 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)));
374 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)));
378 return SoftenFloatRes_Binary(
N, RTLIB::getFMINIMUM(
N->getValueType(0)));
382 return SoftenFloatRes_Binary(
N, RTLIB::getFMAXIMUM(
N->getValueType(0)));
391 RTLIB::ADD_PPCF128));
395 return SoftenFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)));
399 return SoftenFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)));
403 return SoftenFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)));
407 return SoftenFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)));
411 return SoftenFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)));
415 return SoftenFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)));
420 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
423 EVT LVT =
LHS.getValueType();
424 EVT RVT =
RHS.getValueType();
431 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
432 DAG.getConstant(RSize - 1, dl,
433 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
441 DAG.getConstant(SizeDiff, dl,
443 DAG.getDataLayout())));
445 }
else if (SizeDiff < 0) {
449 DAG.getConstant(-SizeDiff, dl,
451 DAG.getDataLayout())));
456 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
457 DAG.getConstant(LSize - 1, dl,
458 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
459 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
463 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
467 return SoftenFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)));
471 return SoftenFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)));
480 RTLIB::DIV_PPCF128));
484 return SoftenFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)));
488 return SoftenFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)));
492 return SoftenFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)));
496 return SoftenFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)));
500 return SoftenFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)));
504 return SoftenFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)));
508 return SoftenFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)));
512 bool IsStrict =
N->isStrictFPOpcode();
513 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
514 unsigned Offset = IsStrict ? 1 : 0;
516 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
517 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
519 TargetLowering::MakeLibCallOptions CallOptions;
520 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
521 N->getOperand(1 +
Offset).getValueType(),
522 N->getOperand(2 +
Offset).getValueType() };
524 std::pair<SDValue, SDValue> Tmp =
525 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)), NVT,
Ops,
526 CallOptions, SDLoc(
N), Chain);
528 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
538 RTLIB::MUL_PPCF128));
542 return SoftenFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)));
546 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
551 return DAG.getNode(
ISD::XOR, dl, NVT, GetSoftenedFloat(
N->getOperand(0)),
552 DAG.getConstant(SignMask, dl, NVT));
556 bool IsStrict =
N->isStrictFPOpcode();
557 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
566 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
567 N->getValueType(0) != MVT::f32) {
570 { MVT::f32, MVT::Other }, { Chain,
Op });
571 Chain =
Op.getValue(1);
577 if (
Op.getValueType() == MVT::bf16) {
579 return SoftenFloatRes_BF16_TO_FP(
N);
583 if (LC == RTLIB::UNKNOWN_LIBCALL) {
584 DAG.getContext()->emitError(
"do not know how to soften fp_extend");
586 ReplaceValueWith(
SDValue(
N, 1), Chain);
587 return DAG.getPOISON(NVT);
589 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
590 if (LCImpl == RTLIB::Unsupported)
591 return SoftenFloatRes_NoLibcall(
N, NVT);
592 TargetLowering::MakeLibCallOptions CallOptions;
593 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
595 std::pair<SDValue, SDValue> Tmp =
596 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
598 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
605 EVT MidVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
607 TargetLowering::MakeLibCallOptions CallOptions;
608 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
610 SDValue Res32 = TLI.makeLibCall(DAG, RTLIB::FPEXT_F16_F32, MidVT,
Op,
611 CallOptions, SDLoc(
N)).first;
612 if (
N->getValueType(0) == MVT::f32)
615 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
617 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
618 return TLI.makeLibCall(DAG, LC, NVT, Res32, CallOptions, SDLoc(
N)).first;
624 assert(
N->getValueType(0) == MVT::f32 &&
625 "Can only soften BF16_TO_FP with f32 result");
626 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), MVT::f32);
632 DAG.getShiftAmountConstant(16, NVT,
DL));
637 bool IsStrict =
N->isStrictFPOpcode();
638 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
642 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
643 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
644 if (LCImpl == RTLIB::Unsupported)
645 return SoftenFloatRes_NoLibcall(
N, NVT);
646 TargetLowering::MakeLibCallOptions CallOptions;
647 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
649 std::pair<SDValue, SDValue> Tmp =
650 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
652 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
657 return SoftenFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)));
661 bool IsStrict =
N->isStrictFPOpcode();
662 unsigned Offset = IsStrict ? 1 : 0;
665 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
667 RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(
N->getValueType(0))
669 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
670 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
671 if (LCImpl == RTLIB::Unsupported) {
674 DAG.getContext()->emitError(
"do not know how to soften fpowi to fpow");
676 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
677 return DAG.getPOISON(NVT);
680 if (DAG.getLibInfo().getIntSize() !=
681 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
684 DAG.getContext()->emitError(
"powi exponent does not match sizeof(int)");
686 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
687 return DAG.getPOISON(NVT);
693 TargetLowering::MakeLibCallOptions CallOptions;
694 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
695 N->getOperand(1 +
Offset).getValueType() };
698 std::pair<SDValue, SDValue> Tmp =
699 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions, SDLoc(
N), Chain);
701 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
706 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented for frexp");
707 EVT VT0 =
N->getValueType(0);
708 EVT VT1 =
N->getValueType(1);
709 RTLIB::Libcall LC = RTLIB::getFREXP(VT0);
710 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
711 EVT NVT0 = TLI.getTypeToTransformTo(*DAG.getContext(), VT0);
714 if (LCImpl == RTLIB::Unsupported) {
715 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
716 N->getOperationName(&DAG));
717 SDValue PoisonExp = DAG.getPOISON(VT1);
718 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
719 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
726 DAG.getContext()->emitError(
"ffrexp exponent does not match sizeof(int)");
727 SDValue PoisonExp = DAG.getPOISON(VT1);
728 ReplaceValueWith(
SDValue(
N, 1), PoisonExp);
729 return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp},
DL);
732 SDValue StackSlot = DAG.CreateStackTemporary(VT1);
735 TargetLowering::MakeLibCallOptions CallOptions;
736 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
743 .setOpsTypeOverrides(CallOpsTypeOverrides);
745 auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LCImpl, NVT0,
Ops, CallOptions,
751 SDValue LoadExp = DAG.getLoad(VT1,
DL, Chain, StackSlot, PtrInfo);
753 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
757bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
758 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
759 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
760 EVT VT =
N->getValueType(0);
762 assert(VT ==
N->getValueType(1) &&
763 "expected both return values to have the same type");
765 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
766 if (LCImpl == RTLIB::Unsupported)
769 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
776 std::array<SDValue, 2> StackSlots;
779 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ++ResNum) {
780 if (ResNum == CallRetResNo)
782 SDValue StackSlot = DAG.CreateStackTemporary(NVT);
783 Ops.push_back(StackSlot);
785 StackSlots[ResNum] = StackSlot;
789 TargetLowering::MakeLibCallOptions CallOptions;
793 .setOpsTypeOverrides(CallOpsTypeOverrides);
795 auto [ReturnVal, Chain] =
796 TLI.makeLibCall(DAG, LCImpl, NVT,
Ops, CallOptions,
DL,
799 auto CreateStackLoad = [&, Chain = Chain](
SDValue StackSlot) {
803 return DAG.getLoad(NVT,
DL, Chain, StackSlot, PtrInfo);
806 for (
auto [ResNum, SlackSlot] :
enumerate(StackSlots)) {
807 if (CallRetResNo == ResNum) {
808 SetSoftenedFloat(
SDValue(
N, ResNum), ReturnVal);
811 SetSoftenedFloat(
SDValue(
N, ResNum), CreateStackLoad(SlackSlot));
818 EVT VT =
N->getValueType(0);
819 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(VT)))
823 RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
824 RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
827 if (DAG.getLibcalls().getLibcallImpl(SinLC) == RTLIB::Unsupported ||
828 DAG.getLibcalls().getLibcallImpl(CosLC) == RTLIB::Unsupported) {
829 DAG.getContext()->emitError(
"do not know how to soften fsincos");
831 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
832 SoftSin = SoftCos = DAG.getPOISON(NVT);
834 SoftSin = SoftenFloatRes_Unary(
N, SinLC);
835 SoftCos = SoftenFloatRes_Unary(
N, CosLC);
838 SetSoftenedFloat(
SDValue(
N, 0), SoftSin);
839 SetSoftenedFloat(
SDValue(
N, 1), SoftCos);
844 EVT VT =
N->getValueType(0);
845 if (SoftenFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(VT),
849 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
850 DAG.getContext()->emitError(
"do not know how to soften fmodf");
858 return SoftenFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)));
862 return SoftenFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)));
866 return SoftenFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)));
870 return SoftenFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)));
874 return SoftenFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)));
878 return SoftenFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)));
882 return SoftenFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)));
891 RTLIB::SUB_PPCF128));
895 return SoftenFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)));
899 return SoftenFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)));
903 return SoftenFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)));
908 EVT VT =
N->getValueType(0);
909 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
913 L->getMemOperand()->getFlags() &
920 NewL = DAG.getLoad(
L->getAddressingMode(),
ISD::EXTLOAD, NVT, dl,
921 L->getChain(),
L->getBasePtr(),
L->getOffset(),
922 L->getPointerInfo(), MemVT,
L->getBaseAlign(), MMOFlags,
932 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
933 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
934 MMOFlags,
L->getAAInfo());
939 return BitConvertToInteger(ExtendNode);
944 EVT VT =
N->getValueType(0);
945 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
951 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
965 return DAG.getSelect(SDLoc(
N),
966 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
973 LHS.getValueType(),
N->getOperand(0),
974 N->getOperand(1),
LHS,
RHS,
N->getOperand(4));
978 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(),
979 N->getValueType(0)));
985 EVT VT =
N->getValueType(0);
986 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
990 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr,
N->getOperand(2),
991 N->getConstantOperandVal(3));
1001 bool IsStrict =
N->isStrictFPOpcode();
1004 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
1005 EVT RVT =
N->getValueType(0);
1012 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1013 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
1014 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
1020 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1022 EVT NRVT = TLI.getTypeToTransformTo(*DAG.getContext(), RVT);
1023 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1024 if (LCImpl == RTLIB::Unsupported)
1025 return SoftenFloatRes_NoLibcall(
N, NRVT);
1030 NVT,
N->getOperand(IsStrict ? 1 : 0));
1031 TargetLowering::MakeLibCallOptions CallOptions;
1034 std::pair<SDValue, SDValue> Tmp =
1035 TLI.makeLibCall(DAG, LCImpl, NRVT,
Op, CallOptions, dl, Chain);
1038 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1044 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
1048SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
1049 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
1057bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
1058 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
1061 switch (
N->getOpcode()) {
1064 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
1065 N->dump(&DAG);
dbgs() <<
"\n";
1070 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1083 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1085 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1089 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1091 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1095 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1096 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1098 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1102 Res = SoftenFloatOp_FAKE_USE(
N);
1105 Res = SoftenFloatOp_STACKMAP(
N, OpNo);
1108 Res = SoftenFloatOp_PATCHPOINT(
N, OpNo);
1113 if (!Res.
getNode())
return false;
1121 "Invalid operand softening");
1123 ReplaceValueWith(
SDValue(
N, 0), Res);
1128 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1130 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
1142 bool IsStrict =
N->isStrictFPOpcode();
1143 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1144 EVT SVT =
Op.getValueType();
1145 EVT RVT =
N->getValueType(0);
1149 FloatRVT = MVT::f16;
1152 FloatRVT = MVT::bf16;
1155 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1158 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1159 if (LCImpl == RTLIB::Unsupported) {
1160 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1161 N->getOperationName(&DAG));
1164 ReplaceValueWith(
SDValue(
N, 1), Chain);
1170 Op = GetSoftenedFloat(
Op);
1171 TargetLowering::MakeLibCallOptions CallOptions;
1173 std::pair<SDValue, SDValue> Tmp =
1174 TLI.makeLibCall(DAG, LCImpl, RVT,
Op, CallOptions, SDLoc(
N), Chain);
1176 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1177 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1188 NewLHS = GetSoftenedFloat(NewLHS);
1189 NewRHS = GetSoftenedFloat(NewRHS);
1190 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1191 N->getOperand(2),
N->getOperand(3));
1195 if (!NewRHS.getNode()) {
1196 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1201 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
1202 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1212 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1213 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1214 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1218 if (Promoted.
bitsGE(RetVT))
1226 bool IsStrict =
N->isStrictFPOpcode();
1230 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1231 EVT SVT =
Op.getValueType();
1232 EVT RVT =
N->getValueType(0);
1242 "Unsupported FP_TO_XINT!");
1245 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1246 if (LCImpl == RTLIB::Unsupported) {
1247 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1248 N->getOperationName(&DAG));
1251 ReplaceValueWith(
SDValue(
N, 1), Chain);
1258 Op = GetSoftenedFloat(
Op);
1259 TargetLowering::MakeLibCallOptions CallOptions;
1261 std::pair<SDValue, SDValue> Tmp =
1262 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
1270 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1271 ReplaceValueWith(
SDValue(
N, 0), Res);
1275SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1276 SDValue Res = TLI.expandFP_TO_INT_SAT(
N, DAG);
1285 NewLHS = GetSoftenedFloat(NewLHS);
1286 NewRHS = GetSoftenedFloat(NewRHS);
1287 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N),
1288 N->getOperand(0),
N->getOperand(1));
1292 if (!NewRHS.getNode()) {
1293 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
1298 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1299 N->getOperand(2),
N->getOperand(3),
1300 DAG.getCondCode(CCCode)),
1305 bool IsStrict =
N->isStrictFPOpcode();
1313 SDValue NewLHS = GetSoftenedFloat(Op0);
1314 SDValue NewRHS = GetSoftenedFloat(Op1);
1315 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1322 NewRHS, DAG.getCondCode(CCCode));
1324 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1325 DAG.getCondCode(CCCode)), 0);
1330 "Unexpected setcc expansion!");
1333 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1334 ReplaceValueWith(
SDValue(
N, 1), Chain);
1340SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1342 assert(OpNo == 1 &&
"Can only soften the stored value!");
1347 if (
ST->isTruncatingStore())
1349 Val = BitConvertToInteger(
1351 DAG.getIntPtrConstant(0, dl,
true)));
1353 Val = GetSoftenedFloat(Val);
1359 return DAG.getTruncStore(
ST->getChain(), dl, Val,
ST->getBasePtr(), MemVT,
1360 ST->getMemOperand());
1363SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1364 assert(OpNo == 1 &&
"Can only soften the stored value!");
1370 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1372 SDValue NewVal = GetSoftenedFloat(Val);
1374 ST->getBasePtr(),
ST->getMemOperand());
1379 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1382 EVT LVT =
LHS.getValueType();
1384 EVT RVT =
RHS.getValueType();
1390 int SizeDiff = RSize - LSize;
1394 DAG.getConstant(SizeDiff, dl,
1395 TLI.getShiftAmountTy(
RHS.getValueType(),
1396 DAG.getDataLayout())));
1398 }
else if (SizeDiff < 0) {
1402 DAG.getConstant(-SizeDiff, dl,
1403 TLI.getShiftAmountTy(
RHS.getValueType(),
1404 DAG.getDataLayout())));
1407 RHS = DAG.getBitcast(LVT,
RHS);
1411SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1412 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1413 bool IsStrict =
N->isStrictFPOpcode();
1414 unsigned Offset = IsStrict ? 1 : 0;
1417 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1418 if (LCImpl == RTLIB::Unsupported) {
1419 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
1420 N->getOperationName(&DAG));
1423 ReplaceValueWith(
SDValue(
N, 1), Chain);
1429 TargetLowering::MakeLibCallOptions CallOptions;
1430 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1432 std::pair<SDValue, SDValue> Tmp =
1433 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
1435 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1436 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1444 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1450 RTLIB::LROUND_PPCF128));
1454 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1459 RTLIB::LLROUND_F128,
1460 RTLIB::LLROUND_PPCF128));
1464 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1470 RTLIB::LRINT_PPCF128));
1474 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1480 RTLIB::LLRINT_PPCF128));
1484 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1485 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1486 N->getOperand(0), Op1);
1489SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1492 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1493 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1496SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1499 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1500 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1511void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1517 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1520 switch (
N->getOpcode()) {
1523 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1524 N->dump(&DAG);
dbgs() <<
"\n";
1639 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1641 "Do not know how to expand this float constant!");
1645 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1646 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1649void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1651 bool IsStrict =
N->isStrictFPOpcode();
1652 unsigned Offset = IsStrict ? 1 : 0;
1655 TargetLowering::MakeLibCallOptions CallOptions;
1656 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1657 Op, CallOptions, SDLoc(
N),
1660 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1661 GetPairElements(Tmp.first,
Lo,
Hi);
1664void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1666 bool IsStrict =
N->isStrictFPOpcode();
1667 unsigned Offset = IsStrict ? 1 : 0;
1670 TargetLowering::MakeLibCallOptions CallOptions;
1671 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC,
N->getValueType(0),
1672 Ops, CallOptions, SDLoc(
N),
1675 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1676 GetPairElements(Tmp.first,
Lo,
Hi);
1679void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1680 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(
N->getValueType(0)),
1684void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1685 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(
N->getValueType(0)));
1688void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1689 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1690 RTLIB::getSINCOSPI(
N->getValueType(0)));
1693void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1694 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1695 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1697 TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo);
1700 GetPairElements(Res,
Lo,
Hi);
1707 assert(
N->getValueType(0) == MVT::ppcf128 &&
1708 "Logic only correct for ppcf128!");
1711 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1714 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1721 ExpandFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)),
Lo,
Hi);
1726 ExpandFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)),
Lo,
Hi);
1731 ExpandFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1736 ExpandFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1742 RTLIB::ADD_F32, RTLIB::ADD_F64,
1743 RTLIB::ADD_F80, RTLIB::ADD_F128,
1744 RTLIB::ADD_PPCF128),
Lo,
Hi);
1749 ExpandFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)),
Lo,
Hi);
1754 ExpandFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)),
Lo,
Hi);
1759 ExpandFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)),
Lo,
Hi);
1764 ExpandFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)),
Lo,
Hi);
1769 ExpandFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)),
Lo,
Hi);
1772void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1774 ExpandFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)),
Lo,
Hi);
1777void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1779 ExpandFloatRes_Binary(
N, RTLIB::getCOPYSIGN(
N->getValueType(0)),
Lo,
Hi);
1782void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1784 ExpandFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)),
Lo,
Hi);
1789 ExpandFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)),
Lo,
Hi);
1799 RTLIB::DIV_PPCF128),
Lo,
Hi);
1802void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1804 ExpandFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)),
Lo,
Hi);
1807void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1809 ExpandFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)),
Lo,
Hi);
1814 ExpandFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)),
Lo,
Hi);
1817void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1819 ExpandFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)),
Lo,
Hi);
1822void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1824 ExpandFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)),
Lo,
Hi);
1827void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1829 ExpandFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)),
Lo,
Hi);
1832void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1834 ExpandFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)),
Lo,
Hi);
1839 bool IsStrict =
N->isStrictFPOpcode();
1840 unsigned Offset = IsStrict ? 1 : 0;
1844 TargetLowering::MakeLibCallOptions CallOptions;
1845 std::pair<SDValue, SDValue> Tmp =
1846 TLI.makeLibCall(DAG, RTLIB::getFMA(
N->getValueType(0)),
1847 N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1849 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1850 GetPairElements(Tmp.first,
Lo,
Hi);
1860 RTLIB::MUL_PPCF128),
Lo,
Hi);
1863void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1865 ExpandFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)),
Lo,
Hi);
1871 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1876void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1880 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1885 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1887 bool IsStrict =
N->isStrictFPOpcode();
1892 if (NVT ==
N->getOperand(1).getValueType()) {
1893 Hi =
N->getOperand(1);
1898 {
N->getOperand(0),
N->getOperand(1) });
1908 ReplaceValueWith(
SDValue(
N, 1), Chain);
1911void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1913 ExpandFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)),
Lo,
Hi);
1916void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1918 ExpandFloatRes_Binary(
N, RTLIB::getPOWI(
N->getValueType(0)),
Lo,
Hi);
1923 ExpandFloatRes_Binary(
N, RTLIB::getLDEXP(
N->getValueType(0)),
Lo,
Hi);
1926void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1928 assert(
N->getValueType(0) == MVT::ppcf128 &&
1929 "Logic only correct for ppcf128!");
1932 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1937void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1939 ExpandFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)),
Lo,
Hi);
1942void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1944 ExpandFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)),
Lo,
Hi);
1947void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1949 ExpandFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)),
Lo,
Hi);
1952void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1954 ExpandFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)),
Lo,
Hi);
1957void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1959 ExpandFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)),
Lo,
Hi);
1964 ExpandFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)),
Lo,
Hi);
1967void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1969 ExpandFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)),
Lo,
Hi);
1979 RTLIB::SUB_PPCF128),
Lo,
Hi);
1984 ExpandFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)),
Lo,
Hi);
1989 ExpandFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)),
Lo,
Hi);
1992void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
1994 ExpandFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)),
Lo,
Hi);
2000 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2010 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2012 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2014 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2015 LD->getMemoryVT(),
LD->getMemOperand());
2025 ReplaceValueWith(
SDValue(LD, 1), Chain);
2030 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2031 EVT VT =
N->getValueType(0);
2032 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2033 bool Strict =
N->isStrictFPOpcode();
2035 EVT SrcVT = Src.getValueType();
2043 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2048 if (SrcVT.
bitsLE(MVT::i32)) {
2052 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2053 {Chain, Src}, Flags);
2056 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2058 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2059 if (SrcVT.
bitsLE(MVT::i64)) {
2062 LC = RTLIB::SINTTOFP_I64_PPCF128;
2063 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2065 LC = RTLIB::SINTTOFP_I128_PPCF128;
2067 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2069 TargetLowering::MakeLibCallOptions CallOptions;
2071 std::pair<SDValue, SDValue> Tmp =
2072 TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
2075 GetPairElements(Tmp.first,
Lo,
Hi);
2081 ReplaceValueWith(
SDValue(
N, 1), Chain);
2091 SrcVT = Src.getValueType();
2094 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2095 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2096 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2097 ArrayRef<uint64_t> Parts;
2114 SDValue NewLo = DAG.getConstantFP(
2118 {Chain, Hi, NewLo}, Flags);
2120 ReplaceValueWith(
SDValue(
N, 1), Chain);
2123 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2125 GetPairElements(
Lo,
Lo,
Hi);
2137bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2142 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2145 switch (
N->getOpcode()) {
2148 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2149 N->dump(&DAG);
dbgs() <<
"\n";
2157 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2165 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2167 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2168 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2172 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2178 if (!Res.
getNode())
return false;
2186 "Invalid operand expansion");
2188 ReplaceValueWith(
SDValue(
N, 0), Res);
2194void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2199 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2200 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2201 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2210 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2211 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2214 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2215 RHSLo, CCCode, OutputChain, IsSignaling);
2219 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2222 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2223 RHSHi, CCCode, OutputChain, IsSignaling);
2228 Chain = OutputChain;
2235 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2240 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2245 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2246 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2247 N->getOperand(4)), 0);
2251 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2252 "Logic only correct for ppcf128!");
2254 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2258 N->getValueType(0),
N->getOperand(0),
Hi);
2262 bool IsStrict =
N->isStrictFPOpcode();
2263 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2264 "Logic only correct for ppcf128!");
2266 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2271 N->getValueType(0),
Hi,
N->getOperand(1));
2275 if (
Hi.getValueType() ==
N->getValueType(0)) {
2277 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2283 {
N->getValueType(0), MVT::Other},
2284 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2291 EVT RVT =
N->getValueType(0);
2294 bool IsStrict =
N->isStrictFPOpcode();
2297 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2303 "Unsupported FP_TO_XINT!");
2304 TargetLowering::MakeLibCallOptions CallOptions;
2305 std::pair<SDValue, SDValue> Tmp =
2306 TLI.makeLibCall(DAG, LC, NVT,
Op, CallOptions, dl, Chain);
2310 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2311 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2319 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2324 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2329 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2330 N->getOperand(2),
N->getOperand(3),
2331 DAG.getCondCode(CCCode)), 0);
2335 bool IsStrict =
N->isStrictFPOpcode();
2341 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2347 "Unexpected setcc expansion!");
2349 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2350 ReplaceValueWith(
SDValue(
N, 1), Chain);
2356SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2358 return ExpandOp_NormalStore(
N, OpNo);
2361 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2367 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2368 ST->getValue().getValueType());
2370 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2374 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2376 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2377 ST->getMemoryVT(),
ST->getMemOperand());
2381 RTLIB::Libcall LC) {
2382 EVT RVT =
N->getValueType(0);
2383 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2384 if (LCImpl == RTLIB::Unsupported) {
2385 DAG.getContext()->emitError(Twine(
"no libcall available for ") +
2386 N->getOperationName(&DAG));
2387 return DAG.getPOISON(RVT);
2390 TargetLowering::MakeLibCallOptions CallOptions;
2392 .makeLibCall(DAG, LCImpl, RVT,
N->getOperand(0), CallOptions, SDLoc(
N))
2398 return ExpandFloatOp_XRINT_XROUND(
2399 N,
GetFPLibCall(RetVT, RTLIB::LROUND_F32, RTLIB::LROUND_F64,
2400 RTLIB::LROUND_F80, RTLIB::LROUND_F128,
2401 RTLIB::LROUND_PPCF128));
2405 EVT RetVT =
N->getOperand(0).getValueType();
2406 return ExpandFloatOp_XRINT_XROUND(
2407 N,
GetFPLibCall(RetVT, RTLIB::LLROUND_F32, RTLIB::LLROUND_F64,
2408 RTLIB::LLROUND_F80, RTLIB::LLROUND_F128,
2409 RTLIB::LLROUND_PPCF128));
2413 EVT RetVT =
N->getOperand(0).getValueType();
2414 return ExpandFloatOp_XRINT_XROUND(
2416 GetFPLibCall(RetVT, RTLIB::LRINT_F32, RTLIB::LRINT_F64, RTLIB::LRINT_F80,
2417 RTLIB::LRINT_F128, RTLIB::LRINT_PPCF128));
2421 EVT RetVT =
N->getOperand(0).getValueType();
2422 return ExpandFloatOp_XRINT_XROUND(
2423 N,
GetFPLibCall(RetVT, RTLIB::LLRINT_F32, RTLIB::LLRINT_F64,
2424 RTLIB::LLRINT_F80, RTLIB::LLRINT_F128,
2425 RTLIB::LLRINT_PPCF128));
2434 if (OpVT == MVT::f16)
2436 if (RetVT == MVT::f16)
2438 if (OpVT == MVT::bf16)
2440 if (RetVT == MVT::bf16)
2446 if (OpVT == MVT::f16)
2448 if (RetVT == MVT::f16)
2450 if (OpVT == MVT::bf16)
2452 if (RetVT == MVT::bf16)
2466 DAG.getVTList(CastVT, MVT::Other),
2467 { AM->getChain(), AM->getBasePtr(), CastVal },
2483void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2484 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2489 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2494 switch (
N->getOpcode()) {
2497 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2498 N->dump(&DAG);
dbgs() <<
"\n";
2504 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2508 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2541 R = SoftPromoteHalfRes_FABS(
N);
2544 R = SoftPromoteHalfRes_FNEG(
N);
2547 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2563 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2566 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2576 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2579 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2581 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2590 R = SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
N);
2593 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2603 R = SoftPromoteHalfRes_VECREDUCE(
N);
2607 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2612 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
2615SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2617 BitConvertToInteger(
N->getOperand(0)));
2621 return BitConvertToInteger(
N->getOperand(0));
2624SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2632SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2633 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2639SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2640 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
2641 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
2644 EVT LVT =
LHS.getValueType();
2645 EVT RVT =
RHS.getValueType();
2652 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2653 DAG.getConstant(RSize - 1, dl,
2654 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2662 DAG.getConstant(SizeDiff, dl,
2664 DAG.getDataLayout())));
2666 }
else if (SizeDiff < 0) {
2670 DAG.getConstant(-SizeDiff, dl,
2672 DAG.getDataLayout())));
2677 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2678 DAG.getConstant(LSize - 1, dl,
2679 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2680 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2684 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2689 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2690 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2691 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2692 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2693 SDNodeFlags
Flags =
N->getFlags();
2698 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2699 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2700 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2703 if (OVT == MVT::f16) {
2712 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2723 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2728 EVT OVT =
N->getValueType(0);
2729 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2730 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2744 EVT OVT =
N->getValueType(0);
2745 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2746 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2753 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2761SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2762 EVT OVT =
N->getValueType(0);
2763 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2764 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2773 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2775 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2776 SetSoftPromotedHalf(
SDValue(
N, ResNum), Trunc);
2782SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2783 EVT RVT =
N->getValueType(0);
2784 bool IsStrict =
N->isStrictFPOpcode();
2785 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2786 EVT SVT =
Op.getValueType();
2792 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2795 Op = GetSoftenedFloat(
Op);
2796 TargetLowering::MakeLibCallOptions CallOptions;
2798 std::pair<SDValue, SDValue> Tmp =
2799 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2801 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2802 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2807 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2822 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
2823 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
2824 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
2825 L->getMemOperand()->getFlags(),
L->getAAInfo());
2832SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
2847 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2848 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2849 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1, Op2,
2853SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
2854 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2855 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
2857 N->getOperand(0),
N->getOperand(1), Op2, Op3,
2861SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
2862 EVT OVT =
N->getValueType(0);
2863 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2866 if (
N->isStrictFPOpcode()) {
2867 SDValue Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
2868 {N->getOperand(0), N->getOperand(1)});
2870 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
2871 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
2882DAGTypeLegalizer::SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
2883 EVT OVT =
N->getValueType(0);
2884 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2888 N->getOperand(0),
N->getOperand(1));
2895 return DAG.getUNDEF(MVT::i16);
2899 EVT OVT =
N->getValueType(0);
2900 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2901 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2914 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2918 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
2919 DAG.getConstant(0x7fff, dl, MVT::i16));
2923 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
2927 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
2928 DAG.getConstant(0x8000, dl, MVT::i16));
2931SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
2932 return GetSoftPromotedHalf(
N->getOperand(0));
2936 EVT OVT =
N->getValueType(0);
2937 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2938 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2939 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2944 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2945 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2953SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
2955 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
2959SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
2961 ReplaceValueWith(
SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
2969bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
2970 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
2974 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2984 switch (
N->getOpcode()) {
2987 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
2988 N->dump(&DAG);
dbgs() <<
"\n";
2993 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
2995 Res = SoftPromoteHalfOp_BUILD_VECTOR(
N);
2998 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3001 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3015 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3019 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3021 Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
N);
3025 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3027 Res = SoftPromoteHalfOp_BR_CC(
N);
3029 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3030 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3032 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3035 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3038 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3048 "Invalid operand expansion");
3050 ReplaceValueWith(
SDValue(
N, 0), Res);
3055 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3057 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3060SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BUILD_VECTOR(
SDNode *
N) {
3062 EVT VT =
N->getValueType(0);
3065 for (
unsigned I = 0,
E =
N->getNumOperands();
I !=
E; ++
I)
3066 Ops[
I] = GetSoftPromotedHalf(
N->getOperand(
I));
3069 SDValue Res = DAG.getBuildVector(IVT, dl,
Ops);
3070 return DAG.getBitcast(VT, Res);
3073SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3074 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3075 SDValue Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3076 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3082 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3087 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3089 Op1 = GetSoftPromotedHalf(Op1);
3092 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3096SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3097 EVT RVT =
N->getValueType(0);
3098 bool IsStrict =
N->isStrictFPOpcode();
3099 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3100 EVT SVT =
Op.getValueType();
3101 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3105 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3107 ReplaceValueWith(
SDValue(
N, 0), Res);
3114SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3115 EVT RVT =
N->getValueType(0);
3116 bool IsStrict =
N->isStrictFPOpcode();
3117 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3118 EVT SVT =
Op.getValueType();
3121 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3122 Op = GetSoftPromotedHalf(
Op);
3126 {
N->getOperand(0),
Op});
3127 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3128 {Op.getValue(1), Op});
3129 ReplaceValueWith(
SDValue(
N, 1),
Op.getValue(1));
3135 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3138SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3139 EVT RVT =
N->getValueType(0);
3141 EVT SVT =
Op.getValueType();
3144 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3146 Op = GetSoftPromotedHalf(
Op);
3150 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3157SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
3158 EVT RVT =
N->getValueType(0);
3160 EVT SVT =
Op.getValueType();
3163 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3164 Op = GetSoftPromotedHalf(
Op);
3168 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
3179 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3182 Op0 = GetSoftPromotedHalf(Op0);
3183 Op1 = GetSoftPromotedHalf(Op1);
3187 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3188 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3191 return DAG.getNode(
ISD::BR_CC, dl, MVT::Other,
N->getOperand(0),
3192 N->getOperand(1), Op0, Op1,
N->getOperand(4));
3197 assert(OpNo == 0 &&
"Can only soften the comparison values");
3203 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3205 Op0 = GetSoftPromotedHalf(Op0);
3206 Op1 = GetSoftPromotedHalf(Op1);
3210 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3211 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3214 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3224 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3226 Op0 = GetSoftPromotedHalf(Op0);
3227 Op1 = GetSoftPromotedHalf(Op1);
3231 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3232 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3234 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3237SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3238 assert(OpNo == 1 &&
"Can only soften the stored value!");
3243 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3244 SDValue Promoted = GetSoftPromotedHalf(Val);
3245 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3246 ST->getMemOperand());
3249SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3251 assert(OpNo == 1 &&
"Can only soften the stored value!");
3256 SDValue Promoted = GetSoftPromotedHalf(Val);
3258 ST->getChain(), Promoted,
ST->getBasePtr(),
3259 ST->getMemOperand());
3262SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3266 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3268 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3270 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3281 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3283 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3285 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isSigned(unsigned Opcode)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static RTLIB::Libcall findFPToIntLibcall(EVT SrcVT, EVT RetVT, EVT &Promoted, bool Signed)
static RTLIB::Libcall GetFPLibCall(EVT VT, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128, RTLIB::Libcall Call_PPCF128)
GetFPLibCall - Return the right libcall for the given floating point type.
static ISD::NodeType GetPromotionOpcode(EVT OpVT, EVT RetVT)
static ISD::NodeType GetPromotionOpcodeStrict(EVT OpVT, EVT RetVT)
static const fltSemantics & PPCDoubleDouble()
APInt bitcastToAPInt() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
const SDValue & getVal() const
const APFloat & getValueAPF() const
@ NewNode
This is a new node, not before seen, that was created in the process of legalizing some other node.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOInvariant
The memory access always returns the same value (or traps).
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ FMAD
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ FAKE_USE
FAKE_USE represents a use of the operand but does not do anything.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ CONVERT_FROM_ARBITRARY_FP
CONVERT_FROM_ARBITRARY_FP - This operator converts from an arbitrary floating-point represented as an...
@ SIGN_EXTEND
Conversion operators.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ VECREDUCE_FMAXIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM nodes do not propagate NaNs and order signed zeroes using the llvm....
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ ARITH_FENCE
ARITH_FENCE - This corresponds to a arithmetic fence intrinsic.
@ SHL
Shift and rotation operations.
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ PATCHPOINT
The llvm.experimental.patchpoint.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ BF16_TO_FP
BF16_TO_FP, FP_TO_BF16 - These operators are used to perform promotions and truncation for bfloat16.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ STACKMAP
The llvm.experimental.stackmap intrinsic.
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ CONVERT_TO_ARBITRARY_FP
CONVERT_TO_ARBITRARY_FP - Converts a native FP value to an arbitrary floating-point format,...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
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.
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)