27#define DEBUG_TYPE "legalize-types"
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;
109 case ISD::FMA:
R = SoftenFloatRes_FMA(
N);
break;
176 SetSoftenedFloat(
SDValue(
N, ResNo), R);
181 bool IsStrict =
N->isStrictFPOpcode();
183 unsigned Offset = IsStrict ? 1 : 0;
185 "Unexpected number of operands!");
189 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
191 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT,
Op,
195 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
200 bool IsStrict =
N->isStrictFPOpcode();
202 unsigned Offset = IsStrict ? 1 : 0;
204 "Unexpected number of operands!");
206 GetSoftenedFloat(
N->getOperand(1 +
Offset)) };
209 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
210 N->getOperand(1 +
Offset).getValueType() };
212 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT, Ops,
216 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
221 return BitConvertToInteger(
N->getOperand(0));
227 GetSoftenedFloat(
N->getOperand(0)));
233 GetSoftenedFloat(
N->getOperand(0)));
239 SDValue Op = DisintegrateMERGE_VALUES(
N, ResNo);
240 return BitConvertToInteger(
Op);
248 BitConvertToInteger(
N->getOperand(0)),
249 BitConvertToInteger(
N->getOperand(1)));
265 APInt Val(128, words);
276SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(
SDNode *
N) {
278 assert(Src.getValueType() == MVT::ppcf128 &&
279 "In floats only ppcf128 can be extracted by element!");
281 N->getValueType(0).changeTypeToInteger(),
285SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N,
unsigned ResNo) {
286 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
289 NewOp,
N->getOperand(1));
300 SDValue Op = GetSoftenedFloat(
N->getOperand(0));
306 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
312 RTLIB::FMIN_PPCF128));
317 return SoftenFloatRes_SELECT_CC(SelCC.getNode());
323 RTLIB::FMAX_PPCF128));
332 RTLIB::ADD_PPCF128));
336 return SoftenFloatRes_Unary(
337 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ACOS_F32, RTLIB::ACOS_F64,
338 RTLIB::ACOS_F80, RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128));
342 return SoftenFloatRes_Unary(
343 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ASIN_F32, RTLIB::ASIN_F64,
344 RTLIB::ASIN_F80, RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128));
348 return SoftenFloatRes_Unary(
349 N,
GetFPLibCall(
N->getValueType(0), RTLIB::ATAN_F32, RTLIB::ATAN_F64,
350 RTLIB::ATAN_F80, RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128));
359 RTLIB::CBRT_PPCF128));
368 RTLIB::CEIL_PPCF128));
373 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
376 EVT LVT =
LHS.getValueType();
377 EVT RVT =
RHS.getValueType();
398 }
else if (SizeDiff < 0) {
425 RTLIB::COS_PPCF128));
429 return SoftenFloatRes_Unary(
430 N,
GetFPLibCall(
N->getValueType(0), RTLIB::COSH_F32, RTLIB::COSH_F64,
431 RTLIB::COSH_F80, RTLIB::COSH_F128, RTLIB::COSH_PPCF128));
440 RTLIB::DIV_PPCF128));
449 RTLIB::EXP_PPCF128));
458 RTLIB::EXP2_PPCF128));
462 return SoftenFloatRes_Unary(
464 GetFPLibCall(
N->getValueType(0), RTLIB::EXP10_F32, RTLIB::EXP10_F64,
465 RTLIB::EXP10_F80, RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128));
474 RTLIB::FLOOR_PPCF128));
483 RTLIB::LOG_PPCF128));
492 RTLIB::LOG2_PPCF128));
501 RTLIB::LOG10_PPCF128));
505 bool IsStrict =
N->isStrictFPOpcode();
507 unsigned Offset = IsStrict ? 1 : 0;
509 GetSoftenedFloat(
N->getOperand(1 +
Offset)),
510 GetSoftenedFloat(
N->getOperand(2 +
Offset)) };
513 EVT OpsVT[3] = {
N->getOperand(0 +
Offset).getValueType(),
514 N->getOperand(1 +
Offset).getValueType(),
515 N->getOperand(2 +
Offset).getValueType() };
517 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG,
524 NVT, Ops, CallOptions,
SDLoc(
N), Chain);
526 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
536 RTLIB::MUL_PPCF128));
541 RTLIB::NEARBYINT_F32,
542 RTLIB::NEARBYINT_F64,
543 RTLIB::NEARBYINT_F80,
544 RTLIB::NEARBYINT_F128,
545 RTLIB::NEARBYINT_PPCF128));
559 bool IsStrict =
N->isStrictFPOpcode();
566 Op = GetPromotedFloat(
Op);
569 if (
Op.getValueType() ==
N->getValueType(0)) {
571 ReplaceValueWith(
SDValue(
N, 1), Chain);
572 return BitConvertToInteger(
Op);
580 if ((
Op.getValueType() == MVT::f16 ||
Op.getValueType() == MVT::bf16) &&
581 N->getValueType(0) != MVT::f32) {
584 { MVT::f32, MVT::Other }, { Chain,
Op });
585 Chain =
Op.getValue(1);
591 if (
Op.getValueType() == MVT::bf16) {
593 return SoftenFloatRes_BF16_TO_FP(
N);
597 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
599 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
601 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT,
Op,
605 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
615 EVT OpsVT[1] = {
N->getOperand(0).getValueType() };
618 CallOptions,
SDLoc(
N)).first;
619 if (
N->getValueType(0) == MVT::f32)
624 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_EXTEND!");
631 assert(
N->getValueType(0) == MVT::f32 &&
632 "Can only soften BF16_TO_FP with f32 result");
644 bool IsStrict =
N->isStrictFPOpcode();
649 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND!");
651 EVT OpVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
653 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT,
Op,
657 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
667 RTLIB::POW_PPCF128));
671 bool IsStrict =
N->isStrictFPOpcode();
672 unsigned Offset = IsStrict ? 1 : 0;
673 assert((
N->getOperand(1 +
Offset).getValueType() == MVT::i16 ||
674 N->getOperand(1 +
Offset).getValueType() == MVT::i32) &&
675 "Unsupported power type!");
681 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected fpowi.");
690 N->getOperand(1 +
Offset).getValueType().getSizeInBits()) {
702 EVT OpsVT[2] = {
N->getOperand(0 +
Offset).getValueType(),
703 N->getOperand(1 +
Offset).getValueType() };
705 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT, Ops,
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);
733 SDValue Ops[2] = {GetSoftenedFloat(
N->getOperand(0)), StackSlot};
740 auto [ReturnVal, Chain] = TLI.
makeLibCall(DAG, LC, NVT0, Ops, CallOptions,
DL,
742 int FrameIdx = cast<FrameIndexSDNode>(StackSlot)->getIndex();
748 ReplaceValueWith(
SDValue(
N, 1), LoadExp);
758 RTLIB::REM_PPCF128));
767 RTLIB::RINT_PPCF128));
776 RTLIB::ROUND_PPCF128));
781 RTLIB::ROUNDEVEN_F32,
782 RTLIB::ROUNDEVEN_F64,
783 RTLIB::ROUNDEVEN_F80,
784 RTLIB::ROUNDEVEN_F128,
785 RTLIB::ROUNDEVEN_PPCF128));
794 RTLIB::SIN_PPCF128));
798 return SoftenFloatRes_Unary(
799 N,
GetFPLibCall(
N->getValueType(0), RTLIB::SINH_F32, RTLIB::SINH_F64,
800 RTLIB::SINH_F80, RTLIB::SINH_F128, RTLIB::SINH_PPCF128));
809 RTLIB::SQRT_PPCF128));
818 RTLIB::SUB_PPCF128));
822 return SoftenFloatRes_Unary(
823 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TAN_F32, RTLIB::TAN_F64,
824 RTLIB::TAN_F80, RTLIB::TAN_F128, RTLIB::TAN_PPCF128));
828 return SoftenFloatRes_Unary(
829 N,
GetFPLibCall(
N->getValueType(0), RTLIB::TANH_F32, RTLIB::TANH_F64,
830 RTLIB::TANH_F80, RTLIB::TANH_F128, RTLIB::TANH_PPCF128));
839 RTLIB::TRUNC_PPCF128));
844 EVT VT =
N->getValueType(0);
849 L->getMemOperand()->getFlags() &
853 NewL = DAG.
getLoad(
L->getAddressingMode(),
L->getExtensionType(), NVT, dl,
854 L->getChain(),
L->getBasePtr(),
L->getOffset(),
855 L->getPointerInfo(), NVT,
L->getOriginalAlign(),
856 MMOFlags,
L->getAAInfo());
865 dl,
L->getChain(),
L->getBasePtr(),
L->getOffset(),
866 L->getPointerInfo(),
L->getMemoryVT(),
867 L->getOriginalAlign(), MMOFlags,
L->getAAInfo());
872 return BitConvertToInteger(ExtendNode);
877 EVT VT =
N->getValueType(0);
884 {L->getChain(), L->getBasePtr()},
L->getMemOperand());
899 LHS.getValueType(),
N->getOperand(0), LHS, RHS);
906 LHS.getValueType(),
N->getOperand(0),
907 N->getOperand(1), LHS, RHS,
N->getOperand(4));
912 N->getValueType(0)));
918 EVT VT =
N->getValueType(0);
923 NewVAARG = DAG.
getVAArg(NVT, dl, Chain,
Ptr,
N->getOperand(2),
924 N->getConstantOperandVal(3));
934 bool IsStrict =
N->isStrictFPOpcode();
937 EVT SVT =
N->getOperand(IsStrict ? 1 : 0).getValueType();
938 EVT RVT =
N->getValueType(0);
946 for (
unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
947 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
953 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
958 NVT,
N->getOperand(IsStrict ? 1 : 0));
962 std::pair<SDValue, SDValue> Tmp =
964 Op, CallOptions, dl, Chain);
967 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
977SDValue DAGTypeLegalizer::SoftenFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
986bool DAGTypeLegalizer::SoftenFloatOperand(
SDNode *
N,
unsigned OpNo) {
987 LLVM_DEBUG(
dbgs() <<
"Soften float operand " << OpNo <<
": ";
N->dump(&DAG));
990 switch (
N->getOpcode()) {
993 dbgs() <<
"SoftenFloatOperand Op #" << OpNo <<
": ";
994 N->dump(&DAG);
dbgs() <<
"\n";
999 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(
N);
break;
1012 Res = SoftenFloatOp_FP_TO_XINT_SAT(
N);
break;
1014 case ISD::LROUND: Res = SoftenFloatOp_LROUND(
N);
break;
1018 case ISD::LRINT: Res = SoftenFloatOp_LRINT(
N);
break;
1020 case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(
N);
break;
1024 case ISD::SETCC: Res = SoftenFloatOp_SETCC(
N);
break;
1025 case ISD::STORE: Res = SoftenFloatOp_STORE(
N, OpNo);
break;
1027 Res = SoftenFloatOp_ATOMIC_STORE(
N, OpNo);
1033 if (!Res.
getNode())
return false;
1041 "Invalid operand softening");
1043 ReplaceValueWith(
SDValue(
N, 0), Res);
1048 SDValue Op0 = GetSoftenedFloat(
N->getOperand(0));
1062 bool IsStrict =
N->isStrictFPOpcode();
1063 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1064 EVT SVT =
Op.getValueType();
1065 EVT RVT =
N->getValueType(0);
1069 FloatRVT = MVT::f16;
1072 FloatRVT = MVT::bf16;
1075 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported FP_ROUND libcall");
1078 Op = GetSoftenedFloat(
Op);
1081 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, RVT,
Op,
1085 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1086 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1093 SDValue NewLHS =
N->getOperand(2), NewRHS =
N->getOperand(3);
1094 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(1))->get();
1097 NewLHS = GetSoftenedFloat(NewLHS);
1098 NewRHS = GetSoftenedFloat(NewRHS);
1100 N->getOperand(2),
N->getOperand(3));
1104 if (!NewRHS.getNode()) {
1122 for (
unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
1123 IntVT <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL;
1127 if (Promoted.
bitsGE(RetVT))
1135 bool IsStrict =
N->isStrictFPOpcode();
1139 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
1140 EVT SVT =
Op.getValueType();
1141 EVT RVT =
N->getValueType(0);
1151 "Unsupported FP_TO_XINT!");
1153 Op = GetSoftenedFloat(
Op);
1157 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT,
Op,
1158 CallOptions, dl, Chain);
1166 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1167 ReplaceValueWith(
SDValue(
N, 0), Res);
1171SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(
SDNode *
N) {
1177 SDValue NewLHS =
N->getOperand(0), NewRHS =
N->getOperand(1);
1178 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(4))->get();
1181 NewLHS = GetSoftenedFloat(NewLHS);
1182 NewRHS = GetSoftenedFloat(NewRHS);
1184 N->getOperand(0),
N->getOperand(1));
1188 if (!NewRHS.getNode()) {
1195 N->getOperand(2),
N->getOperand(3),
1201 bool IsStrict =
N->isStrictFPOpcode();
1202 SDValue Op0 =
N->getOperand(IsStrict ? 1 : 0);
1203 SDValue Op1 =
N->getOperand(IsStrict ? 2 : 1);
1206 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
1209 SDValue NewLHS = GetSoftenedFloat(Op0);
1210 SDValue NewRHS = GetSoftenedFloat(Op1);
1226 "Unexpected setcc expansion!");
1229 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
1230 ReplaceValueWith(
SDValue(
N, 1), Chain);
1236SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
1238 assert(OpNo == 1 &&
"Can only soften the stored value!");
1243 if (
ST->isTruncatingStore())
1245 Val = BitConvertToInteger(
1249 Val = GetSoftenedFloat(Val);
1251 return DAG.
getStore(
ST->getChain(), dl, Val,
ST->getBasePtr(),
1252 ST->getMemOperand());
1255SDValue DAGTypeLegalizer::SoftenFloatOp_ATOMIC_STORE(
SDNode *
N,
unsigned OpNo) {
1256 assert(OpNo == 1 &&
"Can only soften the stored value!");
1262 assert(
ST->getMemoryVT() == VT &&
"truncating atomic store not handled");
1264 SDValue NewVal = GetSoftenedFloat(Val);
1266 ST->getBasePtr(),
ST->getMemOperand());
1271 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
1274 EVT LVT =
LHS.getValueType();
1276 EVT RVT =
RHS.getValueType();
1282 int SizeDiff = RSize - LSize;
1290 }
else if (SizeDiff < 0) {
1305 bool IsStrict =
N->isStrictFPOpcode();
1306 unsigned Offset = IsStrict ? 1 : 0;
1310 EVT OpVT =
N->getOperand(0 +
Offset).getValueType();
1312 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC, NVT,
Op,
1316 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1317 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
1325 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1331 RTLIB::LROUND_PPCF128));
1335 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1340 RTLIB::LLROUND_F128,
1341 RTLIB::LLROUND_PPCF128));
1345 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1351 RTLIB::LRINT_PPCF128));
1355 EVT OpVT =
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType();
1361 RTLIB::LLRINT_PPCF128));
1372void DAGTypeLegalizer::ExpandFloatResult(
SDNode *
N,
unsigned ResNo) {
1378 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true))
1381 switch (
N->getOpcode()) {
1384 dbgs() <<
"ExpandFloatResult #" << ResNo <<
": ";
1385 N->dump(&DAG);
dbgs() <<
"\n";
1493 "Do not know how to expand this float constant!");
1494 APInt C = cast<ConstantFPSDNode>(
N)->getValueAPF().bitcastToAPInt();
1497 APInt(64,
C.getRawData()[1])),
1500 APInt(64,
C.getRawData()[0])),
1506 bool IsStrict =
N->isStrictFPOpcode();
1507 unsigned Offset = IsStrict ? 1 : 0;
1511 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC,
N->getValueType(0),
1515 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1516 GetPairElements(Tmp.first,
Lo,
Hi);
1521 bool IsStrict =
N->isStrictFPOpcode();
1522 unsigned Offset = IsStrict ? 1 : 0;
1526 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC,
N->getValueType(0),
1527 Ops, CallOptions,
SDLoc(
N),
1530 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1531 GetPairElements(Tmp.first,
Lo,
Hi);
1536 assert(
N->getValueType(0) == MVT::ppcf128 &&
1537 "Logic only correct for ppcf128!");
1540 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1551 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1552 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1553 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1559 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1560 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1561 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1567 RTLIB::ADD_F32, RTLIB::ADD_F64,
1568 RTLIB::ADD_F80, RTLIB::ADD_F128,
1569 RTLIB::ADD_PPCF128),
Lo,
Hi);
1574 ExpandFloatRes_Unary(
N,
1576 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1577 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1583 ExpandFloatRes_Unary(
N,
1585 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1586 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1592 ExpandFloatRes_Unary(
N,
1594 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1595 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1601 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1602 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1604 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1607void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1610 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1611 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1612 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1615void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1618 RTLIB::COPYSIGN_F32,
1619 RTLIB::COPYSIGN_F64,
1620 RTLIB::COPYSIGN_F80,
1621 RTLIB::COPYSIGN_F128,
1622 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1625void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1628 RTLIB::COS_F32, RTLIB::COS_F64,
1629 RTLIB::COS_F80, RTLIB::COS_F128,
1630 RTLIB::COS_PPCF128),
Lo,
Hi);
1635 ExpandFloatRes_Unary(
N,
1637 RTLIB::COSH_F64, RTLIB::COSH_F80,
1638 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1649 RTLIB::DIV_PPCF128),
Lo,
Hi);
1652void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1655 RTLIB::EXP_F32, RTLIB::EXP_F64,
1656 RTLIB::EXP_F80, RTLIB::EXP_F128,
1657 RTLIB::EXP_PPCF128),
Lo,
Hi);
1660void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1663 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1664 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1665 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1670 ExpandFloatRes_Unary(
N,
1672 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1673 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1677void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1680 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1681 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1682 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1685void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1688 RTLIB::LOG_F32, RTLIB::LOG_F64,
1689 RTLIB::LOG_F80, RTLIB::LOG_F128,
1690 RTLIB::LOG_PPCF128),
Lo,
Hi);
1693void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1696 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1697 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1698 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1701void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1704 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1705 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1706 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1711 bool IsStrict =
N->isStrictFPOpcode();
1712 unsigned Offset = IsStrict ? 1 : 0;
1722 RTLIB::FMA_PPCF128),
1723 N->getValueType(0), Ops, CallOptions,
1726 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1727 GetPairElements(Tmp.first,
Lo,
Hi);
1737 RTLIB::MUL_PPCF128),
Lo,
Hi);
1740void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1743 RTLIB::NEARBYINT_F32,
1744 RTLIB::NEARBYINT_F64,
1745 RTLIB::NEARBYINT_F80,
1746 RTLIB::NEARBYINT_F128,
1747 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
1753 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1762 bool IsStrict =
N->isStrictFPOpcode();
1767 if (NVT ==
N->getOperand(1).getValueType()) {
1768 Hi =
N->getOperand(1);
1769 Chain =
N->getOperand(0);
1773 {
N->getOperand(0),
N->getOperand(1) });
1774 Chain =
Hi.getValue(1);
1784 ReplaceValueWith(
SDValue(
N, 1), Chain);
1787void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1790 RTLIB::POW_F32, RTLIB::POW_F64,
1791 RTLIB::POW_F80, RTLIB::POW_F128,
1792 RTLIB::POW_PPCF128),
Lo,
Hi);
1795void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1805void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1807 assert(
N->getValueType(0) == MVT::ppcf128 &&
1808 "Logic only correct for ppcf128!");
1811 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1816void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1819 RTLIB::REM_F32, RTLIB::REM_F64,
1820 RTLIB::REM_F80, RTLIB::REM_F128,
1821 RTLIB::REM_PPCF128),
Lo,
Hi);
1824void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1827 RTLIB::RINT_F32, RTLIB::RINT_F64,
1828 RTLIB::RINT_F80, RTLIB::RINT_F128,
1829 RTLIB::RINT_PPCF128),
Lo,
Hi);
1832void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1839 RTLIB::ROUND_PPCF128),
Lo,
Hi);
1842void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1845 RTLIB::ROUNDEVEN_F32,
1846 RTLIB::ROUNDEVEN_F64,
1847 RTLIB::ROUNDEVEN_F80,
1848 RTLIB::ROUNDEVEN_F128,
1849 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
1852void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1855 RTLIB::SIN_F32, RTLIB::SIN_F64,
1856 RTLIB::SIN_F80, RTLIB::SIN_F128,
1857 RTLIB::SIN_PPCF128),
Lo,
Hi);
1862 ExpandFloatRes_Unary(
N,
1864 RTLIB::SINH_F64, RTLIB::SINH_F80,
1865 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
1869void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1872 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
1873 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
1874 RTLIB::SQRT_PPCF128),
Lo,
Hi);
1884 RTLIB::SUB_PPCF128),
Lo,
Hi);
1889 ExpandFloatRes_Unary(
N,
1891 RTLIB::TAN_F64, RTLIB::TAN_F80,
1892 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
1898 ExpandFloatRes_Unary(
N,
1900 RTLIB::TANH_F64, RTLIB::TANH_F80,
1901 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
1905void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
1908 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
1909 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
1910 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
1916 ExpandRes_NormalLoad(
N,
Lo,
Hi);
1928 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
1931 LD->getMemoryVT(),
LD->getMemOperand());
1934 Chain =
Hi.getValue(1);
1942 ReplaceValueWith(
SDValue(LD, 1), Chain);
1947 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
1948 EVT VT =
N->getValueType(0);
1950 bool Strict =
N->isStrictFPOpcode();
1951 SDValue Src =
N->getOperand(Strict ? 1 : 0);
1952 EVT SrcVT = Src.getValueType();
1960 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
1965 if (SrcVT.
bitsLE(MVT::i32)) {
1971 {Chain, Src}, Flags);
1972 Chain =
Hi.getValue(1);
1974 Hi = DAG.
getNode(
N->getOpcode(), dl, NVT, Src);
1977 if (SrcVT.
bitsLE(MVT::i64)) {
1980 LC = RTLIB::SINTTOFP_I64_PPCF128;
1981 }
else if (SrcVT.
bitsLE(MVT::i128)) {
1983 LC = RTLIB::SINTTOFP_I128_PPCF128;
1985 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1989 std::pair<SDValue, SDValue> Tmp =
1990 TLI.
makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
1993 GetPairElements(Tmp.first,
Lo,
Hi);
1999 ReplaceValueWith(
SDValue(
N, 1), Chain);
2009 SrcVT = Src.getValueType();
2012 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2013 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2014 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2036 {Chain, Hi, NewLo}, Flags);
2037 Chain =
Lo.getValue(1);
2038 ReplaceValueWith(
SDValue(
N, 1), Chain);
2043 GetPairElements(
Lo,
Lo,
Hi);
2055bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2060 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2063 switch (
N->getOpcode()) {
2066 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2067 N->dump(&DAG);
dbgs() <<
"\n";
2075 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2083 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2085 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2086 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2090 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2091 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(
N),
2096 if (!Res.
getNode())
return false;
2104 "Invalid operand expansion");
2106 ReplaceValueWith(
SDValue(
N, 0), Res);
2112void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2117 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2118 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2119 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2128 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2133 RHSLo, CCCode, OutputChain, IsSignaling);
2141 RHSHi, CCCode, OutputChain, IsSignaling);
2146 Chain = OutputChain;
2150 SDValue NewLHS =
N->getOperand(2), NewRHS =
N->getOperand(3);
2151 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(1))->get();
2153 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain);
2165 N->getOperand(4)), 0);
2169 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2170 "Logic only correct for ppcf128!");
2172 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2176 N->getValueType(0),
N->getOperand(0),
Hi);
2180 bool IsStrict =
N->isStrictFPOpcode();
2181 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2182 "Logic only correct for ppcf128!");
2184 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2189 N->getValueType(0),
Hi,
N->getOperand(1));
2193 if (
Hi.getValueType() ==
N->getValueType(0)) {
2195 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2201 {
N->getValueType(0), MVT::Other},
2202 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2209 EVT RVT =
N->getValueType(0);
2212 bool IsStrict =
N->isStrictFPOpcode();
2215 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2221 "Unsupported FP_TO_XINT!");
2223 std::pair<SDValue, SDValue> Tmp =
2228 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2229 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2234 SDValue NewLHS =
N->getOperand(0), NewRHS =
N->getOperand(1);
2235 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(4))->get();
2237 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain);
2248 N->getOperand(2),
N->getOperand(3),
2253 bool IsStrict =
N->isStrictFPOpcode();
2254 SDValue NewLHS =
N->getOperand(IsStrict ? 1 : 0);
2255 SDValue NewRHS =
N->getOperand(IsStrict ? 2 : 1);
2258 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
2259 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain,
2265 "Unexpected setcc expansion!");
2267 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2268 ReplaceValueWith(
SDValue(
N, 1), Chain);
2274SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2276 return ExpandOp_NormalStore(
N, OpNo);
2279 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2286 ST->getValue().getValueType());
2288 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2292 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2295 ST->getMemoryVT(),
ST->getMemOperand());
2299 EVT RVT =
N->getValueType(0);
2300 EVT RetVT =
N->getOperand(0).getValueType();
2307 RTLIB::LROUND_PPCF128),
2308 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2312 EVT RVT =
N->getValueType(0);
2313 EVT RetVT =
N->getOperand(0).getValueType();
2319 RTLIB::LLROUND_F128,
2320 RTLIB::LLROUND_PPCF128),
2321 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2325 EVT RVT =
N->getValueType(0);
2326 EVT RetVT =
N->getOperand(0).getValueType();
2333 RTLIB::LRINT_PPCF128),
2334 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2338 EVT RVT =
N->getValueType(0);
2339 EVT RetVT =
N->getOperand(0).getValueType();
2346 RTLIB::LLRINT_PPCF128),
2347 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2356 if (OpVT == MVT::f16) {
2358 }
else if (RetVT == MVT::f16) {
2360 }
else if (OpVT == MVT::bf16) {
2362 }
else if (RetVT == MVT::bf16) {
2370 if (OpVT == MVT::f16)
2373 if (RetVT == MVT::f16)
2376 if (OpVT == MVT::bf16)
2379 if (RetVT == MVT::bf16)
2385bool DAGTypeLegalizer::PromoteFloatOperand(
SDNode *
N,
unsigned OpNo) {
2386 LLVM_DEBUG(
dbgs() <<
"Promote float operand " << OpNo <<
": ";
N->dump(&DAG));
2389 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2400 switch (
N->getOpcode()) {
2403 dbgs() <<
"PromoteFloatOperand Op #" << OpNo <<
": ";
2404 N->dump(&DAG);
dbgs() <<
"\n";
2413 case ISD::LLRINT:
R = PromoteFloatOp_UnaryOp(
N, OpNo);
break;
2416 R = PromoteFloatOp_FP_TO_XINT_SAT(
N, OpNo);
break;
2419 R = PromoteFloatOp_STRICT_FP_EXTEND(
N, OpNo);
2422 case ISD::SETCC:
R = PromoteFloatOp_SETCC(
N, OpNo);
break;
2423 case ISD::STORE:
R = PromoteFloatOp_STORE(
N, OpNo);
break;
2429 ReplaceValueWith(
SDValue(
N, 0), R);
2433SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(
SDNode *
N,
unsigned OpNo) {
2435 EVT OpVT =
Op->getValueType(0);
2437 SDValue Promoted = GetPromotedFloat(
N->getOperand(0));
2446 return DAG.
getBitcast(
N->getValueType(0), Convert);
2451SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(
SDNode *
N,
unsigned OpNo) {
2452 assert (OpNo == 1 &&
"Only Operand 1 must need promotion here");
2453 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2456 N->getOperand(0), Op1);
2460SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(
SDNode *
N,
unsigned OpNo) {
2461 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2465SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(
SDNode *
N,
2467 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2472SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(
SDNode *
N,
unsigned OpNo) {
2473 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2474 EVT VT =
N->getValueType(0);
2477 if (VT ==
Op->getValueType(0))
2484SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(
SDNode *
N,
2486 assert(OpNo == 1 &&
"Promoting unpromotable operand");
2488 SDValue Op = GetPromotedFloat(
N->getOperand(1));
2489 EVT VT =
N->getValueType(0);
2492 if (VT ==
Op->getValueType(0)) {
2493 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2499 N->getOperand(0),
Op);
2507SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(
SDNode *
N,
unsigned OpNo) {
2512 LHS, RHS,
N->getOperand(2),
N->getOperand(3),
2518SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(
SDNode *
N,
unsigned OpNo) {
2519 EVT VT =
N->getValueType(0);
2520 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2521 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2522 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(2))->get();
2530SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2535 SDValue Promoted = GetPromotedFloat(Val);
2536 EVT VT =
ST->getOperand(1).getValueType();
2543 return DAG.
getStore(
ST->getChain(),
DL, NewVal,
ST->getBasePtr(),
2544 ST->getMemOperand());
2553 SDValue Promoted = GetPromotedFloat(Val);
2554 EVT VT =
ST->getOperand(1).getValueType();
2561 ST->getBasePtr(),
ST->getMemOperand());
2568void DAGTypeLegalizer::PromoteFloatResult(
SDNode *
N,
unsigned ResNo) {
2569 LLVM_DEBUG(
dbgs() <<
"Promote float result " << ResNo <<
": ";
N->dump(&DAG));
2573 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2578 switch (
N->getOpcode()) {
2585 dbgs() <<
"PromoteFloatResult #" << ResNo <<
": ";
2586 N->dump(&DAG);
dbgs() <<
"\n";
2593 R = PromoteFloatRes_EXTRACT_VECTOR_ELT(
N);
break;
2637 case ISD::FSUB:
R = PromoteFloatRes_BinOp(
N);
break;
2640 case ISD::FMAD:
R = PromoteFloatRes_FMAD(
N);
break;
2648 R = PromoteFloatRes_STRICT_FP_ROUND(
N);
2650 case ISD::LOAD:
R = PromoteFloatRes_LOAD(
N);
break;
2652 R = PromoteFloatRes_ATOMIC_LOAD(
N);
2667 R = PromoteFloatRes_VECREDUCE(
N);
2671 R = PromoteFloatRes_VECREDUCE_SEQ(
N);
2676 SetPromotedFloat(
SDValue(
N, ResNo), R);
2685 EVT VT =
N->getValueType(0);
2690 N->getOperand(0).getValueType().getSizeInBits());
2697 EVT VT =
N->getValueType(0);
2716SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2721 if (isa<ConstantSDNode>(
N->getOperand(1))) {
2729 switch (getTypeAction(VecVT)) {
2732 SDValue Res = GetScalarizedVector(
N->getOperand(0));
2733 ReplaceValueWith(
SDValue(
N, 0), Res);
2737 Vec = GetWidenedVector(Vec);
2739 ReplaceValueWith(
SDValue(
N, 0), Res);
2744 GetSplitVector(Vec,
Lo,
Hi);
2746 uint64_t LoElts =
Lo.getValueType().getVectorNumElements();
2748 if (IdxVal < LoElts)
2753 Idx.getValueType()));
2754 ReplaceValueWith(
SDValue(
N, 0), Res);
2762 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2767 NewOp,
N->getOperand(1));
2770 EVT VT =
N->getValueType(0);
2779 EVT VT =
N->getValueType(0);
2781 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2792 EVT VT =
N->getValueType(0);
2794 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2803 EVT VT =
N->getValueType(0);
2805 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2806 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2807 return DAG.
getNode(
N->getOpcode(),
SDLoc(
N), NVT, Op0, Op1,
N->getFlags());
2811 EVT VT =
N->getValueType(0);
2813 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2814 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2815 SDValue Op2 = GetPromotedFloat(
N->getOperand(2));
2817 return DAG.
getNode(
N->getOpcode(),
SDLoc(
N), NVT, Op0, Op1, Op2);
2822 EVT VT =
N->getValueType(0);
2824 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2831 EVT VT =
N->getValueType(0);
2833 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2847 EVT VT =
N->getValueType(0);
2848 EVT OpVT =
Op->getValueType(0);
2860SDValue DAGTypeLegalizer::PromoteFloatRes_STRICT_FP_ROUND(
SDNode *
N) {
2865 EVT VT =
N->getValueType(0);
2866 EVT OpVT =
Op->getValueType(0);
2883 EVT VT =
N->getValueType(0);
2888 L->getAddressingMode(),
L->getExtensionType(), IVT,
SDLoc(
N),
2889 L->getChain(),
L->getBasePtr(),
L->getOffset(),
L->getPointerInfo(), IVT,
2890 L->getOriginalAlign(),
L->getMemOperand()->getFlags(),
L->getAAInfo());
2900SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD(
SDNode *
N) {
2925 N->getOperand(0), TrueVal, FalseVal);
2935 TrueVal.getNode()->getValueType(0),
N->getOperand(0),
2936 N->getOperand(1), TrueVal, FalseVal,
N->getOperand(4));
2943 EVT VT =
N->getValueType(0);
2955 N->getValueType(0)));
2967SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
2973 EVT VT =
N->getValueType(0);
2984 { AM->getChain(), AM->getBasePtr(), CastVal },
3007void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
3008 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
3013 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
3018 switch (
N->getOpcode()) {
3021 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
3022 N->dump(&DAG);
dbgs() <<
"\n";
3028 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
3032 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
3077 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
3080 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
3087 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
3089 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
3095 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
3103 R = SoftPromoteHalfRes_VECREDUCE(
N);
3107 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
3112 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
3115SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
3117 BitConvertToInteger(
N->getOperand(0)));
3121 return BitConvertToInteger(
N->getOperand(0));
3124SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
3132SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3133 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3139SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
3140 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
3141 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
3144 EVT LVT =
LHS.getValueType();
3145 EVT RVT =
RHS.getValueType();
3166 }
else if (SizeDiff < 0) {
3188 EVT OVT =
N->getValueType(0);
3190 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3191 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3192 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3197 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3198 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3199 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
3208 EVT OVT =
N->getValueType(0);
3210 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3224 EVT OVT =
N->getValueType(0);
3226 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3241SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
3242 EVT RVT =
N->getValueType(0);
3243 EVT SVT =
N->getOperand(0).getValueType();
3245 if (
N->isStrictFPOpcode()) {
3248 if (RVT == MVT::f16)
3250 else if (RVT == MVT::bf16)
3255 {
N->getOperand(0),
N->getOperand(1)});
3270 DAG.
getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
3271 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
3272 L->getPointerInfo(), MVT::i16,
L->getOriginalAlign(),
3273 L->getMemOperand()->getFlags(),
L->getAAInfo());
3280SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3295 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3296 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3301SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3302 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3303 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3305 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3309SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3310 EVT OVT =
N->getValueType(0);
3325 EVT OVT =
N->getValueType(0);
3327 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3340 EVT OVT =
N->getValueType(0);
3342 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3343 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3348 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3349 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3357SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3363SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3373bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3374 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3378 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3388 switch (
N->getOpcode()) {
3391 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3392 N->dump(&DAG);
dbgs() <<
"\n";
3397 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3398 case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
break;
3403 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3406 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3407 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3408 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3410 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3413 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3416 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3426 "Invalid operand expansion");
3428 ReplaceValueWith(
SDValue(
N, 0), Res);
3433 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3440 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3447 Op1 = GetSoftPromotedHalf(Op1);
3450 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3454SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3455 EVT RVT =
N->getValueType(0);
3456 bool IsStrict =
N->isStrictFPOpcode();
3457 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3458 EVT SVT =
Op.getValueType();
3459 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3463 if (SVT == MVT::f16)
3465 else if (SVT == MVT::bf16)
3471 {
N->getOperand(0),
Op});
3473 ReplaceValueWith(
SDValue(
N, 0), Res);
3480SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(
SDNode *
N) {
3481 EVT RVT =
N->getValueType(0);
3483 EVT SVT =
Op.getValueType();
3488 Op = GetSoftPromotedHalf(
Op);
3492 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0), Res);
3495SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3496 EVT RVT =
N->getValueType(0);
3498 EVT SVT =
Op.getValueType();
3503 Op = GetSoftPromotedHalf(
Op);
3507 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3513 assert(OpNo == 0 &&
"Can only soften the comparison values");
3521 Op0 = GetSoftPromotedHalf(Op0);
3522 Op1 = GetSoftPromotedHalf(Op1);
3526 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3527 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3530 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3536 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(2))->get();
3542 Op0 = GetSoftPromotedHalf(Op0);
3543 Op1 = GetSoftPromotedHalf(Op1);
3547 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3548 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3553SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3554 assert(OpNo == 1 &&
"Can only soften the stored value!");
3559 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3560 SDValue Promoted = GetSoftPromotedHalf(Val);
3561 return DAG.
getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3562 ST->getMemOperand());
3565SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3567 assert(OpNo == 1 &&
"Can only soften the stored value!");
3572 SDValue Promoted = GetSoftPromotedHalf(Val);
3574 ST->getChain(), Promoted,
ST->getBasePtr(),
3575 ST->getMemOperand());
3578SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3582 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3586 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3597 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3601 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static bool isSigned(unsigned int Opcode)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an SDNode representing atomic operations.
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.
This class represents an Operation in the Expression.
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
This class is used to represent ISD::LOAD nodes.
@ 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 a MachineMemOperand object describing the memory reference performed by operation.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
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.
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue SV, unsigned Align)
VAArg produces a result and token chain, and takes a pointer and a source value as input.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
static const fltSemantics & EVTToAPFloatSemantics(EVT VT)
Returns an APFloat semantics tag appropriate for the given type.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
const TargetLibraryInfo & getLibInfo() const
MachineFunction & getMachineFunction() const
SDValue getCondCode(ISD::CondCode Cond)
LLVMContext * getContext() const
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
unsigned getIntSize() const
Get size of a C-level int or unsigned int, in bits.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
virtual EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
const char * getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue expandVecReduceSeq(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_SEQ_* into an explicit ordered calculation.
SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const
Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const
Expand a VECREDUCE_* into an explicit calculation.
SDValue createSelectForFMINNUM_FMAXNUM(SDNode *Node, SelectionDAG &DAG) const
Try to convert the fminnum/fmaxnum to a compare/select sequence.
#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.
@ C
The default llvm calling convention, compatible with C.
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.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) 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.
@ 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...
@ 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.
@ SIGN_EXTEND
Conversion operators.
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.