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));
59 SDValue
R = SDValue();
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!");
215 SDValue
Op = GetSoftenedFloat(
N->getOperand(0 +
Offset));
216 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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!");
236 SDValue
Ops[2] = { GetSoftenedFloat(
N->getOperand(0 +
Offset)),
237 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
238 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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) {
310 SDValue Src =
N->getOperand(0);
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));
332 SDValue
Mask = DAG.getConstant(API, SDLoc(
N), NVT);
333 SDValue
Op = GetSoftenedFloat(
N->getOperand(0));
334 return DAG.getNode(
ISD::AND, SDLoc(
N), NVT,
Op, Mask);
337SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE(
SDNode *
N) {
349 SDValue Operand =
N->getOperand(0);
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)));
424 SDValue
LHS = GetSoftenedFloat(
N->getOperand(0));
425 SDValue
RHS = BitConvertToInteger(
N->getOperand(1));
428 EVT LVT =
LHS.getValueType();
429 EVT RVT =
RHS.getValueType();
435 SDValue SignBit = DAG.getNode(
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())));
460 SDValue
Mask = DAG.getNode(
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;
520 SDValue
Ops[3] = { GetSoftenedFloat(
N->getOperand(0 +
Offset)),
521 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
522 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
523 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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));
566 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
568 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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);
614 SDValue
Op =
N->getOperand(0);
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);
635 SDValue
Op =
N->getOperand(0);
640 DAG.getShiftAmountConstant(16, NVT,
DL));
645 bool IsStrict =
N->isStrictFPOpcode();
646 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
647 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
648 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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);
698 SDValue
Ops[2] = { GetSoftenedFloat(
N->getOperand(0 +
Offset)),
700 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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);
833 SDValue SoftSin, SoftCos;
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");
858 SDValue
Poison = DAG.getPOISON(NVT);
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,
933 ReplaceValueWith(SDValue(
N, 1), NewL.
getValue(1));
939 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
940 L->getPointerInfo(),
L->getMemoryVT(),
L->getBaseAlign(),
941 MMOFlags,
L->getAAInfo());
944 ReplaceValueWith(SDValue(
N, 1), NewL.
getValue(1));
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());
962 ReplaceValueWith(SDValue(
N, 1), NewL.
getValue(1));
970 SDValue
LHS = GetSoftenedFloat(
N->getOperand(1));
971 SDValue
RHS = GetSoftenedFloat(
N->getOperand(2));
972 return DAG.getSelect(SDLoc(
N),
973 LHS.getValueType(),
N->getOperand(0),
LHS,
RHS);
977 SDValue
LHS = GetSoftenedFloat(
N->getOperand(2));
978 SDValue
RHS = GetSoftenedFloat(
N->getOperand(3));
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));
1003 ReplaceValueWith(SDValue(
N, 1), NewVAARG.
getValue(1));
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);
1034 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
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));
1066 SDValue Res = SDValue();
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");
1164 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1165 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1166 if (LCImpl == RTLIB::Unsupported) {
1168 SDValue
Poison = DAG.getPOISON(RVT);
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!");
1250 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1251 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1252 if (LCImpl == RTLIB::Unsupported) {
1254 SDValue
Poison = DAG.getPOISON(RVT);
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();
1313 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1318 SDValue NewLHS = GetSoftenedFloat(Op0);
1319 SDValue NewRHS = GetSoftenedFloat(Op1);
1320 TLI.softenSetCCOperands(DAG, VT, NewLHS, NewRHS, CCCode, SDLoc(
N), Op0, Op1,
1327 NewRHS, DAG.getCondCode(CCCode));
1329 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
1330 DAG.getCondCode(CCCode)), 0);
1335 "Unexpected setcc expansion!");
1338 ReplaceValueWith(SDValue(
N, 0), NewLHS);
1339 ReplaceValueWith(SDValue(
N, 1), Chain);
1345SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1347 assert(OpNo == 1 &&
"Can only soften the stored value!");
1349 SDValue Val =
ST->getValue();
1352 if (
ST->isTruncatingStore())
1354 Val = BitConvertToInteger(
1356 DAG.getIntPtrConstant(0, dl,
true)));
1358 Val = GetSoftenedFloat(Val);
1364 return DAG.getTruncStore(
ST->getChain(), dl, Val,
ST->getBasePtr(), MemVT,
1365 ST->getMemOperand());
1368SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1369 assert(OpNo == 1 &&
"Can only soften the stored value!");
1371 SDValue Val =
ST->getVal();
1375 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1377 SDValue NewVal = GetSoftenedFloat(Val);
1379 ST->getBasePtr(),
ST->getMemOperand());
1383 SDValue
LHS =
N->getOperand(0);
1384 SDValue
RHS = BitConvertToInteger(
N->getOperand(1));
1387 EVT LVT =
LHS.getValueType();
1389 EVT RVT =
RHS.getValueType();
1395 int SizeDiff = RSize - LSize;
1399 DAG.getConstant(SizeDiff, dl,
1400 TLI.getShiftAmountTy(
RHS.getValueType(),
1401 DAG.getDataLayout())));
1403 }
else if (SizeDiff < 0) {
1407 DAG.getConstant(-SizeDiff, dl,
1408 TLI.getShiftAmountTy(
RHS.getValueType(),
1409 DAG.getDataLayout())));
1412 RHS = DAG.getBitcast(LVT,
RHS);
1416SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(
SDNode *
N, RTLIB::Libcall LC) {
1417 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1418 bool IsStrict =
N->isStrictFPOpcode();
1419 unsigned Offset = IsStrict ? 1 : 0;
1420 SDValue
Op = GetSoftenedFloat(
N->getOperand(0 +
Offset));
1421 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1422 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1423 if (LCImpl == RTLIB::Unsupported) {
1425 SDValue
Poison = DAG.getPOISON(
N->getValueType(0));
1427 ReplaceValueWith(SDValue(
N, 1), Chain);
1428 ReplaceValueWith(SDValue(
N, 0),
Poison);
1433 TargetLowering::MakeLibCallOptions CallOptions;
1434 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1436 std::pair<SDValue, SDValue> Tmp =
1437 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, SDLoc(
N), Chain);
1439 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
1440 ReplaceValueWith(SDValue(
N, 0), Tmp.first);
1448 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1454 RTLIB::LROUND_PPCF128));
1458 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1463 RTLIB::LLROUND_F128,
1464 RTLIB::LLROUND_PPCF128));
1468 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1474 RTLIB::LRINT_PPCF128));
1478 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1484 RTLIB::LLRINT_PPCF128));
1488 SDValue Op1 = BitConvertToInteger(
N->getOperand(1));
1489 return DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getValueType(0),
1490 N->getOperand(0), Op1);
1493SDValue DAGTypeLegalizer::SoftenFloatOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
1496 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1497 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1500SDValue DAGTypeLegalizer::SoftenFloatOp_PATCHPOINT(
SDNode *
N,
unsigned OpNo) {
1503 NewOps[OpNo] = GetSoftenedFloat(NewOps[OpNo]);
1504 return SDValue(DAG.UpdateNodeOperands(
N, NewOps), 0);
1515void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1518 Lo =
Hi = SDValue();
1521 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1524 switch (
N->getOpcode()) {
1527 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1528 N->dump(&DAG);
dbgs() <<
"\n";
1638 SetExpandedFloat(SDValue(
N, ResNo),
Lo,
Hi);
1643 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1645 "Do not know how to expand this float constant!");
1649 Lo = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 64)), dl, NVT);
1650 Hi = DAG.getConstantFP(
APFloat(Sem,
C.extractBits(64, 0)), dl, NVT);
1657 if (
N->isStrictFPOpcode())
1658 ReplaceValueWith(SDValue(
N, 1),
N->getOperand(0));
1659 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1660 Lo =
Hi = DAG.getPOISON(NVT);
1663void DAGTypeLegalizer::ExpandFloatRes_Unary(
SDNode *
N, RTLIB::Libcall LC,
1665 bool IsStrict =
N->isStrictFPOpcode();
1666 unsigned Offset = IsStrict ? 1 : 0;
1668 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1669 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1670 if (LCImpl == RTLIB::Unsupported)
1671 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1672 TargetLowering::MakeLibCallOptions CallOptions;
1673 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1674 DAG, LCImpl,
N->getValueType(0),
Op, CallOptions, SDLoc(
N), Chain);
1676 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
1677 GetPairElements(Tmp.first,
Lo,
Hi);
1680void DAGTypeLegalizer::ExpandFloatRes_Binary(
SDNode *
N, RTLIB::Libcall LC,
1682 bool IsStrict =
N->isStrictFPOpcode();
1683 unsigned Offset = IsStrict ? 1 : 0;
1685 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1686 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1687 if (LCImpl == RTLIB::Unsupported)
1688 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1689 TargetLowering::MakeLibCallOptions CallOptions;
1690 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1691 DAG, LCImpl,
N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1693 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
1694 GetPairElements(Tmp.first,
Lo,
Hi);
1697void DAGTypeLegalizer::ExpandFloatRes_FMODF(
SDNode *
N) {
1698 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getMODF(
N->getValueType(0)),
1702void DAGTypeLegalizer::ExpandFloatRes_FSINCOS(
SDNode *
N) {
1703 ExpandFloatRes_UnaryWithTwoFPResults(
N, RTLIB::getSINCOS(
N->getValueType(0)));
1706void DAGTypeLegalizer::ExpandFloatRes_FSINCOSPI(
SDNode *
N) {
1707 ExpandFloatRes_UnaryWithTwoFPResults(
N,
1708 RTLIB::getSINCOSPI(
N->getValueType(0)));
1711void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
1712 SDNode *
N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
1713 assert(!
N->isStrictFPOpcode() &&
"strictfp not implemented");
1715 if (!TLI.expandMultipleResultFPLibCall(DAG, LC,
N,
Results, CallRetResNo)) {
1717 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1718 SDValue
Poison = DAG.getPOISON(NVT);
1719 for (
unsigned ResNo = 0,
E =
N->getNumValues(); ResNo !=
E; ++ResNo)
1725 GetPairElements(Res,
Lo,
Hi);
1726 SetExpandedFloat(SDValue(
N, ResNo),
Lo,
Hi);
1732 assert(
N->getValueType(0) == MVT::ppcf128 &&
1733 "Logic only correct for ppcf128!");
1736 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1739 Lo = DAG.getSelectCC(dl, Tmp,
Hi,
Lo,
1746 ExpandFloatRes_Binary(
N, RTLIB::getFMIN(
N->getValueType(0)),
Lo,
Hi);
1751 ExpandFloatRes_Binary(
N, RTLIB::getFMAX(
N->getValueType(0)),
Lo,
Hi);
1756 ExpandFloatRes_Binary(
N, RTLIB::getFMINIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1761 ExpandFloatRes_Binary(
N, RTLIB::getFMAXIMUM_NUM(
N->getValueType(0)),
Lo,
Hi);
1767 RTLIB::ADD_F32, RTLIB::ADD_F64,
1768 RTLIB::ADD_F80, RTLIB::ADD_F128,
1769 RTLIB::ADD_PPCF128),
Lo,
Hi);
1774 ExpandFloatRes_Unary(
N, RTLIB::getACOS(
N->getValueType(0)),
Lo,
Hi);
1779 ExpandFloatRes_Unary(
N, RTLIB::getASIN(
N->getValueType(0)),
Lo,
Hi);
1784 ExpandFloatRes_Unary(
N, RTLIB::getATAN(
N->getValueType(0)),
Lo,
Hi);
1789 ExpandFloatRes_Binary(
N, RTLIB::getATAN2(
N->getValueType(0)),
Lo,
Hi);
1794 ExpandFloatRes_Unary(
N, RTLIB::getCBRT(
N->getValueType(0)),
Lo,
Hi);
1797void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1799 ExpandFloatRes_Unary(
N, RTLIB::getCEIL(
N->getValueType(0)),
Lo,
Hi);
1802void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1804 ExpandFloatRes_Binary(
N, RTLIB::getCOPYSIGN(
N->getValueType(0)),
Lo,
Hi);
1807void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1809 ExpandFloatRes_Unary(
N, RTLIB::getCOS(
N->getValueType(0)),
Lo,
Hi);
1814 ExpandFloatRes_Unary(
N, RTLIB::getCOSH(
N->getValueType(0)),
Lo,
Hi);
1824 RTLIB::DIV_PPCF128),
Lo,
Hi);
1827void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1829 ExpandFloatRes_Unary(
N, RTLIB::getEXP(
N->getValueType(0)),
Lo,
Hi);
1832void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1834 ExpandFloatRes_Unary(
N, RTLIB::getEXP2(
N->getValueType(0)),
Lo,
Hi);
1839 ExpandFloatRes_Unary(
N, RTLIB::getEXP10(
N->getValueType(0)),
Lo,
Hi);
1842void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1844 ExpandFloatRes_Unary(
N, RTLIB::getFLOOR(
N->getValueType(0)),
Lo,
Hi);
1847void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1849 ExpandFloatRes_Unary(
N, RTLIB::getLOG(
N->getValueType(0)),
Lo,
Hi);
1852void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1854 ExpandFloatRes_Unary(
N, RTLIB::getLOG2(
N->getValueType(0)),
Lo,
Hi);
1857void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1859 ExpandFloatRes_Unary(
N, RTLIB::getLOG10(
N->getValueType(0)),
Lo,
Hi);
1864 bool IsStrict =
N->isStrictFPOpcode();
1865 unsigned Offset = IsStrict ? 1 : 0;
1868 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
1869 RTLIB::Libcall LC = RTLIB::getFMA(
N->getValueType(0));
1870 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
1871 if (LCImpl == RTLIB::Unsupported)
1872 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
1873 TargetLowering::MakeLibCallOptions CallOptions;
1874 std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
1875 DAG, LCImpl,
N->getValueType(0),
Ops, CallOptions, SDLoc(
N), Chain);
1877 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
1878 GetPairElements(Tmp.first,
Lo,
Hi);
1888 RTLIB::MUL_PPCF128),
Lo,
Hi);
1891void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1893 ExpandFloatRes_Unary(
N, RTLIB::getNEARBYINT(
N->getValueType(0)),
Lo,
Hi);
1899 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1904void DAGTypeLegalizer::ExpandFloatRes_AssertNoFPClass(
SDNode *
N,
SDValue &
Lo,
1908 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1913 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
N->getValueType(0));
1915 bool IsStrict =
N->isStrictFPOpcode();
1920 if (NVT ==
N->getOperand(1).getValueType()) {
1921 Hi =
N->getOperand(1);
1926 {
N->getOperand(0),
N->getOperand(1) });
1936 ReplaceValueWith(SDValue(
N, 1), Chain);
1939void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1941 ExpandFloatRes_Binary(
N, RTLIB::getPOW(
N->getValueType(0)),
Lo,
Hi);
1944void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1946 ExpandFloatRes_Binary(
N, RTLIB::getPOWI(
N->getValueType(0)),
Lo,
Hi);
1951 ExpandFloatRes_Binary(
N, RTLIB::getLDEXP(
N->getValueType(0)),
Lo,
Hi);
1954void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1956 assert(
N->getValueType(0) == MVT::ppcf128 &&
1957 "Logic only correct for ppcf128!");
1960 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1965void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1967 ExpandFloatRes_Binary(
N, RTLIB::getREM(
N->getValueType(0)),
Lo,
Hi);
1970void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1972 ExpandFloatRes_Unary(
N, RTLIB::getRINT(
N->getValueType(0)),
Lo,
Hi);
1975void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1977 ExpandFloatRes_Unary(
N, RTLIB::getROUND(
N->getValueType(0)),
Lo,
Hi);
1980void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1982 ExpandFloatRes_Unary(
N, RTLIB::getROUNDEVEN(
N->getValueType(0)),
Lo,
Hi);
1985void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1987 ExpandFloatRes_Unary(
N, RTLIB::getSIN(
N->getValueType(0)),
Lo,
Hi);
1992 ExpandFloatRes_Unary(
N, RTLIB::getSINH(
N->getValueType(0)),
Lo,
Hi);
1995void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1997 ExpandFloatRes_Unary(
N, RTLIB::getSQRT(
N->getValueType(0)),
Lo,
Hi);
2007 RTLIB::SUB_PPCF128),
Lo,
Hi);
2012 ExpandFloatRes_Unary(
N, RTLIB::getTAN(
N->getValueType(0)),
Lo,
Hi);
2017 ExpandFloatRes_Unary(
N, RTLIB::getTANH(
N->getValueType(0)),
Lo,
Hi);
2020void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
2022 ExpandFloatRes_Unary(
N, RTLIB::getTRUNC(
N->getValueType(0)),
Lo,
Hi);
2028 ExpandRes_NormalLoad(
N,
Lo,
Hi);
2034 SDValue Chain =
LD->getChain();
2035 SDValue Ptr =
LD->getBasePtr();
2038 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
LD->getValueType(0));
2040 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2042 Hi = DAG.getExtLoad(
LD->getExtensionType(), dl, NVT, Chain, Ptr,
2043 LD->getMemoryVT(),
LD->getMemOperand());
2053 ReplaceValueWith(SDValue(LD, 1), Chain);
2058 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
2059 EVT VT =
N->getValueType(0);
2060 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2061 bool Strict =
N->isStrictFPOpcode();
2062 SDValue Src =
N->getOperand(
Strict ? 1 : 0);
2063 EVT SrcVT = Src.getValueType();
2071 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
2076 if (SrcVT.
bitsLE(MVT::i32)) {
2080 Hi = DAG.getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, MVT::Other),
2081 {Chain, Src}, Flags);
2084 Hi = DAG.getNode(
N->getOpcode(), dl, NVT, Src);
2086 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
2087 if (SrcVT.
bitsLE(MVT::i64)) {
2090 LC = RTLIB::SINTTOFP_I64_PPCF128;
2091 }
else if (SrcVT.
bitsLE(MVT::i128)) {
2093 LC = RTLIB::SINTTOFP_I128_PPCF128;
2095 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
2097 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2098 if (LCImpl == RTLIB::Unsupported)
2099 return ExpandFloatRes_NoLibcall(
N,
Lo,
Hi);
2101 TargetLowering::MakeLibCallOptions CallOptions;
2103 std::pair<SDValue, SDValue> Tmp =
2104 TLI.makeLibCall(DAG, LCImpl, VT, Src, CallOptions, dl, Chain);
2107 GetPairElements(Tmp.first,
Lo,
Hi);
2113 ReplaceValueWith(SDValue(
N, 1), Chain);
2123 SrcVT = Src.getValueType();
2126 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2127 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2128 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2129 ArrayRef<uint64_t> Parts;
2146 SDValue NewLo = DAG.getConstantFP(
2150 {Chain, Hi, NewLo}, Flags);
2152 ReplaceValueWith(SDValue(
N, 1), Chain);
2155 Lo = DAG.getSelectCC(dl, Src, DAG.getConstant(0, dl, SrcVT),
2157 GetPairElements(
Lo,
Lo,
Hi);
2169bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2171 SDValue Res = SDValue();
2174 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2177 switch (
N->getOpcode()) {
2180 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2181 N->dump(&DAG);
dbgs() <<
"\n";
2189 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2197 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2199 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2200 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2204 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2210 if (!Res.
getNode())
return false;
2218 "Invalid operand expansion");
2220 ReplaceValueWith(SDValue(
N, 0), Res);
2226void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2231 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2232 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2233 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2242 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2243 Tmp1 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2246 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSLo.
getValueType()), LHSLo,
2247 RHSLo, CCCode, OutputChain, IsSignaling);
2251 DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi, RHSHi,
2254 Tmp2 = DAG.getSetCC(dl, getSetCCResultType(LHSHi.
getValueType()), LHSHi,
2255 RHSHi, CCCode, OutputChain, IsSignaling);
2260 Chain = OutputChain;
2267 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2272 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2277 return SDValue(DAG.UpdateNodeOperands(
N,
N->getOperand(0),
2278 DAG.getCondCode(CCCode), NewLHS, NewRHS,
2279 N->getOperand(4)), 0);
2283 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2284 "Logic only correct for ppcf128!");
2286 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2290 N->getValueType(0),
N->getOperand(0),
Hi);
2294 bool IsStrict =
N->isStrictFPOpcode();
2295 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2296 "Logic only correct for ppcf128!");
2298 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2303 N->getValueType(0),
Hi,
N->getOperand(1));
2307 if (
Hi.getValueType() ==
N->getValueType(0)) {
2309 ReplaceValueWith(SDValue(
N, 1),
N->getOperand(0));
2310 ReplaceValueWith(SDValue(
N, 0),
Hi);
2315 {
N->getValueType(0), MVT::Other},
2316 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2317 ReplaceValueWith(SDValue(
N, 1),
Expansion.getValue(1));
2323 EVT RVT =
N->getValueType(0);
2326 bool IsStrict =
N->isStrictFPOpcode();
2329 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
2330 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
2335 "Unsupported FP_TO_XINT!");
2336 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2337 if (LCImpl == RTLIB::Unsupported) {
2339 SDValue
Poison = DAG.getPOISON(RVT);
2341 ReplaceValueWith(SDValue(
N, 1), Chain);
2342 ReplaceValueWith(SDValue(
N, 0),
Poison);
2347 TargetLowering::MakeLibCallOptions CallOptions;
2348 std::pair<SDValue, SDValue> Tmp =
2349 TLI.makeLibCall(DAG, LCImpl, NVT,
Op, CallOptions, dl, Chain);
2353 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
2354 ReplaceValueWith(SDValue(
N, 0), Tmp.first);
2362 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain);
2367 NewRHS = DAG.getConstant(0, SDLoc(
N), NewLHS.
getValueType());
2372 return SDValue(DAG.UpdateNodeOperands(
N, NewLHS, NewRHS,
2373 N->getOperand(2),
N->getOperand(3),
2374 DAG.getCondCode(CCCode)), 0);
2378 bool IsStrict =
N->isStrictFPOpcode();
2381 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
2384 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, SDLoc(
N), Chain,
2390 "Unexpected setcc expansion!");
2392 ReplaceValueWith(SDValue(
N, 0), NewLHS);
2393 ReplaceValueWith(SDValue(
N, 1), Chain);
2399SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2401 return ExpandOp_NormalStore(
N, OpNo);
2404 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2407 SDValue Chain =
ST->getChain();
2408 SDValue Ptr =
ST->getBasePtr();
2410 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
2411 ST->getValue().getValueType());
2413 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2417 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2419 return DAG.getTruncStore(Chain, SDLoc(
N),
Hi, Ptr,
2420 ST->getMemoryVT(),
ST->getMemOperand());
2424 RTLIB::Libcall LC) {
2425 EVT RVT =
N->getValueType(0);
2426 RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
2427 if (LCImpl == RTLIB::Unsupported) {
2429 return DAG.getPOISON(RVT);
2432 TargetLowering::MakeLibCallOptions CallOptions;
2434 .makeLibCall(DAG, LCImpl, RVT,
N->getOperand(0), CallOptions, SDLoc(
N))
2440 return ExpandFloatOp_XRINT_XROUND(
2441 N,
GetFPLibCall(RetVT, RTLIB::LROUND_F32, RTLIB::LROUND_F64,
2442 RTLIB::LROUND_F80, RTLIB::LROUND_F128,
2443 RTLIB::LROUND_PPCF128));
2447 EVT RetVT =
N->getOperand(0).getValueType();
2448 return ExpandFloatOp_XRINT_XROUND(
2449 N,
GetFPLibCall(RetVT, RTLIB::LLROUND_F32, RTLIB::LLROUND_F64,
2450 RTLIB::LLROUND_F80, RTLIB::LLROUND_F128,
2451 RTLIB::LLROUND_PPCF128));
2455 EVT RetVT =
N->getOperand(0).getValueType();
2456 return ExpandFloatOp_XRINT_XROUND(
2458 GetFPLibCall(RetVT, RTLIB::LRINT_F32, RTLIB::LRINT_F64, RTLIB::LRINT_F80,
2459 RTLIB::LRINT_F128, RTLIB::LRINT_PPCF128));
2463 EVT RetVT =
N->getOperand(0).getValueType();
2464 return ExpandFloatOp_XRINT_XROUND(
2465 N,
GetFPLibCall(RetVT, RTLIB::LLRINT_F32, RTLIB::LLRINT_F64,
2466 RTLIB::LLRINT_F80, RTLIB::LLRINT_F128,
2467 RTLIB::LLRINT_PPCF128));
2476 if (OpVT == MVT::f16)
2478 if (RetVT == MVT::f16)
2480 if (OpVT == MVT::bf16)
2482 if (RetVT == MVT::bf16)
2488 if (OpVT == MVT::f16)
2490 if (RetVT == MVT::f16)
2492 if (OpVT == MVT::bf16)
2494 if (RetVT == MVT::bf16)
2503 SDValue CastVal = BitConvertToInteger(AM->
getVal());
2508 DAG.getVTList(CastVT, MVT::Other),
2509 { AM->getChain(), AM->getBasePtr(), CastVal },
2512 SDValue
Result = NewAtomic;
2516 ReplaceValueWith(SDValue(
N, 1), NewAtomic.
getValue(1));
2525void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
2526 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
2528 SDValue
R = SDValue();
2531 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2536 switch (
N->getOpcode()) {
2539 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
2540 N->dump(&DAG);
dbgs() <<
"\n";
2546 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
2550 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
2583 R = SoftPromoteHalfRes_FABS(
N);
2586 R = SoftPromoteHalfRes_FNEG(
N);
2589 R = SoftPromoteHalfRes_AssertNoFPClass(
N);
2605 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
2608 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
2618 R = SoftPromoteHalfRes_UnaryWithTwoFPResults(
N);
2621 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
2623 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
2632 R = SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
N);
2635 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
2645 R = SoftPromoteHalfRes_VECREDUCE(
N);
2649 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
2654 SetSoftPromotedHalf(SDValue(
N, ResNo), R);
2657SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
2659 BitConvertToInteger(
N->getOperand(0)));
2663 return BitConvertToInteger(
N->getOperand(0));
2666SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
2674SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2675 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2681SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
2682 SDValue
LHS = GetSoftPromotedHalf(
N->getOperand(0));
2683 SDValue
RHS = BitConvertToInteger(
N->getOperand(1));
2686 EVT LVT =
LHS.getValueType();
2687 EVT RVT =
RHS.getValueType();
2693 SDValue SignBit = DAG.
getNode(
2694 ISD::SHL, dl, RVT, DAG.getConstant(1, dl, RVT),
2695 DAG.getConstant(RSize - 1, dl,
2696 TLI.getShiftAmountTy(RVT, DAG.getDataLayout())));
2704 DAG.getConstant(SizeDiff, dl,
2706 DAG.getDataLayout())));
2708 }
else if (SizeDiff < 0) {
2712 DAG.getConstant(-SizeDiff, dl,
2714 DAG.getDataLayout())));
2718 SDValue
Mask = DAG.getNode(
2719 ISD::SHL, dl, LVT, DAG.getConstant(1, dl, LVT),
2720 DAG.getConstant(LSize - 1, dl,
2721 TLI.getShiftAmountTy(LVT, DAG.getDataLayout())));
2722 Mask = DAG.getNode(
ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, dl, LVT));
2726 return DAG.getNode(
ISD::OR, dl, LVT,
LHS, SignBit);
2731 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2732 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2733 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2734 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2735 SDNodeFlags
Flags =
N->getFlags();
2740 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2741 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2742 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
2745 if (OVT == MVT::f16) {
2748 SDValue A64 = DAG.getNode(
ISD::FP_EXTEND, dl, MVT::f64, Op0, Flags);
2750 SDValue C64 = DAG.getNode(
ISD::FP_EXTEND, dl, MVT::f64, Op2, Flags);
2754 if (TLI.isFMAFasterThanFMulAndFAdd(DAG.getMachineFunction(), MVT::f64)) {
2757 SDValue
Mul = DAG.getNode(
ISD::FMUL, dl, MVT::f64, A64, B64, Flags);
2765 Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1, Op2, Flags);
2770 EVT OVT =
N->getValueType(0);
2771 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2772 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2779 SDValue Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1);
2786 EVT OVT =
N->getValueType(0);
2787 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2788 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(0));
2794 SDValue Res = DAG.
getNode(
N->getOpcode(), dl,
2795 DAG.getVTList(NVT,
N->getValueType(1)),
Op);
2797 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
2803SDValue DAGTypeLegalizer::SoftPromoteHalfRes_UnaryWithTwoFPResults(
SDNode *
N) {
2804 EVT OVT =
N->getValueType(0);
2805 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2806 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(0));
2811 SDValue Res = DAG.
getNode(
N->getOpcode(), dl, DAG.getVTList(NVT, NVT),
Op);
2815 for (
unsigned ResNum = 0, NumValues =
N->getNumValues(); ResNum < NumValues;
2817 SDValue Trunc = DAG.getNode(Truncate, dl, MVT::i16, Res.
getValue(ResNum));
2818 SetSoftPromotedHalf(SDValue(
N, ResNum), Trunc);
2824SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
2825 EVT RVT =
N->getValueType(0);
2826 bool IsStrict =
N->isStrictFPOpcode();
2827 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
2828 EVT SVT =
Op.getValueType();
2834 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
2836 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
2837 Op = GetSoftenedFloat(
Op);
2838 TargetLowering::MakeLibCallOptions CallOptions;
2840 std::pair<SDValue, SDValue> Tmp =
2841 TLI.makeLibCall(DAG, LC, RVT,
Op, CallOptions, SDLoc(
N), Chain);
2843 ReplaceValueWith(SDValue(
N, 1), Tmp.second);
2844 return DAG.getNode(
ISD::BITCAST, SDLoc(
N), MVT::i16, Tmp.first);
2849 {MVT::i16, MVT::Other}, {
N->getOperand(0),
Op});
2850 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
2864 DAG.getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
2865 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
2866 L->getPointerInfo(), MVT::i16,
L->getBaseAlign(),
2867 L->getMemOperand()->getFlags(),
L->getAAInfo());
2870 ReplaceValueWith(SDValue(
N, 1), NewL.
getValue(1));
2874SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
2878 SDValue NewL = DAG.getAtomic(
2884 ReplaceValueWith(SDValue(
N, 1), NewL.
getValue(1));
2889 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2890 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2891 return DAG.getSelect(SDLoc(
N), Op1.
getValueType(),
N->getOperand(0), Op1, Op2,
2895SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
2896 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
2897 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
2899 N->getOperand(0),
N->getOperand(1), Op2, Op3,
2903SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
2904 EVT OVT =
N->getValueType(0);
2905 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2908 if (
N->isStrictFPOpcode()) {
2909 SDValue
Op = DAG.getNode(
N->getOpcode(), dl, {NVT, MVT::Other},
2910 {N->getOperand(0), N->getOperand(1)});
2912 {MVT::i16, MVT::Other}, {
Op.getValue(1),
Op});
2913 ReplaceValueWith(SDValue(
N, 1),
Op.getValue(1));
2917 SDValue Res = DAG.
getNode(
N->getOpcode(), dl, NVT,
N->getOperand(0));
2924DAGTypeLegalizer::SoftPromoteHalfRes_CONVERT_FROM_ARBITRARY_FP(
SDNode *
N) {
2925 EVT OVT =
N->getValueType(0);
2926 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2930 N->getOperand(0),
N->getOperand(1));
2937 return DAG.getUNDEF(MVT::i16);
2941 EVT OVT =
N->getValueType(0);
2942 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2943 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(0));
2949 SDValue Res = DAG.
getNode(
N->getOpcode(), dl, NVT,
Op);
2956 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(0));
2960 return DAG.getNode(
ISD::AND, dl, MVT::i16,
Op,
2961 DAG.getConstant(0x7fff, dl, MVT::i16));
2965 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(0));
2969 return DAG.getNode(
ISD::XOR, dl, MVT::i16,
Op,
2970 DAG.getConstant(0x8000, dl, MVT::i16));
2973SDValue DAGTypeLegalizer::SoftPromoteHalfRes_AssertNoFPClass(
SDNode *
N) {
2974 return GetSoftPromotedHalf(
N->getOperand(0));
2978 EVT OVT =
N->getValueType(0);
2979 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
2980 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
2981 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
2986 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
2987 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
2989 SDValue Res = DAG.
getNode(
N->getOpcode(), dl, NVT, Op0, Op1);
2995SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
2997 ReplaceValueWith(SDValue(
N, 0), TLI.expandVecReduce(
N, DAG));
3001SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3003 ReplaceValueWith(SDValue(
N, 0), TLI.expandVecReduceSeq(
N, DAG));
3011bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3012 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3014 SDValue Res = SDValue();
3016 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3026 switch (
N->getOpcode()) {
3029 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3030 N->dump(&DAG);
dbgs() <<
"\n";
3035 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3037 Res = SoftPromoteHalfOp_BUILD_VECTOR(
N);
3040 Res = SoftPromoteHalfOp_INSERT_VECTOR_ELT(
N, OpNo);
3043 Res = SoftPromoteHalfOp_FAKE_USE(
N, OpNo);
3046 Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
3060 Res = SoftPromoteHalfOp_Op0WithStrict(
N);
3064 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3066 Res = SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
N);
3070 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3072 Res = SoftPromoteHalfOp_BR_CC(
N);
3074 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3075 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3077 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3080 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3083 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3093 "Invalid operand expansion");
3095 ReplaceValueWith(SDValue(
N, 0), Res);
3100 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3102 return DAG.getNode(
ISD::BITCAST, SDLoc(
N),
N->getValueType(0), Op0);
3105SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BUILD_VECTOR(
SDNode *
N) {
3107 EVT VT =
N->getValueType(0);
3110 for (
unsigned I = 0,
E =
N->getNumOperands();
I !=
E; ++
I)
3111 Ops[
I] = GetSoftPromotedHalf(
N->getOperand(
I));
3114 SDValue Res = DAG.getBuildVector(IVT, dl,
Ops);
3115 return DAG.getBitcast(VT, Res);
3118SDValue DAGTypeLegalizer::SoftPromoteHalfOp_INSERT_VECTOR_ELT(
SDNode *
N,
3120 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3121 SDValue Vec = BitConvertVectorToIntegerVector(
N->getOperand(0));
3122 SDValue Elt = GetSoftPromotedHalf(
N->getOperand(OpNo));
3125 return DAG.getBitcast(
N->getValueType(0), Res);
3128SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FAKE_USE(
SDNode *
N,
unsigned OpNo) {
3129 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3130 SDValue
Op = GetSoftPromotedHalf(
N->getOperand(OpNo));
3131 return DAG.getNode(
N->getOpcode(), SDLoc(
N), MVT::Other,
N->getOperand(0),
3137 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3142 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op1.
getValueType());
3144 Op1 = GetSoftPromotedHalf(Op1);
3147 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3151SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3152 EVT RVT =
N->getValueType(0);
3153 bool IsStrict =
N->isStrictFPOpcode();
3154 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
3155 EVT SVT =
Op.getValueType();
3156 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3160 {RVT, MVT::Other}, {
N->getOperand(0),
Op});
3161 ReplaceValueWith(SDValue(
N, 1), Res.
getValue(1));
3162 ReplaceValueWith(SDValue(
N, 0), Res);
3169SDValue DAGTypeLegalizer::SoftPromoteHalfOp_Op0WithStrict(
SDNode *
N) {
3170 EVT RVT =
N->getValueType(0);
3171 bool IsStrict =
N->isStrictFPOpcode();
3172 SDValue
Op =
N->getOperand(IsStrict ? 1 : 0);
3173 EVT SVT =
Op.getValueType();
3176 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3177 Op = GetSoftPromotedHalf(
Op);
3181 {
N->getOperand(0),
Op});
3182 Op = DAG.getNode(
N->getOpcode(), dl, {RVT, MVT::Other},
3183 {Op.getValue(1), Op});
3184 ReplaceValueWith(SDValue(
N, 1),
Op.getValue(1));
3185 ReplaceValueWith(SDValue(
N, 0),
Op);
3190 return DAG.getNode(
N->getOpcode(), dl, RVT, Res);
3193SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3194 EVT RVT =
N->getValueType(0);
3195 SDValue
Op =
N->getOperand(0);
3196 EVT SVT =
Op.getValueType();
3199 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3201 Op = GetSoftPromotedHalf(
Op);
3205 return DAG.getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3212SDValue DAGTypeLegalizer::SoftPromoteHalfOp_CONVERT_TO_ARBITRARY_FP(
SDNode *
N) {
3213 EVT RVT =
N->getValueType(0);
3214 SDValue
Op =
N->getOperand(0);
3215 EVT SVT =
Op.getValueType();
3218 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(),
Op.getValueType());
3219 Op = GetSoftPromotedHalf(
Op);
3223 N->getOperand(1),
N->getOperand(2),
N->getOperand(3));
3234 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3237 Op0 = GetSoftPromotedHalf(Op0);
3238 Op1 = GetSoftPromotedHalf(Op1);
3242 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3243 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3246 return DAG.getNode(
ISD::BR_CC, dl, MVT::Other,
N->getOperand(0),
3247 N->getOperand(1), Op0, Op1,
N->getOperand(4));
3252 assert(OpNo == 0 &&
"Can only soften the comparison values");
3258 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT);
3260 Op0 = GetSoftPromotedHalf(Op0);
3261 Op1 = GetSoftPromotedHalf(Op1);
3265 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3266 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3269 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3279 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Op0.
getValueType());
3281 Op0 = GetSoftPromotedHalf(Op0);
3282 Op1 = GetSoftPromotedHalf(Op1);
3286 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3287 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3289 return DAG.getSetCC(SDLoc(
N),
N->getValueType(0), Op0, Op1, CCCode);
3292SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3293 assert(OpNo == 1 &&
"Can only soften the stored value!");
3295 SDValue Val =
ST->getValue();
3298 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3299 SDValue Promoted = GetSoftPromotedHalf(Val);
3300 return DAG.getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3301 ST->getMemOperand());
3304SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3306 assert(OpNo == 1 &&
"Can only soften the stored value!");
3308 SDValue Val =
ST->getVal();
3311 SDValue Promoted = GetSoftPromotedHalf(Val);
3313 ST->getChain(), Promoted,
ST->getBasePtr(),
3314 ST->getMemOperand());
3317SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3320 SDValue
Op =
N->getOperand(OpNo);
3321 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3323 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3325 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3326 ReplaceValueWith(SDValue(
N, ResNum),
NewNode.getValue(ResNum));
3335 SDValue
Op =
N->getOperand(OpNo);
3336 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3338 DAG.getNode(
N->getOpcode(), SDLoc(
N),
N->getVTList(), NewOps);
3340 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3341 ReplaceValueWith(SDValue(
N, ResNum),
NewNode.getValue(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.
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 - 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),...
@ 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 - 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.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
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)