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();
1503 bool IsStrict =
N->isStrictFPOpcode();
1504 unsigned Offset = IsStrict ? 1 : 0;
1508 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC,
N->getValueType(0),
1512 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1513 GetPairElements(Tmp.first,
Lo,
Hi);
1518 bool IsStrict =
N->isStrictFPOpcode();
1519 unsigned Offset = IsStrict ? 1 : 0;
1523 std::pair<SDValue, SDValue> Tmp = TLI.
makeLibCall(DAG, LC,
N->getValueType(0),
1524 Ops, CallOptions,
SDLoc(
N),
1527 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1528 GetPairElements(Tmp.first,
Lo,
Hi);
1533 assert(
N->getValueType(0) == MVT::ppcf128 &&
1534 "Logic only correct for ppcf128!");
1537 GetExpandedFloat(
N->getOperand(0),
Lo, Tmp);
1548 RTLIB::FMIN_F32, RTLIB::FMIN_F64,
1549 RTLIB::FMIN_F80, RTLIB::FMIN_F128,
1550 RTLIB::FMIN_PPCF128),
Lo,
Hi);
1556 RTLIB::FMAX_F32, RTLIB::FMAX_F64,
1557 RTLIB::FMAX_F80, RTLIB::FMAX_F128,
1558 RTLIB::FMAX_PPCF128),
Lo,
Hi);
1564 RTLIB::ADD_F32, RTLIB::ADD_F64,
1565 RTLIB::ADD_F80, RTLIB::ADD_F128,
1566 RTLIB::ADD_PPCF128),
Lo,
Hi);
1571 ExpandFloatRes_Unary(
N,
1573 RTLIB::ACOS_F64, RTLIB::ACOS_F80,
1574 RTLIB::ACOS_F128, RTLIB::ACOS_PPCF128),
1580 ExpandFloatRes_Unary(
N,
1582 RTLIB::ASIN_F64, RTLIB::ASIN_F80,
1583 RTLIB::ASIN_F128, RTLIB::ASIN_PPCF128),
1589 ExpandFloatRes_Unary(
N,
1591 RTLIB::ATAN_F64, RTLIB::ATAN_F80,
1592 RTLIB::ATAN_F128, RTLIB::ATAN_PPCF128),
1598 ExpandFloatRes_Unary(
N,
GetFPLibCall(
N->getValueType(0), RTLIB::CBRT_F32,
1599 RTLIB::CBRT_F64, RTLIB::CBRT_F80,
1601 RTLIB::CBRT_PPCF128),
Lo,
Hi);
1604void DAGTypeLegalizer::ExpandFloatRes_FCEIL(
SDNode *
N,
1607 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
1608 RTLIB::CEIL_F80, RTLIB::CEIL_F128,
1609 RTLIB::CEIL_PPCF128),
Lo,
Hi);
1612void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(
SDNode *
N,
1615 RTLIB::COPYSIGN_F32,
1616 RTLIB::COPYSIGN_F64,
1617 RTLIB::COPYSIGN_F80,
1618 RTLIB::COPYSIGN_F128,
1619 RTLIB::COPYSIGN_PPCF128),
Lo,
Hi);
1622void DAGTypeLegalizer::ExpandFloatRes_FCOS(
SDNode *
N,
1625 RTLIB::COS_F32, RTLIB::COS_F64,
1626 RTLIB::COS_F80, RTLIB::COS_F128,
1627 RTLIB::COS_PPCF128),
Lo,
Hi);
1632 ExpandFloatRes_Unary(
N,
1634 RTLIB::COSH_F64, RTLIB::COSH_F80,
1635 RTLIB::COSH_F128, RTLIB::COSH_PPCF128),
1646 RTLIB::DIV_PPCF128),
Lo,
Hi);
1649void DAGTypeLegalizer::ExpandFloatRes_FEXP(
SDNode *
N,
1652 RTLIB::EXP_F32, RTLIB::EXP_F64,
1653 RTLIB::EXP_F80, RTLIB::EXP_F128,
1654 RTLIB::EXP_PPCF128),
Lo,
Hi);
1657void DAGTypeLegalizer::ExpandFloatRes_FEXP2(
SDNode *
N,
1660 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
1661 RTLIB::EXP2_F80, RTLIB::EXP2_F128,
1662 RTLIB::EXP2_PPCF128),
Lo,
Hi);
1667 ExpandFloatRes_Unary(
N,
1669 RTLIB::EXP10_F64, RTLIB::EXP10_F80,
1670 RTLIB::EXP10_F128, RTLIB::EXP10_PPCF128),
1674void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(
SDNode *
N,
1677 RTLIB::FLOOR_F32, RTLIB::FLOOR_F64,
1678 RTLIB::FLOOR_F80, RTLIB::FLOOR_F128,
1679 RTLIB::FLOOR_PPCF128),
Lo,
Hi);
1682void DAGTypeLegalizer::ExpandFloatRes_FLOG(
SDNode *
N,
1685 RTLIB::LOG_F32, RTLIB::LOG_F64,
1686 RTLIB::LOG_F80, RTLIB::LOG_F128,
1687 RTLIB::LOG_PPCF128),
Lo,
Hi);
1690void DAGTypeLegalizer::ExpandFloatRes_FLOG2(
SDNode *
N,
1693 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
1694 RTLIB::LOG2_F80, RTLIB::LOG2_F128,
1695 RTLIB::LOG2_PPCF128),
Lo,
Hi);
1698void DAGTypeLegalizer::ExpandFloatRes_FLOG10(
SDNode *
N,
1701 RTLIB::LOG10_F32, RTLIB::LOG10_F64,
1702 RTLIB::LOG10_F80, RTLIB::LOG10_F128,
1703 RTLIB::LOG10_PPCF128),
Lo,
Hi);
1708 bool IsStrict =
N->isStrictFPOpcode();
1709 unsigned Offset = IsStrict ? 1 : 0;
1719 RTLIB::FMA_PPCF128),
1720 N->getValueType(0), Ops, CallOptions,
1723 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
1724 GetPairElements(Tmp.first,
Lo,
Hi);
1734 RTLIB::MUL_PPCF128),
Lo,
Hi);
1737void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(
SDNode *
N,
1740 RTLIB::NEARBYINT_F32,
1741 RTLIB::NEARBYINT_F64,
1742 RTLIB::NEARBYINT_F80,
1743 RTLIB::NEARBYINT_F128,
1744 RTLIB::NEARBYINT_PPCF128),
Lo,
Hi);
1750 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1759 bool IsStrict =
N->isStrictFPOpcode();
1764 if (NVT ==
N->getOperand(1).getValueType()) {
1765 Hi =
N->getOperand(1);
1766 Chain =
N->getOperand(0);
1770 {
N->getOperand(0),
N->getOperand(1) });
1771 Chain =
Hi.getValue(1);
1780 ReplaceValueWith(
SDValue(
N, 1), Chain);
1783void DAGTypeLegalizer::ExpandFloatRes_FPOW(
SDNode *
N,
1786 RTLIB::POW_F32, RTLIB::POW_F64,
1787 RTLIB::POW_F80, RTLIB::POW_F128,
1788 RTLIB::POW_PPCF128),
Lo,
Hi);
1791void DAGTypeLegalizer::ExpandFloatRes_FPOWI(
SDNode *
N,
1801void DAGTypeLegalizer::ExpandFloatRes_FREEZE(
SDNode *
N,
1803 assert(
N->getValueType(0) == MVT::ppcf128 &&
1804 "Logic only correct for ppcf128!");
1807 GetExpandedFloat(
N->getOperand(0),
Lo,
Hi);
1812void DAGTypeLegalizer::ExpandFloatRes_FREM(
SDNode *
N,
1815 RTLIB::REM_F32, RTLIB::REM_F64,
1816 RTLIB::REM_F80, RTLIB::REM_F128,
1817 RTLIB::REM_PPCF128),
Lo,
Hi);
1820void DAGTypeLegalizer::ExpandFloatRes_FRINT(
SDNode *
N,
1823 RTLIB::RINT_F32, RTLIB::RINT_F64,
1824 RTLIB::RINT_F80, RTLIB::RINT_F128,
1825 RTLIB::RINT_PPCF128),
Lo,
Hi);
1828void DAGTypeLegalizer::ExpandFloatRes_FROUND(
SDNode *
N,
1835 RTLIB::ROUND_PPCF128),
Lo,
Hi);
1838void DAGTypeLegalizer::ExpandFloatRes_FROUNDEVEN(
SDNode *
N,
1841 RTLIB::ROUNDEVEN_F32,
1842 RTLIB::ROUNDEVEN_F64,
1843 RTLIB::ROUNDEVEN_F80,
1844 RTLIB::ROUNDEVEN_F128,
1845 RTLIB::ROUNDEVEN_PPCF128),
Lo,
Hi);
1848void DAGTypeLegalizer::ExpandFloatRes_FSIN(
SDNode *
N,
1851 RTLIB::SIN_F32, RTLIB::SIN_F64,
1852 RTLIB::SIN_F80, RTLIB::SIN_F128,
1853 RTLIB::SIN_PPCF128),
Lo,
Hi);
1858 ExpandFloatRes_Unary(
N,
1860 RTLIB::SINH_F64, RTLIB::SINH_F80,
1861 RTLIB::SINH_F128, RTLIB::SINH_PPCF128),
1865void DAGTypeLegalizer::ExpandFloatRes_FSQRT(
SDNode *
N,
1868 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
1869 RTLIB::SQRT_F80, RTLIB::SQRT_F128,
1870 RTLIB::SQRT_PPCF128),
Lo,
Hi);
1880 RTLIB::SUB_PPCF128),
Lo,
Hi);
1885 ExpandFloatRes_Unary(
N,
1887 RTLIB::TAN_F64, RTLIB::TAN_F80,
1888 RTLIB::TAN_F128, RTLIB::TAN_PPCF128),
1894 ExpandFloatRes_Unary(
N,
1896 RTLIB::TANH_F64, RTLIB::TANH_F80,
1897 RTLIB::TANH_F128, RTLIB::TANH_PPCF128),
1901void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(
SDNode *
N,
1904 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
1905 RTLIB::TRUNC_F80, RTLIB::TRUNC_F128,
1906 RTLIB::TRUNC_PPCF128),
Lo,
Hi);
1912 ExpandRes_NormalLoad(
N,
Lo,
Hi);
1924 assert(
LD->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
1927 LD->getMemoryVT(),
LD->getMemOperand());
1930 Chain =
Hi.getValue(1);
1937 ReplaceValueWith(
SDValue(LD, 1), Chain);
1942 assert(
N->getValueType(0) == MVT::ppcf128 &&
"Unsupported XINT_TO_FP!");
1943 EVT VT =
N->getValueType(0);
1945 bool Strict =
N->isStrictFPOpcode();
1946 SDValue Src =
N->getOperand(Strict ? 1 : 0);
1947 EVT SrcVT = Src.getValueType();
1955 Flags.setNoFPExcept(
N->getFlags().hasNoFPExcept());
1960 if (SrcVT.
bitsLE(MVT::i32)) {
1965 {Chain, Src}, Flags);
1966 Chain =
Hi.getValue(1);
1968 Hi = DAG.
getNode(
N->getOpcode(), dl, NVT, Src);
1971 if (SrcVT.
bitsLE(MVT::i64)) {
1974 LC = RTLIB::SINTTOFP_I64_PPCF128;
1975 }
else if (SrcVT.
bitsLE(MVT::i128)) {
1977 LC = RTLIB::SINTTOFP_I128_PPCF128;
1979 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unsupported XINT_TO_FP!");
1983 std::pair<SDValue, SDValue> Tmp =
1984 TLI.
makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
1987 GetPairElements(Tmp.first,
Lo,
Hi);
1993 ReplaceValueWith(
SDValue(
N, 1), Chain);
2003 SrcVT = Src.getValueType();
2006 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
2007 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
2008 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
2030 {Chain, Hi, NewLo}, Flags);
2031 Chain =
Lo.getValue(1);
2032 ReplaceValueWith(
SDValue(
N, 1), Chain);
2037 GetPairElements(
Lo,
Lo,
Hi);
2049bool DAGTypeLegalizer::ExpandFloatOperand(
SDNode *
N,
unsigned OpNo) {
2054 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false))
2057 switch (
N->getOpcode()) {
2060 dbgs() <<
"ExpandFloatOperand Op #" << OpNo <<
": ";
2061 N->dump(&DAG);
dbgs() <<
"\n";
2069 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(
N);
break;
2077 case ISD::LROUND: Res = ExpandFloatOp_LROUND(
N);
break;
2079 case ISD::LRINT: Res = ExpandFloatOp_LRINT(
N);
break;
2080 case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(
N);
break;
2084 case ISD::SETCC: Res = ExpandFloatOp_SETCC(
N);
break;
2085 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(
N),
2090 if (!Res.
getNode())
return false;
2098 "Invalid operand expansion");
2100 ReplaceValueWith(
SDValue(
N, 0), Res);
2106void DAGTypeLegalizer::FloatExpandSetCCOperands(
SDValue &NewLHS,
2111 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2112 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
2113 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
2122 SDValue Tmp1, Tmp2, Tmp3, OutputChain;
2127 RHSLo, CCCode, OutputChain, IsSignaling);
2135 RHSHi, CCCode, OutputChain, IsSignaling);
2140 Chain = OutputChain;
2144 SDValue NewLHS =
N->getOperand(2), NewRHS =
N->getOperand(3);
2145 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(1))->get();
2147 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain);
2159 N->getOperand(4)), 0);
2163 assert(
N->getOperand(1).getValueType() == MVT::ppcf128 &&
2164 "Logic only correct for ppcf128!");
2166 GetExpandedFloat(
N->getOperand(1),
Lo,
Hi);
2170 N->getValueType(0),
N->getOperand(0),
Hi);
2174 bool IsStrict =
N->isStrictFPOpcode();
2175 assert(
N->getOperand(IsStrict ? 1 : 0).getValueType() == MVT::ppcf128 &&
2176 "Logic only correct for ppcf128!");
2178 GetExpandedFloat(
N->getOperand(IsStrict ? 1 : 0),
Lo,
Hi);
2183 N->getValueType(0),
Hi,
N->getOperand(1));
2187 if (
Hi.getValueType() ==
N->getValueType(0)) {
2189 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2195 {
N->getValueType(0), MVT::Other},
2196 {
N->getOperand(0),
Hi,
N->getOperand(2)});
2203 EVT RVT =
N->getValueType(0);
2206 bool IsStrict =
N->isStrictFPOpcode();
2209 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
2215 "Unsupported FP_TO_XINT!");
2217 std::pair<SDValue, SDValue> Tmp =
2222 ReplaceValueWith(
SDValue(
N, 1), Tmp.second);
2223 ReplaceValueWith(
SDValue(
N, 0), Tmp.first);
2228 SDValue NewLHS =
N->getOperand(0), NewRHS =
N->getOperand(1);
2229 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(4))->get();
2231 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain);
2242 N->getOperand(2),
N->getOperand(3),
2247 bool IsStrict =
N->isStrictFPOpcode();
2248 SDValue NewLHS =
N->getOperand(IsStrict ? 1 : 0);
2249 SDValue NewRHS =
N->getOperand(IsStrict ? 2 : 1);
2252 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
2253 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode,
SDLoc(
N), Chain,
2259 "Unexpected setcc expansion!");
2261 ReplaceValueWith(
SDValue(
N, 0), NewLHS);
2262 ReplaceValueWith(
SDValue(
N, 1), Chain);
2268SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2270 return ExpandOp_NormalStore(
N, OpNo);
2273 assert(OpNo == 1 &&
"Can only expand the stored value so far");
2280 ST->getValue().getValueType());
2282 assert(
ST->getMemoryVT().bitsLE(NVT) &&
"Float type not round?");
2286 GetExpandedOp(
ST->getValue(),
Lo,
Hi);
2289 ST->getMemoryVT(),
ST->getMemOperand());
2293 EVT RVT =
N->getValueType(0);
2294 EVT RetVT =
N->getOperand(0).getValueType();
2301 RTLIB::LROUND_PPCF128),
2302 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2306 EVT RVT =
N->getValueType(0);
2307 EVT RetVT =
N->getOperand(0).getValueType();
2313 RTLIB::LLROUND_F128,
2314 RTLIB::LLROUND_PPCF128),
2315 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2319 EVT RVT =
N->getValueType(0);
2320 EVT RetVT =
N->getOperand(0).getValueType();
2327 RTLIB::LRINT_PPCF128),
2328 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2332 EVT RVT =
N->getValueType(0);
2333 EVT RetVT =
N->getOperand(0).getValueType();
2340 RTLIB::LLRINT_PPCF128),
2341 RVT,
N->getOperand(0), CallOptions,
SDLoc(
N)).first;
2350 if (OpVT == MVT::f16) {
2352 }
else if (RetVT == MVT::f16) {
2354 }
else if (OpVT == MVT::bf16) {
2356 }
else if (RetVT == MVT::bf16) {
2364 if (OpVT == MVT::f16)
2367 if (RetVT == MVT::f16)
2370 if (OpVT == MVT::bf16)
2373 if (RetVT == MVT::bf16)
2379bool DAGTypeLegalizer::PromoteFloatOperand(
SDNode *
N,
unsigned OpNo) {
2380 LLVM_DEBUG(
dbgs() <<
"Promote float operand " << OpNo <<
": ";
N->dump(&DAG));
2383 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
2394 switch (
N->getOpcode()) {
2397 dbgs() <<
"PromoteFloatOperand Op #" << OpNo <<
": ";
2398 N->dump(&DAG);
dbgs() <<
"\n";
2407 case ISD::LLRINT:
R = PromoteFloatOp_UnaryOp(
N, OpNo);
break;
2410 R = PromoteFloatOp_FP_TO_XINT_SAT(
N, OpNo);
break;
2413 R = PromoteFloatOp_STRICT_FP_EXTEND(
N, OpNo);
2416 case ISD::SETCC:
R = PromoteFloatOp_SETCC(
N, OpNo);
break;
2417 case ISD::STORE:
R = PromoteFloatOp_STORE(
N, OpNo);
break;
2423 ReplaceValueWith(
SDValue(
N, 0), R);
2427SDValue DAGTypeLegalizer::PromoteFloatOp_BITCAST(
SDNode *
N,
unsigned OpNo) {
2429 EVT OpVT =
Op->getValueType(0);
2431 SDValue Promoted = GetPromotedFloat(
N->getOperand(0));
2440 return DAG.
getBitcast(
N->getValueType(0), Convert);
2445SDValue DAGTypeLegalizer::PromoteFloatOp_FCOPYSIGN(
SDNode *
N,
unsigned OpNo) {
2446 assert (OpNo == 1 &&
"Only Operand 1 must need promotion here");
2447 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2450 N->getOperand(0), Op1);
2454SDValue DAGTypeLegalizer::PromoteFloatOp_UnaryOp(
SDNode *
N,
unsigned OpNo) {
2455 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2459SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(
SDNode *
N,
2461 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2466SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(
SDNode *
N,
unsigned OpNo) {
2467 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2468 EVT VT =
N->getValueType(0);
2471 if (VT ==
Op->getValueType(0))
2478SDValue DAGTypeLegalizer::PromoteFloatOp_STRICT_FP_EXTEND(
SDNode *
N,
2480 assert(OpNo == 1 &&
"Promoting unpromotable operand");
2482 SDValue Op = GetPromotedFloat(
N->getOperand(1));
2483 EVT VT =
N->getValueType(0);
2486 if (VT ==
Op->getValueType(0)) {
2487 ReplaceValueWith(
SDValue(
N, 1),
N->getOperand(0));
2493 N->getOperand(0),
Op);
2501SDValue DAGTypeLegalizer::PromoteFloatOp_SELECT_CC(
SDNode *
N,
unsigned OpNo) {
2506 LHS, RHS,
N->getOperand(2),
N->getOperand(3),
2512SDValue DAGTypeLegalizer::PromoteFloatOp_SETCC(
SDNode *
N,
unsigned OpNo) {
2513 EVT VT =
N->getValueType(0);
2514 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2515 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2516 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(2))->get();
2524SDValue DAGTypeLegalizer::PromoteFloatOp_STORE(
SDNode *
N,
unsigned OpNo) {
2529 SDValue Promoted = GetPromotedFloat(Val);
2530 EVT VT =
ST->getOperand(1).getValueType();
2537 return DAG.
getStore(
ST->getChain(),
DL, NewVal,
ST->getBasePtr(),
2538 ST->getMemOperand());
2547 SDValue Promoted = GetPromotedFloat(Val);
2548 EVT VT =
ST->getOperand(1).getValueType();
2555 ST->getBasePtr(),
ST->getMemOperand());
2562void DAGTypeLegalizer::PromoteFloatResult(
SDNode *
N,
unsigned ResNo) {
2563 LLVM_DEBUG(
dbgs() <<
"Promote float result " << ResNo <<
": ";
N->dump(&DAG));
2567 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
2572 switch (
N->getOpcode()) {
2579 dbgs() <<
"PromoteFloatResult #" << ResNo <<
": ";
2580 N->dump(&DAG);
dbgs() <<
"\n";
2587 R = PromoteFloatRes_EXTRACT_VECTOR_ELT(
N);
break;
2631 case ISD::FSUB:
R = PromoteFloatRes_BinOp(
N);
break;
2634 case ISD::FMAD:
R = PromoteFloatRes_FMAD(
N);
break;
2642 R = PromoteFloatRes_STRICT_FP_ROUND(
N);
2644 case ISD::LOAD:
R = PromoteFloatRes_LOAD(
N);
break;
2646 R = PromoteFloatRes_ATOMIC_LOAD(
N);
2661 R = PromoteFloatRes_VECREDUCE(
N);
2665 R = PromoteFloatRes_VECREDUCE_SEQ(
N);
2670 SetPromotedFloat(
SDValue(
N, ResNo), R);
2679 EVT VT =
N->getValueType(0);
2684 N->getOperand(0).getValueType().getSizeInBits());
2691 EVT VT =
N->getValueType(0);
2710SDValue DAGTypeLegalizer::PromoteFloatRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
2715 if (isa<ConstantSDNode>(
N->getOperand(1))) {
2723 switch (getTypeAction(VecVT)) {
2726 SDValue Res = GetScalarizedVector(
N->getOperand(0));
2727 ReplaceValueWith(
SDValue(
N, 0), Res);
2731 Vec = GetWidenedVector(Vec);
2733 ReplaceValueWith(
SDValue(
N, 0), Res);
2738 GetSplitVector(Vec,
Lo,
Hi);
2740 uint64_t LoElts =
Lo.getValueType().getVectorNumElements();
2742 if (IdxVal < LoElts)
2747 Idx.getValueType()));
2748 ReplaceValueWith(
SDValue(
N, 0), Res);
2756 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
2761 NewOp,
N->getOperand(1));
2764 EVT VT =
N->getValueType(0);
2773 EVT VT =
N->getValueType(0);
2775 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2786 EVT VT =
N->getValueType(0);
2788 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2797 EVT VT =
N->getValueType(0);
2799 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2800 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2801 return DAG.
getNode(
N->getOpcode(),
SDLoc(
N), NVT, Op0, Op1,
N->getFlags());
2805 EVT VT =
N->getValueType(0);
2807 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2808 SDValue Op1 = GetPromotedFloat(
N->getOperand(1));
2809 SDValue Op2 = GetPromotedFloat(
N->getOperand(2));
2811 return DAG.
getNode(
N->getOpcode(),
SDLoc(
N), NVT, Op0, Op1, Op2);
2816 EVT VT =
N->getValueType(0);
2818 SDValue Op0 = GetPromotedFloat(
N->getOperand(0));
2825 EVT VT =
N->getValueType(0);
2827 SDValue Op = GetPromotedFloat(
N->getOperand(0));
2841 EVT VT =
N->getValueType(0);
2842 EVT OpVT =
Op->getValueType(0);
2854SDValue DAGTypeLegalizer::PromoteFloatRes_STRICT_FP_ROUND(
SDNode *
N) {
2859 EVT VT =
N->getValueType(0);
2860 EVT OpVT =
Op->getValueType(0);
2877 EVT VT =
N->getValueType(0);
2882 L->getAddressingMode(),
L->getExtensionType(), IVT,
SDLoc(
N),
2883 L->getChain(),
L->getBasePtr(),
L->getOffset(),
L->getPointerInfo(), IVT,
2884 L->getOriginalAlign(),
L->getMemOperand()->getFlags(),
L->getAAInfo());
2894SDValue DAGTypeLegalizer::PromoteFloatRes_ATOMIC_LOAD(
SDNode *
N) {
2919 N->getOperand(0), TrueVal, FalseVal);
2929 TrueVal.getNode()->getValueType(0),
N->getOperand(0),
2930 N->getOperand(1), TrueVal, FalseVal,
N->getOperand(4));
2937 EVT VT =
N->getValueType(0);
2949 N->getValueType(0)));
2961SDValue DAGTypeLegalizer::PromoteFloatRes_VECREDUCE_SEQ(
SDNode *
N) {
2967 EVT VT =
N->getValueType(0);
2978 { AM->getChain(), AM->getBasePtr(), CastVal },
3001void DAGTypeLegalizer::SoftPromoteHalfResult(
SDNode *
N,
unsigned ResNo) {
3002 LLVM_DEBUG(
dbgs() <<
"Soft promote half result " << ResNo <<
": ";
3007 if (CustomLowerNode(
N,
N->getValueType(ResNo),
true)) {
3012 switch (
N->getOpcode()) {
3015 dbgs() <<
"SoftPromoteHalfResult #" << ResNo <<
": ";
3016 N->dump(&DAG);
dbgs() <<
"\n";
3022 R = SoftPromoteHalfRes_ARITH_FENCE(
N);
break;
3026 R = SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
N);
break;
3071 case ISD::FSUB:
R = SoftPromoteHalfRes_BinOp(
N);
break;
3074 case ISD::FMAD:
R = SoftPromoteHalfRes_FMAD(
N);
break;
3081 case ISD::LOAD:
R = SoftPromoteHalfRes_LOAD(
N);
break;
3083 R = SoftPromoteHalfRes_ATOMIC_LOAD(
N);
3089 case ISD::UNDEF:
R = SoftPromoteHalfRes_UNDEF(
N);
break;
3097 R = SoftPromoteHalfRes_VECREDUCE(
N);
3101 R = SoftPromoteHalfRes_VECREDUCE_SEQ(
N);
3106 SetSoftPromotedHalf(
SDValue(
N, ResNo), R);
3109SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ARITH_FENCE(
SDNode *
N) {
3111 BitConvertToInteger(
N->getOperand(0)));
3115 return BitConvertToInteger(
N->getOperand(0));
3118SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ConstantFP(
SDNode *
N) {
3126SDValue DAGTypeLegalizer::SoftPromoteHalfRes_EXTRACT_VECTOR_ELT(
SDNode *
N) {
3127 SDValue NewOp = BitConvertVectorToIntegerVector(
N->getOperand(0));
3133SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FCOPYSIGN(
SDNode *
N) {
3134 SDValue LHS = GetSoftPromotedHalf(
N->getOperand(0));
3135 SDValue RHS = BitConvertToInteger(
N->getOperand(1));
3138 EVT LVT =
LHS.getValueType();
3139 EVT RVT =
RHS.getValueType();
3160 }
else if (SizeDiff < 0) {
3182 EVT OVT =
N->getValueType(0);
3184 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3185 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3186 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3191 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3192 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3193 Op2 = DAG.
getNode(PromotionOpcode, dl, NVT, Op2);
3202 EVT OVT =
N->getValueType(0);
3204 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3218 EVT OVT =
N->getValueType(0);
3220 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3235SDValue DAGTypeLegalizer::SoftPromoteHalfRes_FP_ROUND(
SDNode *
N) {
3236 EVT RVT =
N->getValueType(0);
3237 EVT SVT =
N->getOperand(0).getValueType();
3239 if (
N->isStrictFPOpcode()) {
3242 if (RVT == MVT::f16)
3244 else if (RVT == MVT::bf16)
3249 {
N->getOperand(0),
N->getOperand(1)});
3264 DAG.
getLoad(
L->getAddressingMode(),
L->getExtensionType(), MVT::i16,
3265 SDLoc(
N),
L->getChain(),
L->getBasePtr(),
L->getOffset(),
3266 L->getPointerInfo(), MVT::i16,
L->getOriginalAlign(),
3267 L->getMemOperand()->getFlags(),
L->getAAInfo());
3274SDValue DAGTypeLegalizer::SoftPromoteHalfRes_ATOMIC_LOAD(
SDNode *
N) {
3289 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3290 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3295SDValue DAGTypeLegalizer::SoftPromoteHalfRes_SELECT_CC(
SDNode *
N) {
3296 SDValue Op2 = GetSoftPromotedHalf(
N->getOperand(2));
3297 SDValue Op3 = GetSoftPromotedHalf(
N->getOperand(3));
3299 N->getOperand(0),
N->getOperand(1), Op2, Op3,
3303SDValue DAGTypeLegalizer::SoftPromoteHalfRes_XINT_TO_FP(
SDNode *
N) {
3304 EVT OVT =
N->getValueType(0);
3319 EVT OVT =
N->getValueType(0);
3321 SDValue Op = GetSoftPromotedHalf(
N->getOperand(0));
3334 EVT OVT =
N->getValueType(0);
3336 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3337 SDValue Op1 = GetSoftPromotedHalf(
N->getOperand(1));
3342 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3343 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3351SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE(
SDNode *
N) {
3357SDValue DAGTypeLegalizer::SoftPromoteHalfRes_VECREDUCE_SEQ(
SDNode *
N) {
3367bool DAGTypeLegalizer::SoftPromoteHalfOperand(
SDNode *
N,
unsigned OpNo) {
3368 LLVM_DEBUG(
dbgs() <<
"Soft promote half operand " << OpNo <<
": ";
3372 if (CustomLowerNode(
N,
N->getOperand(OpNo).getValueType(),
false)) {
3382 switch (
N->getOpcode()) {
3385 dbgs() <<
"SoftPromoteHalfOperand Op #" << OpNo <<
": ";
3386 N->dump(&DAG);
dbgs() <<
"\n";
3391 case ISD::BITCAST: Res = SoftPromoteHalfOp_BITCAST(
N);
break;
3392 case ISD::FCOPYSIGN: Res = SoftPromoteHalfOp_FCOPYSIGN(
N, OpNo);
break;
3397 Res = SoftPromoteHalfOp_FP_TO_XINT_SAT(
N);
break;
3400 case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(
N, OpNo);
break;
3401 case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(
N);
break;
3402 case ISD::STORE: Res = SoftPromoteHalfOp_STORE(
N, OpNo);
break;
3404 Res = SoftPromoteHalfOp_ATOMIC_STORE(
N, OpNo);
3407 Res = SoftPromoteHalfOp_STACKMAP(
N, OpNo);
3410 Res = SoftPromoteHalfOp_PATCHPOINT(
N, OpNo);
3420 "Invalid operand expansion");
3422 ReplaceValueWith(
SDValue(
N, 0), Res);
3427 SDValue Op0 = GetSoftPromotedHalf(
N->getOperand(0));
3434 assert(OpNo == 1 &&
"Only Operand 1 must need promotion here");
3441 Op1 = GetSoftPromotedHalf(Op1);
3444 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0),
N->getOperand(0),
3448SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_EXTEND(
SDNode *
N) {
3449 EVT RVT =
N->getValueType(0);
3450 bool IsStrict =
N->isStrictFPOpcode();
3451 SDValue Op =
N->getOperand(IsStrict ? 1 : 0);
3452 EVT SVT =
Op.getValueType();
3453 Op = GetSoftPromotedHalf(
N->getOperand(IsStrict ? 1 : 0));
3457 if (SVT == MVT::f16)
3459 else if (SVT == MVT::bf16)
3465 {
N->getOperand(0),
Op});
3467 ReplaceValueWith(
SDValue(
N, 0), Res);
3474SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT(
SDNode *
N) {
3475 EVT RVT =
N->getValueType(0);
3477 EVT SVT =
Op.getValueType();
3482 Op = GetSoftPromotedHalf(
Op);
3486 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0), Res);
3489SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(
SDNode *
N) {
3490 EVT RVT =
N->getValueType(0);
3492 EVT SVT =
Op.getValueType();
3497 Op = GetSoftPromotedHalf(
Op);
3501 return DAG.
getNode(
N->getOpcode(), dl,
N->getValueType(0), Res,
3507 assert(OpNo == 0 &&
"Can only soften the comparison values");
3515 Op0 = GetSoftPromotedHalf(Op0);
3516 Op1 = GetSoftPromotedHalf(Op1);
3520 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3521 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3524 N->getOperand(2),
N->getOperand(3),
N->getOperand(4));
3530 ISD::CondCode CCCode = cast<CondCodeSDNode>(
N->getOperand(2))->get();
3536 Op0 = GetSoftPromotedHalf(Op0);
3537 Op1 = GetSoftPromotedHalf(Op1);
3541 Op0 = DAG.
getNode(PromotionOpcode, dl, NVT, Op0);
3542 Op1 = DAG.
getNode(PromotionOpcode, dl, NVT, Op1);
3547SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STORE(
SDNode *
N,
unsigned OpNo) {
3548 assert(OpNo == 1 &&
"Can only soften the stored value!");
3553 assert(!
ST->isTruncatingStore() &&
"Unexpected truncating store.");
3554 SDValue Promoted = GetSoftPromotedHalf(Val);
3555 return DAG.
getStore(
ST->getChain(), dl, Promoted,
ST->getBasePtr(),
3556 ST->getMemOperand());
3559SDValue DAGTypeLegalizer::SoftPromoteHalfOp_ATOMIC_STORE(
SDNode *
N,
3561 assert(OpNo == 1 &&
"Can only soften the stored value!");
3566 SDValue Promoted = GetSoftPromotedHalf(Val);
3568 ST->getChain(), Promoted,
ST->getBasePtr(),
3569 ST->getMemOperand());
3572SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(
SDNode *
N,
unsigned OpNo) {
3576 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3580 for (
unsigned ResNum = 0; ResNum <
N->getNumValues(); ResNum++)
3591 NewOps[OpNo] = GetSoftPromotedHalf(
Op);
3595 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
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
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.
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.
@ FNEG
Perform various unary floating-point operations inspired by libm.