28#include "llvm/IR/IntrinsicsLoongArch.h"
37#define DEBUG_TYPE "loongarch-isel-lowering"
42 cl::desc(
"Trap on integer division by zero."),
54 if (Subtarget.hasBasicF())
56 if (Subtarget.hasBasicD())
60 MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64};
62 MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64, MVT::v8f32, MVT::v4f64};
64 if (Subtarget.hasExtLSX())
68 if (Subtarget.hasExtLASX())
69 for (
MVT VT : LASXVTs)
170 if (Subtarget.hasBasicF()) {
190 if (!Subtarget.hasBasicD()) {
201 if (Subtarget.hasBasicD()) {
226 if (Subtarget.hasExtLSX()) {
241 for (
MVT VT : LSXVTs) {
253 for (
MVT VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64}) {
268 for (
MVT VT : {MVT::v4i32, MVT::v2i64}) {
272 for (
MVT VT : {MVT::v4f32, MVT::v2f64}) {
286 if (Subtarget.hasExtLASX()) {
287 for (
MVT VT : LASXVTs) {
299 for (
MVT VT : {MVT::v4i64, MVT::v8i32, MVT::v16i16, MVT::v32i8}) {
314 for (
MVT VT : {MVT::v8i32, MVT::v4i32, MVT::v4i64}) {
318 for (
MVT VT : {MVT::v8f32, MVT::v4f64}) {
338 if (Subtarget.hasExtLSX())
372 switch (
Op.getOpcode()) {
374 return lowerATOMIC_FENCE(
Op, DAG);
376 return lowerEH_DWARF_CFA(
Op, DAG);
378 return lowerGlobalAddress(
Op, DAG);
380 return lowerGlobalTLSAddress(
Op, DAG);
382 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
384 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
386 return lowerINTRINSIC_VOID(
Op, DAG);
388 return lowerBlockAddress(
Op, DAG);
390 return lowerJumpTable(
Op, DAG);
392 return lowerShiftLeftParts(
Op, DAG);
394 return lowerShiftRightParts(
Op, DAG,
true);
396 return lowerShiftRightParts(
Op, DAG,
false);
398 return lowerConstantPool(
Op, DAG);
400 return lowerFP_TO_SINT(
Op, DAG);
402 return lowerBITCAST(
Op, DAG);
404 return lowerUINT_TO_FP(
Op, DAG);
406 return lowerSINT_TO_FP(
Op, DAG);
408 return lowerVASTART(
Op, DAG);
410 return lowerFRAMEADDR(
Op, DAG);
412 return lowerRETURNADDR(
Op, DAG);
414 return lowerWRITE_REGISTER(
Op, DAG);
416 return lowerINSERT_VECTOR_ELT(
Op, DAG);
418 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
420 return lowerBUILD_VECTOR(
Op, DAG);
422 return lowerVECTOR_SHUFFLE(
Op, DAG);
436 if (isa<ConstantSDNode>(
Op))
438 if (isa<ConstantFPSDNode>(
Op))
453 EVT ResTy =
Op->getValueType(0);
455 APInt SplatValue, SplatUndef;
456 unsigned SplatBitSize;
461 if ((!Subtarget.hasExtLSX() || !Is128Vec) &&
462 (!Subtarget.hasExtLASX() || !Is256Vec))
465 if (
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
467 SplatBitSize <= 64) {
469 if (SplatBitSize != 8 && SplatBitSize != 16 && SplatBitSize != 32 &&
475 switch (SplatBitSize) {
479 ViaVecTy = Is128Vec ? MVT::v16i8 : MVT::v32i8;
482 ViaVecTy = Is128Vec ? MVT::v8i16 : MVT::v16i16;
485 ViaVecTy = Is128Vec ? MVT::v4i32 : MVT::v8i32;
488 ViaVecTy = Is128Vec ? MVT::v2i64 : MVT::v4i64;
496 if (ViaVecTy != ResTy)
509 EVT ResTy =
Node->getValueType(0);
515 for (
unsigned i = 0; i < NumElts; ++i) {
527LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
529 EVT VecTy =
Op->getOperand(0)->getValueType(0);
534 if (isa<ConstantSDNode>(
Idx) &&
535 (EltTy == MVT::i32 || EltTy == MVT::i64 || EltTy == MVT::f32 ||
536 EltTy == MVT::f64 ||
Idx->getAsZExtVal() < NumElts / 2))
543LoongArchTargetLowering::lowerINSERT_VECTOR_ELT(
SDValue Op,
545 if (isa<ConstantSDNode>(
Op->getOperand(2)))
569 if (Subtarget.
is64Bit() &&
Op.getOperand(2).getValueType() == MVT::i32) {
571 "On LA64, only 64-bit registers can be written.");
572 return Op.getOperand(0);
575 if (!Subtarget.
is64Bit() &&
Op.getOperand(2).getValueType() == MVT::i64) {
577 "On LA32, only 32-bit registers can be written.");
578 return Op.getOperand(0);
586 if (!isa<ConstantSDNode>(
Op.getOperand(0))) {
588 "be a constant integer");
595 EVT VT =
Op.getValueType();
598 unsigned Depth =
Op.getConstantOperandVal(0);
599 int GRLenInBytes = Subtarget.
getGRLen() / 8;
602 int Offset = -(GRLenInBytes * 2);
617 if (
Op.getConstantOperandVal(0) != 0) {
619 "return address can only be determined for the current frame");
653 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
661 !Subtarget.hasBasicD() &&
"unexpected target features");
666 auto *
C = dyn_cast<ConstantSDNode>(Op0.
getOperand(1));
667 if (
C &&
C->getZExtValue() < UINT64_C(0xFFFFFFFF))
677 dyn_cast<VTSDNode>(Op0.
getOperand(1))->getVT().bitsLT(MVT::i32))
681 EVT RetVT =
Op.getValueType();
683 MakeLibCallOptions CallOptions;
684 CallOptions.setTypeListBeforeSoften(OpVT, RetVT,
true);
687 std::tie(Result, Chain) =
695 !Subtarget.hasBasicD() &&
"unexpected target features");
702 dyn_cast<VTSDNode>(Op0.
getOperand(1))->getVT().bitsLE(MVT::i32))
706 EVT RetVT =
Op.getValueType();
708 MakeLibCallOptions CallOptions;
709 CallOptions.setTypeListBeforeSoften(OpVT, RetVT,
true);
712 std::tie(Result, Chain) =
723 if (
Op.getValueType() == MVT::f32 && Op0.
getValueType() == MVT::i32 &&
724 Subtarget.
is64Bit() && Subtarget.hasBasicF()) {
736 if (
Op.getValueSizeInBits() > 32 && Subtarget.hasBasicF() &&
737 !Subtarget.hasBasicD()) {
762 N->getOffset(), Flags);
770template <
class NodeTy>
773 bool IsLocal)
const {
783 assert(Subtarget.
is64Bit() &&
"Large code model requires LA64");
819 return getAddr(cast<BlockAddressSDNode>(
Op), DAG,
825 return getAddr(cast<JumpTableSDNode>(
Op), DAG,
831 return getAddr(cast<ConstantPoolSDNode>(
Op), DAG,
838 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
842 if (GV->
isDSOLocal() && isa<GlobalVariable>(GV)) {
843 if (
auto GCM = dyn_cast<GlobalVariable>(GV)->
getCodeModel())
893 Args.push_back(Entry);
925LoongArchTargetLowering::lowerGlobalTLSAddress(
SDValue Op,
932 assert((!Large || Subtarget.
is64Bit()) &&
"Large code model requires LA64");
935 assert(
N->getOffset() == 0 &&
"unexpected offset in global node");
945 return getDynamicTLSAddr(
N, DAG,
946 Large ? LoongArch::PseudoLA_TLS_GD_LARGE
947 : LoongArch::PseudoLA_TLS_GD,
954 return getDynamicTLSAddr(
N, DAG,
955 Large ? LoongArch::PseudoLA_TLS_LD_LARGE
956 : LoongArch::PseudoLA_TLS_LD,
961 return getStaticTLSAddr(
N, DAG,
962 Large ? LoongArch::PseudoLA_TLS_IE_LARGE
963 : LoongArch::PseudoLA_TLS_IE,
970 return getStaticTLSAddr(
N, DAG, LoongArch::PseudoLA_TLS_LE);
973 return getTLSDescAddr(
N, DAG,
974 Large ? LoongArch::PseudoLA_TLS_DESC_PC_LARGE
975 : LoongArch::PseudoLA_TLS_DESC_PC,
982 auto *CImm = cast<ConstantSDNode>(
Op->getOperand(ImmOp));
984 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
985 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
987 ": argument out of range.");
994LoongArchTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
997 switch (
Op.getConstantOperandVal(0)) {
1000 case Intrinsic::thread_pointer: {
1004 case Intrinsic::loongarch_lsx_vpickve2gr_d:
1005 case Intrinsic::loongarch_lsx_vpickve2gr_du:
1006 case Intrinsic::loongarch_lsx_vreplvei_d:
1007 case Intrinsic::loongarch_lasx_xvrepl128vei_d:
1008 return checkIntrinsicImmArg<1>(
Op, 2, DAG);
1009 case Intrinsic::loongarch_lsx_vreplvei_w:
1010 case Intrinsic::loongarch_lasx_xvrepl128vei_w:
1011 case Intrinsic::loongarch_lasx_xvpickve2gr_d:
1012 case Intrinsic::loongarch_lasx_xvpickve2gr_du:
1013 case Intrinsic::loongarch_lasx_xvpickve_d:
1014 case Intrinsic::loongarch_lasx_xvpickve_d_f:
1015 return checkIntrinsicImmArg<2>(
Op, 2, DAG);
1016 case Intrinsic::loongarch_lasx_xvinsve0_d:
1017 return checkIntrinsicImmArg<2>(
Op, 3, DAG);
1018 case Intrinsic::loongarch_lsx_vsat_b:
1019 case Intrinsic::loongarch_lsx_vsat_bu:
1020 case Intrinsic::loongarch_lsx_vrotri_b:
1021 case Intrinsic::loongarch_lsx_vsllwil_h_b:
1022 case Intrinsic::loongarch_lsx_vsllwil_hu_bu:
1023 case Intrinsic::loongarch_lsx_vsrlri_b:
1024 case Intrinsic::loongarch_lsx_vsrari_b:
1025 case Intrinsic::loongarch_lsx_vreplvei_h:
1026 case Intrinsic::loongarch_lasx_xvsat_b:
1027 case Intrinsic::loongarch_lasx_xvsat_bu:
1028 case Intrinsic::loongarch_lasx_xvrotri_b:
1029 case Intrinsic::loongarch_lasx_xvsllwil_h_b:
1030 case Intrinsic::loongarch_lasx_xvsllwil_hu_bu:
1031 case Intrinsic::loongarch_lasx_xvsrlri_b:
1032 case Intrinsic::loongarch_lasx_xvsrari_b:
1033 case Intrinsic::loongarch_lasx_xvrepl128vei_h:
1034 case Intrinsic::loongarch_lasx_xvpickve_w:
1035 case Intrinsic::loongarch_lasx_xvpickve_w_f:
1036 return checkIntrinsicImmArg<3>(
Op, 2, DAG);
1037 case Intrinsic::loongarch_lasx_xvinsve0_w:
1038 return checkIntrinsicImmArg<3>(
Op, 3, DAG);
1039 case Intrinsic::loongarch_lsx_vsat_h:
1040 case Intrinsic::loongarch_lsx_vsat_hu:
1041 case Intrinsic::loongarch_lsx_vrotri_h:
1042 case Intrinsic::loongarch_lsx_vsllwil_w_h:
1043 case Intrinsic::loongarch_lsx_vsllwil_wu_hu:
1044 case Intrinsic::loongarch_lsx_vsrlri_h:
1045 case Intrinsic::loongarch_lsx_vsrari_h:
1046 case Intrinsic::loongarch_lsx_vreplvei_b:
1047 case Intrinsic::loongarch_lasx_xvsat_h:
1048 case Intrinsic::loongarch_lasx_xvsat_hu:
1049 case Intrinsic::loongarch_lasx_xvrotri_h:
1050 case Intrinsic::loongarch_lasx_xvsllwil_w_h:
1051 case Intrinsic::loongarch_lasx_xvsllwil_wu_hu:
1052 case Intrinsic::loongarch_lasx_xvsrlri_h:
1053 case Intrinsic::loongarch_lasx_xvsrari_h:
1054 case Intrinsic::loongarch_lasx_xvrepl128vei_b:
1055 return checkIntrinsicImmArg<4>(
Op, 2, DAG);
1056 case Intrinsic::loongarch_lsx_vsrlni_b_h:
1057 case Intrinsic::loongarch_lsx_vsrani_b_h:
1058 case Intrinsic::loongarch_lsx_vsrlrni_b_h:
1059 case Intrinsic::loongarch_lsx_vsrarni_b_h:
1060 case Intrinsic::loongarch_lsx_vssrlni_b_h:
1061 case Intrinsic::loongarch_lsx_vssrani_b_h:
1062 case Intrinsic::loongarch_lsx_vssrlni_bu_h:
1063 case Intrinsic::loongarch_lsx_vssrani_bu_h:
1064 case Intrinsic::loongarch_lsx_vssrlrni_b_h:
1065 case Intrinsic::loongarch_lsx_vssrarni_b_h:
1066 case Intrinsic::loongarch_lsx_vssrlrni_bu_h:
1067 case Intrinsic::loongarch_lsx_vssrarni_bu_h:
1068 case Intrinsic::loongarch_lasx_xvsrlni_b_h:
1069 case Intrinsic::loongarch_lasx_xvsrani_b_h:
1070 case Intrinsic::loongarch_lasx_xvsrlrni_b_h:
1071 case Intrinsic::loongarch_lasx_xvsrarni_b_h:
1072 case Intrinsic::loongarch_lasx_xvssrlni_b_h:
1073 case Intrinsic::loongarch_lasx_xvssrani_b_h:
1074 case Intrinsic::loongarch_lasx_xvssrlni_bu_h:
1075 case Intrinsic::loongarch_lasx_xvssrani_bu_h:
1076 case Intrinsic::loongarch_lasx_xvssrlrni_b_h:
1077 case Intrinsic::loongarch_lasx_xvssrarni_b_h:
1078 case Intrinsic::loongarch_lasx_xvssrlrni_bu_h:
1079 case Intrinsic::loongarch_lasx_xvssrarni_bu_h:
1080 return checkIntrinsicImmArg<4>(
Op, 3, DAG);
1081 case Intrinsic::loongarch_lsx_vsat_w:
1082 case Intrinsic::loongarch_lsx_vsat_wu:
1083 case Intrinsic::loongarch_lsx_vrotri_w:
1084 case Intrinsic::loongarch_lsx_vsllwil_d_w:
1085 case Intrinsic::loongarch_lsx_vsllwil_du_wu:
1086 case Intrinsic::loongarch_lsx_vsrlri_w:
1087 case Intrinsic::loongarch_lsx_vsrari_w:
1088 case Intrinsic::loongarch_lsx_vslei_bu:
1089 case Intrinsic::loongarch_lsx_vslei_hu:
1090 case Intrinsic::loongarch_lsx_vslei_wu:
1091 case Intrinsic::loongarch_lsx_vslei_du:
1092 case Intrinsic::loongarch_lsx_vslti_bu:
1093 case Intrinsic::loongarch_lsx_vslti_hu:
1094 case Intrinsic::loongarch_lsx_vslti_wu:
1095 case Intrinsic::loongarch_lsx_vslti_du:
1096 case Intrinsic::loongarch_lsx_vbsll_v:
1097 case Intrinsic::loongarch_lsx_vbsrl_v:
1098 case Intrinsic::loongarch_lasx_xvsat_w:
1099 case Intrinsic::loongarch_lasx_xvsat_wu:
1100 case Intrinsic::loongarch_lasx_xvrotri_w:
1101 case Intrinsic::loongarch_lasx_xvsllwil_d_w:
1102 case Intrinsic::loongarch_lasx_xvsllwil_du_wu:
1103 case Intrinsic::loongarch_lasx_xvsrlri_w:
1104 case Intrinsic::loongarch_lasx_xvsrari_w:
1105 case Intrinsic::loongarch_lasx_xvslei_bu:
1106 case Intrinsic::loongarch_lasx_xvslei_hu:
1107 case Intrinsic::loongarch_lasx_xvslei_wu:
1108 case Intrinsic::loongarch_lasx_xvslei_du:
1109 case Intrinsic::loongarch_lasx_xvslti_bu:
1110 case Intrinsic::loongarch_lasx_xvslti_hu:
1111 case Intrinsic::loongarch_lasx_xvslti_wu:
1112 case Intrinsic::loongarch_lasx_xvslti_du:
1113 case Intrinsic::loongarch_lasx_xvbsll_v:
1114 case Intrinsic::loongarch_lasx_xvbsrl_v:
1115 return checkIntrinsicImmArg<5>(
Op, 2, DAG);
1116 case Intrinsic::loongarch_lsx_vseqi_b:
1117 case Intrinsic::loongarch_lsx_vseqi_h:
1118 case Intrinsic::loongarch_lsx_vseqi_w:
1119 case Intrinsic::loongarch_lsx_vseqi_d:
1120 case Intrinsic::loongarch_lsx_vslei_b:
1121 case Intrinsic::loongarch_lsx_vslei_h:
1122 case Intrinsic::loongarch_lsx_vslei_w:
1123 case Intrinsic::loongarch_lsx_vslei_d:
1124 case Intrinsic::loongarch_lsx_vslti_b:
1125 case Intrinsic::loongarch_lsx_vslti_h:
1126 case Intrinsic::loongarch_lsx_vslti_w:
1127 case Intrinsic::loongarch_lsx_vslti_d:
1128 case Intrinsic::loongarch_lasx_xvseqi_b:
1129 case Intrinsic::loongarch_lasx_xvseqi_h:
1130 case Intrinsic::loongarch_lasx_xvseqi_w:
1131 case Intrinsic::loongarch_lasx_xvseqi_d:
1132 case Intrinsic::loongarch_lasx_xvslei_b:
1133 case Intrinsic::loongarch_lasx_xvslei_h:
1134 case Intrinsic::loongarch_lasx_xvslei_w:
1135 case Intrinsic::loongarch_lasx_xvslei_d:
1136 case Intrinsic::loongarch_lasx_xvslti_b:
1137 case Intrinsic::loongarch_lasx_xvslti_h:
1138 case Intrinsic::loongarch_lasx_xvslti_w:
1139 case Intrinsic::loongarch_lasx_xvslti_d:
1140 return checkIntrinsicImmArg<5>(
Op, 2, DAG,
true);
1141 case Intrinsic::loongarch_lsx_vsrlni_h_w:
1142 case Intrinsic::loongarch_lsx_vsrani_h_w:
1143 case Intrinsic::loongarch_lsx_vsrlrni_h_w:
1144 case Intrinsic::loongarch_lsx_vsrarni_h_w:
1145 case Intrinsic::loongarch_lsx_vssrlni_h_w:
1146 case Intrinsic::loongarch_lsx_vssrani_h_w:
1147 case Intrinsic::loongarch_lsx_vssrlni_hu_w:
1148 case Intrinsic::loongarch_lsx_vssrani_hu_w:
1149 case Intrinsic::loongarch_lsx_vssrlrni_h_w:
1150 case Intrinsic::loongarch_lsx_vssrarni_h_w:
1151 case Intrinsic::loongarch_lsx_vssrlrni_hu_w:
1152 case Intrinsic::loongarch_lsx_vssrarni_hu_w:
1153 case Intrinsic::loongarch_lsx_vfrstpi_b:
1154 case Intrinsic::loongarch_lsx_vfrstpi_h:
1155 case Intrinsic::loongarch_lasx_xvsrlni_h_w:
1156 case Intrinsic::loongarch_lasx_xvsrani_h_w:
1157 case Intrinsic::loongarch_lasx_xvsrlrni_h_w:
1158 case Intrinsic::loongarch_lasx_xvsrarni_h_w:
1159 case Intrinsic::loongarch_lasx_xvssrlni_h_w:
1160 case Intrinsic::loongarch_lasx_xvssrani_h_w:
1161 case Intrinsic::loongarch_lasx_xvssrlni_hu_w:
1162 case Intrinsic::loongarch_lasx_xvssrani_hu_w:
1163 case Intrinsic::loongarch_lasx_xvssrlrni_h_w:
1164 case Intrinsic::loongarch_lasx_xvssrarni_h_w:
1165 case Intrinsic::loongarch_lasx_xvssrlrni_hu_w:
1166 case Intrinsic::loongarch_lasx_xvssrarni_hu_w:
1167 case Intrinsic::loongarch_lasx_xvfrstpi_b:
1168 case Intrinsic::loongarch_lasx_xvfrstpi_h:
1169 return checkIntrinsicImmArg<5>(
Op, 3, DAG);
1170 case Intrinsic::loongarch_lsx_vsat_d:
1171 case Intrinsic::loongarch_lsx_vsat_du:
1172 case Intrinsic::loongarch_lsx_vrotri_d:
1173 case Intrinsic::loongarch_lsx_vsrlri_d:
1174 case Intrinsic::loongarch_lsx_vsrari_d:
1175 case Intrinsic::loongarch_lasx_xvsat_d:
1176 case Intrinsic::loongarch_lasx_xvsat_du:
1177 case Intrinsic::loongarch_lasx_xvrotri_d:
1178 case Intrinsic::loongarch_lasx_xvsrlri_d:
1179 case Intrinsic::loongarch_lasx_xvsrari_d:
1180 return checkIntrinsicImmArg<6>(
Op, 2, DAG);
1181 case Intrinsic::loongarch_lsx_vsrlni_w_d:
1182 case Intrinsic::loongarch_lsx_vsrani_w_d:
1183 case Intrinsic::loongarch_lsx_vsrlrni_w_d:
1184 case Intrinsic::loongarch_lsx_vsrarni_w_d:
1185 case Intrinsic::loongarch_lsx_vssrlni_w_d:
1186 case Intrinsic::loongarch_lsx_vssrani_w_d:
1187 case Intrinsic::loongarch_lsx_vssrlni_wu_d:
1188 case Intrinsic::loongarch_lsx_vssrani_wu_d:
1189 case Intrinsic::loongarch_lsx_vssrlrni_w_d:
1190 case Intrinsic::loongarch_lsx_vssrarni_w_d:
1191 case Intrinsic::loongarch_lsx_vssrlrni_wu_d:
1192 case Intrinsic::loongarch_lsx_vssrarni_wu_d:
1193 case Intrinsic::loongarch_lasx_xvsrlni_w_d:
1194 case Intrinsic::loongarch_lasx_xvsrani_w_d:
1195 case Intrinsic::loongarch_lasx_xvsrlrni_w_d:
1196 case Intrinsic::loongarch_lasx_xvsrarni_w_d:
1197 case Intrinsic::loongarch_lasx_xvssrlni_w_d:
1198 case Intrinsic::loongarch_lasx_xvssrani_w_d:
1199 case Intrinsic::loongarch_lasx_xvssrlni_wu_d:
1200 case Intrinsic::loongarch_lasx_xvssrani_wu_d:
1201 case Intrinsic::loongarch_lasx_xvssrlrni_w_d:
1202 case Intrinsic::loongarch_lasx_xvssrarni_w_d:
1203 case Intrinsic::loongarch_lasx_xvssrlrni_wu_d:
1204 case Intrinsic::loongarch_lasx_xvssrarni_wu_d:
1205 return checkIntrinsicImmArg<6>(
Op, 3, DAG);
1206 case Intrinsic::loongarch_lsx_vsrlni_d_q:
1207 case Intrinsic::loongarch_lsx_vsrani_d_q:
1208 case Intrinsic::loongarch_lsx_vsrlrni_d_q:
1209 case Intrinsic::loongarch_lsx_vsrarni_d_q:
1210 case Intrinsic::loongarch_lsx_vssrlni_d_q:
1211 case Intrinsic::loongarch_lsx_vssrani_d_q:
1212 case Intrinsic::loongarch_lsx_vssrlni_du_q:
1213 case Intrinsic::loongarch_lsx_vssrani_du_q:
1214 case Intrinsic::loongarch_lsx_vssrlrni_d_q:
1215 case Intrinsic::loongarch_lsx_vssrarni_d_q:
1216 case Intrinsic::loongarch_lsx_vssrlrni_du_q:
1217 case Intrinsic::loongarch_lsx_vssrarni_du_q:
1218 case Intrinsic::loongarch_lasx_xvsrlni_d_q:
1219 case Intrinsic::loongarch_lasx_xvsrani_d_q:
1220 case Intrinsic::loongarch_lasx_xvsrlrni_d_q:
1221 case Intrinsic::loongarch_lasx_xvsrarni_d_q:
1222 case Intrinsic::loongarch_lasx_xvssrlni_d_q:
1223 case Intrinsic::loongarch_lasx_xvssrani_d_q:
1224 case Intrinsic::loongarch_lasx_xvssrlni_du_q:
1225 case Intrinsic::loongarch_lasx_xvssrani_du_q:
1226 case Intrinsic::loongarch_lasx_xvssrlrni_d_q:
1227 case Intrinsic::loongarch_lasx_xvssrarni_d_q:
1228 case Intrinsic::loongarch_lasx_xvssrlrni_du_q:
1229 case Intrinsic::loongarch_lasx_xvssrarni_du_q:
1230 return checkIntrinsicImmArg<7>(
Op, 3, DAG);
1231 case Intrinsic::loongarch_lsx_vnori_b:
1232 case Intrinsic::loongarch_lsx_vshuf4i_b:
1233 case Intrinsic::loongarch_lsx_vshuf4i_h:
1234 case Intrinsic::loongarch_lsx_vshuf4i_w:
1235 case Intrinsic::loongarch_lasx_xvnori_b:
1236 case Intrinsic::loongarch_lasx_xvshuf4i_b:
1237 case Intrinsic::loongarch_lasx_xvshuf4i_h:
1238 case Intrinsic::loongarch_lasx_xvshuf4i_w:
1239 case Intrinsic::loongarch_lasx_xvpermi_d:
1240 return checkIntrinsicImmArg<8>(
Op, 2, DAG);
1241 case Intrinsic::loongarch_lsx_vshuf4i_d:
1242 case Intrinsic::loongarch_lsx_vpermi_w:
1243 case Intrinsic::loongarch_lsx_vbitseli_b:
1244 case Intrinsic::loongarch_lsx_vextrins_b:
1245 case Intrinsic::loongarch_lsx_vextrins_h:
1246 case Intrinsic::loongarch_lsx_vextrins_w:
1247 case Intrinsic::loongarch_lsx_vextrins_d:
1248 case Intrinsic::loongarch_lasx_xvshuf4i_d:
1249 case Intrinsic::loongarch_lasx_xvpermi_w:
1250 case Intrinsic::loongarch_lasx_xvpermi_q:
1251 case Intrinsic::loongarch_lasx_xvbitseli_b:
1252 case Intrinsic::loongarch_lasx_xvextrins_b:
1253 case Intrinsic::loongarch_lasx_xvextrins_h:
1254 case Intrinsic::loongarch_lasx_xvextrins_w:
1255 case Intrinsic::loongarch_lasx_xvextrins_d:
1256 return checkIntrinsicImmArg<8>(
Op, 3, DAG);
1257 case Intrinsic::loongarch_lsx_vrepli_b:
1258 case Intrinsic::loongarch_lsx_vrepli_h:
1259 case Intrinsic::loongarch_lsx_vrepli_w:
1260 case Intrinsic::loongarch_lsx_vrepli_d:
1261 case Intrinsic::loongarch_lasx_xvrepli_b:
1262 case Intrinsic::loongarch_lasx_xvrepli_h:
1263 case Intrinsic::loongarch_lasx_xvrepli_w:
1264 case Intrinsic::loongarch_lasx_xvrepli_d:
1265 return checkIntrinsicImmArg<10>(
Op, 1, DAG,
true);
1266 case Intrinsic::loongarch_lsx_vldi:
1267 case Intrinsic::loongarch_lasx_xvldi:
1268 return checkIntrinsicImmArg<13>(
Op, 1, DAG,
true);
1283LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
1287 EVT VT =
Op.getValueType();
1289 const StringRef ErrorMsgOOR =
"argument out of range";
1290 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1291 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1293 switch (
Op.getConstantOperandVal(1)) {
1296 case Intrinsic::loongarch_crc_w_b_w:
1297 case Intrinsic::loongarch_crc_w_h_w:
1298 case Intrinsic::loongarch_crc_w_w_w:
1299 case Intrinsic::loongarch_crc_w_d_w:
1300 case Intrinsic::loongarch_crcc_w_b_w:
1301 case Intrinsic::loongarch_crcc_w_h_w:
1302 case Intrinsic::loongarch_crcc_w_w_w:
1303 case Intrinsic::loongarch_crcc_w_d_w:
1305 case Intrinsic::loongarch_csrrd_w:
1306 case Intrinsic::loongarch_csrrd_d: {
1307 unsigned Imm =
Op.getConstantOperandVal(2);
1308 return !isUInt<14>(Imm)
1310 : DAG.getNode(LoongArchISD::
CSRRD,
DL, {GRLenVT, MVT::Other},
1313 case Intrinsic::loongarch_csrwr_w:
1314 case Intrinsic::loongarch_csrwr_d: {
1315 unsigned Imm =
Op.getConstantOperandVal(3);
1316 return !isUInt<14>(Imm)
1318 : DAG.getNode(LoongArchISD::
CSRWR,
DL, {GRLenVT, MVT::Other},
1319 {Chain,
Op.getOperand(2),
1322 case Intrinsic::loongarch_csrxchg_w:
1323 case Intrinsic::loongarch_csrxchg_d: {
1324 unsigned Imm =
Op.getConstantOperandVal(4);
1325 return !isUInt<14>(Imm)
1327 : DAG.getNode(LoongArchISD::
CSRXCHG,
DL, {GRLenVT, MVT::Other},
1328 {Chain,
Op.getOperand(2),
Op.getOperand(3),
1331 case Intrinsic::loongarch_iocsrrd_d: {
1336#define IOCSRRD_CASE(NAME, NODE) \
1337 case Intrinsic::loongarch_##NAME: { \
1338 return DAG.getNode(LoongArchISD::NODE, DL, {GRLenVT, MVT::Other}, \
1339 {Chain, Op.getOperand(2)}); \
1345 case Intrinsic::loongarch_cpucfg: {
1347 {Chain,
Op.getOperand(2)});
1349 case Intrinsic::loongarch_lddir_d: {
1350 unsigned Imm =
Op.getConstantOperandVal(3);
1351 return !isUInt<8>(Imm)
1355 case Intrinsic::loongarch_movfcsr2gr: {
1356 if (!Subtarget.hasBasicF())
1358 unsigned Imm =
Op.getConstantOperandVal(2);
1359 return !isUInt<2>(Imm)
1361 : DAG.getNode(LoongArchISD::
MOVFCSR2GR,
DL, {VT, MVT::Other},
1364 case Intrinsic::loongarch_lsx_vld:
1365 case Intrinsic::loongarch_lsx_vldrepl_b:
1366 case Intrinsic::loongarch_lasx_xvld:
1367 case Intrinsic::loongarch_lasx_xvldrepl_b:
1368 return !isInt<12>(cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1371 case Intrinsic::loongarch_lsx_vldrepl_h:
1372 case Intrinsic::loongarch_lasx_xvldrepl_h:
1373 return !isShiftedInt<11, 1>(
1374 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1376 Op,
"argument out of range or not a multiple of 2", DAG)
1378 case Intrinsic::loongarch_lsx_vldrepl_w:
1379 case Intrinsic::loongarch_lasx_xvldrepl_w:
1380 return !isShiftedInt<10, 2>(
1381 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1383 Op,
"argument out of range or not a multiple of 4", DAG)
1385 case Intrinsic::loongarch_lsx_vldrepl_d:
1386 case Intrinsic::loongarch_lasx_xvldrepl_d:
1387 return !isShiftedInt<9, 3>(
1388 cast<ConstantSDNode>(
Op.getOperand(3))->getSExtValue())
1390 Op,
"argument out of range or not a multiple of 8", DAG)
1401 return Op.getOperand(0);
1409 uint64_t IntrinsicEnum =
Op.getConstantOperandVal(1);
1411 const StringRef ErrorMsgOOR =
"argument out of range";
1412 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1413 const StringRef ErrorMsgReqLA32 =
"requires loongarch32";
1414 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1416 switch (IntrinsicEnum) {
1420 case Intrinsic::loongarch_cacop_d:
1421 case Intrinsic::loongarch_cacop_w: {
1422 if (IntrinsicEnum == Intrinsic::loongarch_cacop_d && !Subtarget.
is64Bit())
1424 if (IntrinsicEnum == Intrinsic::loongarch_cacop_w && Subtarget.
is64Bit())
1428 int Imm2 = cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue();
1429 if (!isUInt<5>(Imm1) || !isInt<12>(Imm2))
1433 case Intrinsic::loongarch_dbar: {
1435 return !isUInt<15>(Imm)
1440 case Intrinsic::loongarch_ibar: {
1442 return !isUInt<15>(Imm)
1447 case Intrinsic::loongarch_break: {
1449 return !isUInt<15>(Imm)
1454 case Intrinsic::loongarch_movgr2fcsr: {
1455 if (!Subtarget.hasBasicF())
1458 return !isUInt<2>(Imm)
1465 case Intrinsic::loongarch_syscall: {
1467 return !isUInt<15>(Imm)
1472#define IOCSRWR_CASE(NAME, NODE) \
1473 case Intrinsic::loongarch_##NAME: { \
1474 SDValue Op3 = Op.getOperand(3); \
1475 return Subtarget.is64Bit() \
1476 ? DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, \
1477 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
1478 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3)) \
1479 : DAG.getNode(LoongArchISD::NODE, DL, MVT::Other, Chain, Op2, \
1486 case Intrinsic::loongarch_iocsrwr_d: {
1494#define ASRT_LE_GT_CASE(NAME) \
1495 case Intrinsic::loongarch_##NAME: { \
1496 return !Subtarget.is64Bit() \
1497 ? emitIntrinsicErrorMessage(Op, ErrorMsgReqLA64, DAG) \
1502#undef ASRT_LE_GT_CASE
1503 case Intrinsic::loongarch_ldpte_d: {
1504 unsigned Imm =
Op.getConstantOperandVal(3);
1510 case Intrinsic::loongarch_lsx_vst:
1511 case Intrinsic::loongarch_lasx_xvst:
1512 return !isInt<12>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue())
1515 case Intrinsic::loongarch_lasx_xvstelm_b:
1516 return (!isInt<8>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1517 !isUInt<5>(
Op.getConstantOperandVal(5)))
1520 case Intrinsic::loongarch_lsx_vstelm_b:
1521 return (!isInt<8>(cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1522 !isUInt<4>(
Op.getConstantOperandVal(5)))
1525 case Intrinsic::loongarch_lasx_xvstelm_h:
1526 return (!isShiftedInt<8, 1>(
1527 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1528 !isUInt<4>(
Op.getConstantOperandVal(5)))
1530 Op,
"argument out of range or not a multiple of 2", DAG)
1532 case Intrinsic::loongarch_lsx_vstelm_h:
1533 return (!isShiftedInt<8, 1>(
1534 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1535 !isUInt<3>(
Op.getConstantOperandVal(5)))
1537 Op,
"argument out of range or not a multiple of 2", DAG)
1539 case Intrinsic::loongarch_lasx_xvstelm_w:
1540 return (!isShiftedInt<8, 2>(
1541 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1542 !isUInt<3>(
Op.getConstantOperandVal(5)))
1544 Op,
"argument out of range or not a multiple of 4", DAG)
1546 case Intrinsic::loongarch_lsx_vstelm_w:
1547 return (!isShiftedInt<8, 2>(
1548 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1549 !isUInt<2>(
Op.getConstantOperandVal(5)))
1551 Op,
"argument out of range or not a multiple of 4", DAG)
1553 case Intrinsic::loongarch_lasx_xvstelm_d:
1554 return (!isShiftedInt<8, 3>(
1555 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1556 !isUInt<2>(
Op.getConstantOperandVal(5)))
1558 Op,
"argument out of range or not a multiple of 8", DAG)
1560 case Intrinsic::loongarch_lsx_vstelm_d:
1561 return (!isShiftedInt<8, 3>(
1562 cast<ConstantSDNode>(
Op.getOperand(4))->getSExtValue()) ||
1563 !isUInt<1>(
Op.getConstantOperandVal(5)))
1565 Op,
"argument out of range or not a multiple of 8", DAG)
1576 EVT VT =
Lo.getValueType();
1616 EVT VT =
Lo.getValueType();
1699 NewOp0 = DAG.
getNode(ExtOpc,
DL, MVT::i64,
N->getOperand(0));
1700 NewRes = DAG.
getNode(WOpcode,
DL, MVT::i64, NewOp0);
1704 NewOp0 = DAG.
getNode(ExtOpc,
DL, MVT::i64,
N->getOperand(0));
1710 NewRes = DAG.
getNode(WOpcode,
DL, MVT::i64, NewOp0, NewOp1);
1725 StringRef ErrorMsg,
bool WithChain =
true) {
1730 Results.push_back(
N->getOperand(0));
1733template <
unsigned N>
1738 const StringRef ErrorMsgOOR =
"argument out of range";
1739 unsigned Imm =
Node->getConstantOperandVal(2);
1740 if (!isUInt<N>(Imm)) {
1773 switch (
N->getConstantOperandVal(0)) {
1776 case Intrinsic::loongarch_lsx_vpickve2gr_b:
1777 replaceVPICKVE2GRResults<4>(
N,
Results, DAG, Subtarget,
1780 case Intrinsic::loongarch_lsx_vpickve2gr_h:
1781 case Intrinsic::loongarch_lasx_xvpickve2gr_w:
1782 replaceVPICKVE2GRResults<3>(
N,
Results, DAG, Subtarget,
1785 case Intrinsic::loongarch_lsx_vpickve2gr_w:
1786 replaceVPICKVE2GRResults<2>(
N,
Results, DAG, Subtarget,
1789 case Intrinsic::loongarch_lsx_vpickve2gr_bu:
1790 replaceVPICKVE2GRResults<4>(
N,
Results, DAG, Subtarget,
1793 case Intrinsic::loongarch_lsx_vpickve2gr_hu:
1794 case Intrinsic::loongarch_lasx_xvpickve2gr_wu:
1795 replaceVPICKVE2GRResults<3>(
N,
Results, DAG, Subtarget,
1798 case Intrinsic::loongarch_lsx_vpickve2gr_wu:
1799 replaceVPICKVE2GRResults<2>(
N,
Results, DAG, Subtarget,
1802 case Intrinsic::loongarch_lsx_bz_b:
1803 case Intrinsic::loongarch_lsx_bz_h:
1804 case Intrinsic::loongarch_lsx_bz_w:
1805 case Intrinsic::loongarch_lsx_bz_d:
1806 case Intrinsic::loongarch_lasx_xbz_b:
1807 case Intrinsic::loongarch_lasx_xbz_h:
1808 case Intrinsic::loongarch_lasx_xbz_w:
1809 case Intrinsic::loongarch_lasx_xbz_d:
1813 case Intrinsic::loongarch_lsx_bz_v:
1814 case Intrinsic::loongarch_lasx_xbz_v:
1818 case Intrinsic::loongarch_lsx_bnz_b:
1819 case Intrinsic::loongarch_lsx_bnz_h:
1820 case Intrinsic::loongarch_lsx_bnz_w:
1821 case Intrinsic::loongarch_lsx_bnz_d:
1822 case Intrinsic::loongarch_lasx_xbnz_b:
1823 case Intrinsic::loongarch_lasx_xbnz_h:
1824 case Intrinsic::loongarch_lasx_xbnz_w:
1825 case Intrinsic::loongarch_lasx_xbnz_d:
1829 case Intrinsic::loongarch_lsx_bnz_v:
1830 case Intrinsic::loongarch_lasx_xbnz_v:
1840 EVT VT =
N->getValueType(0);
1841 switch (
N->getOpcode()) {
1848 "Unexpected custom legalisation");
1857 "Unexpected custom legalisation");
1862 "Unexpected custom legalisation");
1876 EVT OpVT = Src.getValueType();
1880 std::tie(Result, Chain) =
1887 EVT SrcVT = Src.getValueType();
1888 if (VT == MVT::i32 && SrcVT == MVT::f32 && Subtarget.
is64Bit() &&
1889 Subtarget.hasBasicF()) {
1898 "Unexpected custom legalisation");
1901 TLI.expandFP_TO_UINT(
N, Tmp1, Tmp2, DAG);
1907 assert((VT == MVT::i16 || VT == MVT::i32) &&
1908 "Unexpected custom legalization");
1929 assert((VT == MVT::i8 || (VT == MVT::i32 && Subtarget.
is64Bit())) &&
1930 "Unexpected custom legalization");
1950 "Unexpected custom legalisation");
1958 const StringRef ErrorMsgOOR =
"argument out of range";
1959 const StringRef ErrorMsgReqLA64 =
"requires loongarch64";
1960 const StringRef ErrorMsgReqF =
"requires basic 'f' target feature";
1962 switch (
N->getConstantOperandVal(1)) {
1965 case Intrinsic::loongarch_movfcsr2gr: {
1966 if (!Subtarget.hasBasicF()) {
1971 if (!isUInt<2>(Imm)) {
1983#define CRC_CASE_EXT_BINARYOP(NAME, NODE) \
1984 case Intrinsic::loongarch_##NAME: { \
1985 SDValue NODE = DAG.getNode( \
1986 LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
1987 {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
1988 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
1989 Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
1990 Results.push_back(NODE.getValue(1)); \
1999#undef CRC_CASE_EXT_BINARYOP
2001#define CRC_CASE_EXT_UNARYOP(NAME, NODE) \
2002 case Intrinsic::loongarch_##NAME: { \
2003 SDValue NODE = DAG.getNode( \
2004 LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
2006 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
2007 Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
2008 Results.push_back(NODE.getValue(1)); \
2013#undef CRC_CASE_EXT_UNARYOP
2014#define CSR_CASE(ID) \
2015 case Intrinsic::loongarch_##ID: { \
2016 if (!Subtarget.is64Bit()) \
2017 emitErrorAndReplaceIntrinsicResults(N, Results, DAG, ErrorMsgReqLA64); \
2025 case Intrinsic::loongarch_csrrd_w: {
2027 if (!isUInt<14>(Imm)) {
2039 case Intrinsic::loongarch_csrwr_w: {
2040 unsigned Imm =
N->getConstantOperandVal(3);
2041 if (!isUInt<14>(Imm)) {
2054 case Intrinsic::loongarch_csrxchg_w: {
2055 unsigned Imm =
N->getConstantOperandVal(4);
2056 if (!isUInt<14>(Imm)) {
2070#define IOCSRRD_CASE(NAME, NODE) \
2071 case Intrinsic::loongarch_##NAME: { \
2072 SDValue IOCSRRDResults = \
2073 DAG.getNode(LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
2074 {Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)}); \
2075 Results.push_back( \
2076 DAG.getNode(ISD::TRUNCATE, DL, VT, IOCSRRDResults.getValue(0))); \
2077 Results.push_back(IOCSRRDResults.getValue(1)); \
2084 case Intrinsic::loongarch_cpucfg: {
2093 case Intrinsic::loongarch_lddir_d: {
2106 "On LA64, only 64-bit registers can be read.");
2109 "On LA32, only 32-bit registers can be read.");
2111 Results.push_back(
N->getOperand(0));
2127 SDValue FirstOperand =
N->getOperand(0);
2128 SDValue SecondOperand =
N->getOperand(1);
2129 unsigned FirstOperandOpc = FirstOperand.
getOpcode();
2130 EVT ValTy =
N->getValueType(0);
2133 unsigned SMIdx, SMLen;
2139 if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)) ||
2150 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))))
2191 NewOperand = FirstOperand;
2194 msb = lsb + SMLen - 1;
2198 if (FirstOperandOpc ==
ISD::SRA || FirstOperandOpc ==
ISD::SRL || lsb == 0)
2219 SDValue FirstOperand =
N->getOperand(0);
2221 EVT ValTy =
N->getValueType(0);
2224 unsigned MaskIdx, MaskLen;
2230 !(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))) ||
2235 if (!(CN = dyn_cast<ConstantSDNode>(
N->getOperand(1))))
2239 if (MaskIdx <= Shamt && Shamt <= MaskIdx + MaskLen - 1)
2252 EVT ValTy =
N->getValueType(0);
2253 SDValue N0 =
N->getOperand(0), N1 =
N->getOperand(1);
2257 unsigned MaskIdx0, MaskLen0, MaskIdx1, MaskLen1;
2259 bool SwapAndRetried =
false;
2264 if (ValBits != 32 && ValBits != 64)
2274 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2277 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2279 MaskIdx0 == MaskIdx1 && MaskLen0 == MaskLen1 &&
2280 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2282 (MaskIdx0 + MaskLen0 <= ValBits)) {
2296 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2299 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2301 (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2303 MaskLen0 == MaskLen1 && MaskIdx1 == 0 &&
2304 (MaskIdx0 + MaskLen0 <= ValBits)) {
2319 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2321 (MaskIdx0 + MaskLen0 <= 64) &&
2322 (CN1 = dyn_cast<ConstantSDNode>(N1->getOperand(1))) &&
2329 ? (MaskIdx0 + (MaskLen0 & 31) - 1)
2330 : (MaskIdx0 + MaskLen0 - 1),
2342 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2344 MaskIdx0 == 0 && (CN1 = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2346 (MaskIdx0 + MaskLen0 <= ValBits)) {
2361 (CN0 = dyn_cast<ConstantSDNode>(N0.
getOperand(1))) &&
2363 (CN1 = dyn_cast<ConstantSDNode>(N1)) &&
2369 DAG.
getConstant(ValBits == 32 ? (MaskIdx0 + (MaskLen0 & 31) - 1)
2370 : (MaskIdx0 + MaskLen0 - 1),
2385 unsigned MaskIdx, MaskLen;
2386 if (N1.getOpcode() ==
ISD::SHL && N1.getOperand(0).getOpcode() ==
ISD::AND &&
2387 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2389 MaskIdx == 0 && (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2411 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2413 N1.getOperand(0).getOpcode() ==
ISD::SHL &&
2414 (CNShamt = dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(1))) &&
2427 if (!SwapAndRetried) {
2429 SwapAndRetried =
true;
2433 SwapAndRetried =
false;
2445 (CNMask = dyn_cast<ConstantSDNode>(N1.getOperand(1))) &&
2459 if (!SwapAndRetried) {
2461 SwapAndRetried =
true;
2483template <
unsigned N>
2487 bool IsSigned =
false) {
2489 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(ImmOp));
2491 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
2492 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
2494 ": argument out of range.");
2500template <
unsigned N>
2504 EVT ResTy =
Node->getValueType(0);
2505 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(ImmOp));
2508 if ((IsSigned && !isInt<N>(CImm->getSExtValue())) ||
2509 (!IsSigned && !isUInt<N>(CImm->getZExtValue()))) {
2511 ": argument out of range.");
2516 IsSigned ? CImm->getSExtValue() : CImm->getZExtValue(), IsSigned),
2522 EVT ResTy =
Node->getValueType(0);
2530 EVT ResTy =
Node->getValueType(0);
2539template <
unsigned N>
2542 EVT ResTy =
Node->getValueType(0);
2543 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2545 if (!isUInt<N>(CImm->getZExtValue())) {
2547 ": argument out of range.");
2557template <
unsigned N>
2560 EVT ResTy =
Node->getValueType(0);
2561 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2563 if (!isUInt<N>(CImm->getZExtValue())) {
2565 ": argument out of range.");
2574template <
unsigned N>
2577 EVT ResTy =
Node->getValueType(0);
2578 auto *CImm = cast<ConstantSDNode>(
Node->getOperand(2));
2580 if (!isUInt<N>(CImm->getZExtValue())) {
2582 ": argument out of range.");
2596 switch (
N->getConstantOperandVal(0)) {
2599 case Intrinsic::loongarch_lsx_vadd_b:
2600 case Intrinsic::loongarch_lsx_vadd_h:
2601 case Intrinsic::loongarch_lsx_vadd_w:
2602 case Intrinsic::loongarch_lsx_vadd_d:
2603 case Intrinsic::loongarch_lasx_xvadd_b:
2604 case Intrinsic::loongarch_lasx_xvadd_h:
2605 case Intrinsic::loongarch_lasx_xvadd_w:
2606 case Intrinsic::loongarch_lasx_xvadd_d:
2609 case Intrinsic::loongarch_lsx_vaddi_bu:
2610 case Intrinsic::loongarch_lsx_vaddi_hu:
2611 case Intrinsic::loongarch_lsx_vaddi_wu:
2612 case Intrinsic::loongarch_lsx_vaddi_du:
2613 case Intrinsic::loongarch_lasx_xvaddi_bu:
2614 case Intrinsic::loongarch_lasx_xvaddi_hu:
2615 case Intrinsic::loongarch_lasx_xvaddi_wu:
2616 case Intrinsic::loongarch_lasx_xvaddi_du:
2618 lowerVectorSplatImm<5>(
N, 2, DAG));
2619 case Intrinsic::loongarch_lsx_vsub_b:
2620 case Intrinsic::loongarch_lsx_vsub_h:
2621 case Intrinsic::loongarch_lsx_vsub_w:
2622 case Intrinsic::loongarch_lsx_vsub_d:
2623 case Intrinsic::loongarch_lasx_xvsub_b:
2624 case Intrinsic::loongarch_lasx_xvsub_h:
2625 case Intrinsic::loongarch_lasx_xvsub_w:
2626 case Intrinsic::loongarch_lasx_xvsub_d:
2629 case Intrinsic::loongarch_lsx_vsubi_bu:
2630 case Intrinsic::loongarch_lsx_vsubi_hu:
2631 case Intrinsic::loongarch_lsx_vsubi_wu:
2632 case Intrinsic::loongarch_lsx_vsubi_du:
2633 case Intrinsic::loongarch_lasx_xvsubi_bu:
2634 case Intrinsic::loongarch_lasx_xvsubi_hu:
2635 case Intrinsic::loongarch_lasx_xvsubi_wu:
2636 case Intrinsic::loongarch_lasx_xvsubi_du:
2638 lowerVectorSplatImm<5>(
N, 2, DAG));
2639 case Intrinsic::loongarch_lsx_vneg_b:
2640 case Intrinsic::loongarch_lsx_vneg_h:
2641 case Intrinsic::loongarch_lsx_vneg_w:
2642 case Intrinsic::loongarch_lsx_vneg_d:
2643 case Intrinsic::loongarch_lasx_xvneg_b:
2644 case Intrinsic::loongarch_lasx_xvneg_h:
2645 case Intrinsic::loongarch_lasx_xvneg_w:
2646 case Intrinsic::loongarch_lasx_xvneg_d:
2650 APInt(
N->getValueType(0).getScalarType().getSizeInBits(), 0,
2652 SDLoc(
N),
N->getValueType(0)),
2654 case Intrinsic::loongarch_lsx_vmax_b:
2655 case Intrinsic::loongarch_lsx_vmax_h:
2656 case Intrinsic::loongarch_lsx_vmax_w:
2657 case Intrinsic::loongarch_lsx_vmax_d:
2658 case Intrinsic::loongarch_lasx_xvmax_b:
2659 case Intrinsic::loongarch_lasx_xvmax_h:
2660 case Intrinsic::loongarch_lasx_xvmax_w:
2661 case Intrinsic::loongarch_lasx_xvmax_d:
2664 case Intrinsic::loongarch_lsx_vmax_bu:
2665 case Intrinsic::loongarch_lsx_vmax_hu:
2666 case Intrinsic::loongarch_lsx_vmax_wu:
2667 case Intrinsic::loongarch_lsx_vmax_du:
2668 case Intrinsic::loongarch_lasx_xvmax_bu:
2669 case Intrinsic::loongarch_lasx_xvmax_hu:
2670 case Intrinsic::loongarch_lasx_xvmax_wu:
2671 case Intrinsic::loongarch_lasx_xvmax_du:
2674 case Intrinsic::loongarch_lsx_vmaxi_b:
2675 case Intrinsic::loongarch_lsx_vmaxi_h:
2676 case Intrinsic::loongarch_lsx_vmaxi_w:
2677 case Intrinsic::loongarch_lsx_vmaxi_d:
2678 case Intrinsic::loongarch_lasx_xvmaxi_b:
2679 case Intrinsic::loongarch_lasx_xvmaxi_h:
2680 case Intrinsic::loongarch_lasx_xvmaxi_w:
2681 case Intrinsic::loongarch_lasx_xvmaxi_d:
2683 lowerVectorSplatImm<5>(
N, 2, DAG,
true));
2684 case Intrinsic::loongarch_lsx_vmaxi_bu:
2685 case Intrinsic::loongarch_lsx_vmaxi_hu:
2686 case Intrinsic::loongarch_lsx_vmaxi_wu:
2687 case Intrinsic::loongarch_lsx_vmaxi_du:
2688 case Intrinsic::loongarch_lasx_xvmaxi_bu:
2689 case Intrinsic::loongarch_lasx_xvmaxi_hu:
2690 case Intrinsic::loongarch_lasx_xvmaxi_wu:
2691 case Intrinsic::loongarch_lasx_xvmaxi_du:
2693 lowerVectorSplatImm<5>(
N, 2, DAG));
2694 case Intrinsic::loongarch_lsx_vmin_b:
2695 case Intrinsic::loongarch_lsx_vmin_h:
2696 case Intrinsic::loongarch_lsx_vmin_w:
2697 case Intrinsic::loongarch_lsx_vmin_d:
2698 case Intrinsic::loongarch_lasx_xvmin_b:
2699 case Intrinsic::loongarch_lasx_xvmin_h:
2700 case Intrinsic::loongarch_lasx_xvmin_w:
2701 case Intrinsic::loongarch_lasx_xvmin_d:
2704 case Intrinsic::loongarch_lsx_vmin_bu:
2705 case Intrinsic::loongarch_lsx_vmin_hu:
2706 case Intrinsic::loongarch_lsx_vmin_wu:
2707 case Intrinsic::loongarch_lsx_vmin_du:
2708 case Intrinsic::loongarch_lasx_xvmin_bu:
2709 case Intrinsic::loongarch_lasx_xvmin_hu:
2710 case Intrinsic::loongarch_lasx_xvmin_wu:
2711 case Intrinsic::loongarch_lasx_xvmin_du:
2714 case Intrinsic::loongarch_lsx_vmini_b:
2715 case Intrinsic::loongarch_lsx_vmini_h:
2716 case Intrinsic::loongarch_lsx_vmini_w:
2717 case Intrinsic::loongarch_lsx_vmini_d:
2718 case Intrinsic::loongarch_lasx_xvmini_b:
2719 case Intrinsic::loongarch_lasx_xvmini_h:
2720 case Intrinsic::loongarch_lasx_xvmini_w:
2721 case Intrinsic::loongarch_lasx_xvmini_d:
2723 lowerVectorSplatImm<5>(
N, 2, DAG,
true));
2724 case Intrinsic::loongarch_lsx_vmini_bu:
2725 case Intrinsic::loongarch_lsx_vmini_hu:
2726 case Intrinsic::loongarch_lsx_vmini_wu:
2727 case Intrinsic::loongarch_lsx_vmini_du:
2728 case Intrinsic::loongarch_lasx_xvmini_bu:
2729 case Intrinsic::loongarch_lasx_xvmini_hu:
2730 case Intrinsic::loongarch_lasx_xvmini_wu:
2731 case Intrinsic::loongarch_lasx_xvmini_du:
2733 lowerVectorSplatImm<5>(
N, 2, DAG));
2734 case Intrinsic::loongarch_lsx_vmul_b:
2735 case Intrinsic::loongarch_lsx_vmul_h:
2736 case Intrinsic::loongarch_lsx_vmul_w:
2737 case Intrinsic::loongarch_lsx_vmul_d:
2738 case Intrinsic::loongarch_lasx_xvmul_b:
2739 case Intrinsic::loongarch_lasx_xvmul_h:
2740 case Intrinsic::loongarch_lasx_xvmul_w:
2741 case Intrinsic::loongarch_lasx_xvmul_d:
2744 case Intrinsic::loongarch_lsx_vmadd_b:
2745 case Intrinsic::loongarch_lsx_vmadd_h:
2746 case Intrinsic::loongarch_lsx_vmadd_w:
2747 case Intrinsic::loongarch_lsx_vmadd_d:
2748 case Intrinsic::loongarch_lasx_xvmadd_b:
2749 case Intrinsic::loongarch_lasx_xvmadd_h:
2750 case Intrinsic::loongarch_lasx_xvmadd_w:
2751 case Intrinsic::loongarch_lasx_xvmadd_d: {
2752 EVT ResTy =
N->getValueType(0);
2757 case Intrinsic::loongarch_lsx_vmsub_b:
2758 case Intrinsic::loongarch_lsx_vmsub_h:
2759 case Intrinsic::loongarch_lsx_vmsub_w:
2760 case Intrinsic::loongarch_lsx_vmsub_d:
2761 case Intrinsic::loongarch_lasx_xvmsub_b:
2762 case Intrinsic::loongarch_lasx_xvmsub_h:
2763 case Intrinsic::loongarch_lasx_xvmsub_w:
2764 case Intrinsic::loongarch_lasx_xvmsub_d: {
2765 EVT ResTy =
N->getValueType(0);
2770 case Intrinsic::loongarch_lsx_vdiv_b:
2771 case Intrinsic::loongarch_lsx_vdiv_h:
2772 case Intrinsic::loongarch_lsx_vdiv_w:
2773 case Intrinsic::loongarch_lsx_vdiv_d:
2774 case Intrinsic::loongarch_lasx_xvdiv_b:
2775 case Intrinsic::loongarch_lasx_xvdiv_h:
2776 case Intrinsic::loongarch_lasx_xvdiv_w:
2777 case Intrinsic::loongarch_lasx_xvdiv_d:
2780 case Intrinsic::loongarch_lsx_vdiv_bu:
2781 case Intrinsic::loongarch_lsx_vdiv_hu:
2782 case Intrinsic::loongarch_lsx_vdiv_wu:
2783 case Intrinsic::loongarch_lsx_vdiv_du:
2784 case Intrinsic::loongarch_lasx_xvdiv_bu:
2785 case Intrinsic::loongarch_lasx_xvdiv_hu:
2786 case Intrinsic::loongarch_lasx_xvdiv_wu:
2787 case Intrinsic::loongarch_lasx_xvdiv_du:
2790 case Intrinsic::loongarch_lsx_vmod_b:
2791 case Intrinsic::loongarch_lsx_vmod_h:
2792 case Intrinsic::loongarch_lsx_vmod_w:
2793 case Intrinsic::loongarch_lsx_vmod_d:
2794 case Intrinsic::loongarch_lasx_xvmod_b:
2795 case Intrinsic::loongarch_lasx_xvmod_h:
2796 case Intrinsic::loongarch_lasx_xvmod_w:
2797 case Intrinsic::loongarch_lasx_xvmod_d:
2800 case Intrinsic::loongarch_lsx_vmod_bu:
2801 case Intrinsic::loongarch_lsx_vmod_hu:
2802 case Intrinsic::loongarch_lsx_vmod_wu:
2803 case Intrinsic::loongarch_lsx_vmod_du:
2804 case Intrinsic::loongarch_lasx_xvmod_bu:
2805 case Intrinsic::loongarch_lasx_xvmod_hu:
2806 case Intrinsic::loongarch_lasx_xvmod_wu:
2807 case Intrinsic::loongarch_lasx_xvmod_du:
2810 case Intrinsic::loongarch_lsx_vand_v:
2811 case Intrinsic::loongarch_lasx_xvand_v:
2814 case Intrinsic::loongarch_lsx_vor_v:
2815 case Intrinsic::loongarch_lasx_xvor_v:
2818 case Intrinsic::loongarch_lsx_vxor_v:
2819 case Intrinsic::loongarch_lasx_xvxor_v:
2822 case Intrinsic::loongarch_lsx_vnor_v:
2823 case Intrinsic::loongarch_lasx_xvnor_v: {
2828 case Intrinsic::loongarch_lsx_vandi_b:
2829 case Intrinsic::loongarch_lasx_xvandi_b:
2831 lowerVectorSplatImm<8>(
N, 2, DAG));
2832 case Intrinsic::loongarch_lsx_vori_b:
2833 case Intrinsic::loongarch_lasx_xvori_b:
2835 lowerVectorSplatImm<8>(
N, 2, DAG));
2836 case Intrinsic::loongarch_lsx_vxori_b:
2837 case Intrinsic::loongarch_lasx_xvxori_b:
2839 lowerVectorSplatImm<8>(
N, 2, DAG));
2840 case Intrinsic::loongarch_lsx_vsll_b:
2841 case Intrinsic::loongarch_lsx_vsll_h:
2842 case Intrinsic::loongarch_lsx_vsll_w:
2843 case Intrinsic::loongarch_lsx_vsll_d:
2844 case Intrinsic::loongarch_lasx_xvsll_b:
2845 case Intrinsic::loongarch_lasx_xvsll_h:
2846 case Intrinsic::loongarch_lasx_xvsll_w:
2847 case Intrinsic::loongarch_lasx_xvsll_d:
2850 case Intrinsic::loongarch_lsx_vslli_b:
2851 case Intrinsic::loongarch_lasx_xvslli_b:
2853 lowerVectorSplatImm<3>(
N, 2, DAG));
2854 case Intrinsic::loongarch_lsx_vslli_h:
2855 case Intrinsic::loongarch_lasx_xvslli_h:
2857 lowerVectorSplatImm<4>(
N, 2, DAG));
2858 case Intrinsic::loongarch_lsx_vslli_w:
2859 case Intrinsic::loongarch_lasx_xvslli_w:
2861 lowerVectorSplatImm<5>(
N, 2, DAG));
2862 case Intrinsic::loongarch_lsx_vslli_d:
2863 case Intrinsic::loongarch_lasx_xvslli_d:
2865 lowerVectorSplatImm<6>(
N, 2, DAG));
2866 case Intrinsic::loongarch_lsx_vsrl_b:
2867 case Intrinsic::loongarch_lsx_vsrl_h:
2868 case Intrinsic::loongarch_lsx_vsrl_w:
2869 case Intrinsic::loongarch_lsx_vsrl_d:
2870 case Intrinsic::loongarch_lasx_xvsrl_b:
2871 case Intrinsic::loongarch_lasx_xvsrl_h:
2872 case Intrinsic::loongarch_lasx_xvsrl_w:
2873 case Intrinsic::loongarch_lasx_xvsrl_d:
2876 case Intrinsic::loongarch_lsx_vsrli_b:
2877 case Intrinsic::loongarch_lasx_xvsrli_b:
2879 lowerVectorSplatImm<3>(
N, 2, DAG));
2880 case Intrinsic::loongarch_lsx_vsrli_h:
2881 case Intrinsic::loongarch_lasx_xvsrli_h:
2883 lowerVectorSplatImm<4>(
N, 2, DAG));
2884 case Intrinsic::loongarch_lsx_vsrli_w:
2885 case Intrinsic::loongarch_lasx_xvsrli_w:
2887 lowerVectorSplatImm<5>(
N, 2, DAG));
2888 case Intrinsic::loongarch_lsx_vsrli_d:
2889 case Intrinsic::loongarch_lasx_xvsrli_d:
2891 lowerVectorSplatImm<6>(
N, 2, DAG));
2892 case Intrinsic::loongarch_lsx_vsra_b:
2893 case Intrinsic::loongarch_lsx_vsra_h:
2894 case Intrinsic::loongarch_lsx_vsra_w:
2895 case Intrinsic::loongarch_lsx_vsra_d:
2896 case Intrinsic::loongarch_lasx_xvsra_b:
2897 case Intrinsic::loongarch_lasx_xvsra_h:
2898 case Intrinsic::loongarch_lasx_xvsra_w:
2899 case Intrinsic::loongarch_lasx_xvsra_d:
2902 case Intrinsic::loongarch_lsx_vsrai_b:
2903 case Intrinsic::loongarch_lasx_xvsrai_b:
2905 lowerVectorSplatImm<3>(
N, 2, DAG));
2906 case Intrinsic::loongarch_lsx_vsrai_h:
2907 case Intrinsic::loongarch_lasx_xvsrai_h:
2909 lowerVectorSplatImm<4>(
N, 2, DAG));
2910 case Intrinsic::loongarch_lsx_vsrai_w:
2911 case Intrinsic::loongarch_lasx_xvsrai_w:
2913 lowerVectorSplatImm<5>(
N, 2, DAG));
2914 case Intrinsic::loongarch_lsx_vsrai_d:
2915 case Intrinsic::loongarch_lasx_xvsrai_d:
2917 lowerVectorSplatImm<6>(
N, 2, DAG));
2918 case Intrinsic::loongarch_lsx_vclz_b:
2919 case Intrinsic::loongarch_lsx_vclz_h:
2920 case Intrinsic::loongarch_lsx_vclz_w:
2921 case Intrinsic::loongarch_lsx_vclz_d:
2922 case Intrinsic::loongarch_lasx_xvclz_b:
2923 case Intrinsic::loongarch_lasx_xvclz_h:
2924 case Intrinsic::loongarch_lasx_xvclz_w:
2925 case Intrinsic::loongarch_lasx_xvclz_d:
2927 case Intrinsic::loongarch_lsx_vpcnt_b:
2928 case Intrinsic::loongarch_lsx_vpcnt_h:
2929 case Intrinsic::loongarch_lsx_vpcnt_w:
2930 case Intrinsic::loongarch_lsx_vpcnt_d:
2931 case Intrinsic::loongarch_lasx_xvpcnt_b:
2932 case Intrinsic::loongarch_lasx_xvpcnt_h:
2933 case Intrinsic::loongarch_lasx_xvpcnt_w:
2934 case Intrinsic::loongarch_lasx_xvpcnt_d:
2936 case Intrinsic::loongarch_lsx_vbitclr_b:
2937 case Intrinsic::loongarch_lsx_vbitclr_h:
2938 case Intrinsic::loongarch_lsx_vbitclr_w:
2939 case Intrinsic::loongarch_lsx_vbitclr_d:
2940 case Intrinsic::loongarch_lasx_xvbitclr_b:
2941 case Intrinsic::loongarch_lasx_xvbitclr_h:
2942 case Intrinsic::loongarch_lasx_xvbitclr_w:
2943 case Intrinsic::loongarch_lasx_xvbitclr_d:
2945 case Intrinsic::loongarch_lsx_vbitclri_b:
2946 case Intrinsic::loongarch_lasx_xvbitclri_b:
2947 return lowerVectorBitClearImm<3>(
N, DAG);
2948 case Intrinsic::loongarch_lsx_vbitclri_h:
2949 case Intrinsic::loongarch_lasx_xvbitclri_h:
2950 return lowerVectorBitClearImm<4>(
N, DAG);
2951 case Intrinsic::loongarch_lsx_vbitclri_w:
2952 case Intrinsic::loongarch_lasx_xvbitclri_w:
2953 return lowerVectorBitClearImm<5>(
N, DAG);
2954 case Intrinsic::loongarch_lsx_vbitclri_d:
2955 case Intrinsic::loongarch_lasx_xvbitclri_d:
2956 return lowerVectorBitClearImm<6>(
N, DAG);
2957 case Intrinsic::loongarch_lsx_vbitset_b:
2958 case Intrinsic::loongarch_lsx_vbitset_h:
2959 case Intrinsic::loongarch_lsx_vbitset_w:
2960 case Intrinsic::loongarch_lsx_vbitset_d:
2961 case Intrinsic::loongarch_lasx_xvbitset_b:
2962 case Intrinsic::loongarch_lasx_xvbitset_h:
2963 case Intrinsic::loongarch_lasx_xvbitset_w:
2964 case Intrinsic::loongarch_lasx_xvbitset_d: {
2965 EVT VecTy =
N->getValueType(0);
2971 case Intrinsic::loongarch_lsx_vbitseti_b:
2972 case Intrinsic::loongarch_lasx_xvbitseti_b:
2973 return lowerVectorBitSetImm<3>(
N, DAG);
2974 case Intrinsic::loongarch_lsx_vbitseti_h:
2975 case Intrinsic::loongarch_lasx_xvbitseti_h:
2976 return lowerVectorBitSetImm<4>(
N, DAG);
2977 case Intrinsic::loongarch_lsx_vbitseti_w:
2978 case Intrinsic::loongarch_lasx_xvbitseti_w:
2979 return lowerVectorBitSetImm<5>(
N, DAG);
2980 case Intrinsic::loongarch_lsx_vbitseti_d:
2981 case Intrinsic::loongarch_lasx_xvbitseti_d:
2982 return lowerVectorBitSetImm<6>(
N, DAG);
2983 case Intrinsic::loongarch_lsx_vbitrev_b:
2984 case Intrinsic::loongarch_lsx_vbitrev_h:
2985 case Intrinsic::loongarch_lsx_vbitrev_w:
2986 case Intrinsic::loongarch_lsx_vbitrev_d:
2987 case Intrinsic::loongarch_lasx_xvbitrev_b:
2988 case Intrinsic::loongarch_lasx_xvbitrev_h:
2989 case Intrinsic::loongarch_lasx_xvbitrev_w:
2990 case Intrinsic::loongarch_lasx_xvbitrev_d: {
2991 EVT VecTy =
N->getValueType(0);
2997 case Intrinsic::loongarch_lsx_vbitrevi_b:
2998 case Intrinsic::loongarch_lasx_xvbitrevi_b:
2999 return lowerVectorBitRevImm<3>(
N, DAG);
3000 case Intrinsic::loongarch_lsx_vbitrevi_h:
3001 case Intrinsic::loongarch_lasx_xvbitrevi_h:
3002 return lowerVectorBitRevImm<4>(
N, DAG);
3003 case Intrinsic::loongarch_lsx_vbitrevi_w:
3004 case Intrinsic::loongarch_lasx_xvbitrevi_w:
3005 return lowerVectorBitRevImm<5>(
N, DAG);
3006 case Intrinsic::loongarch_lsx_vbitrevi_d:
3007 case Intrinsic::loongarch_lasx_xvbitrevi_d:
3008 return lowerVectorBitRevImm<6>(
N, DAG);
3009 case Intrinsic::loongarch_lsx_vfadd_s:
3010 case Intrinsic::loongarch_lsx_vfadd_d:
3011 case Intrinsic::loongarch_lasx_xvfadd_s:
3012 case Intrinsic::loongarch_lasx_xvfadd_d:
3015 case Intrinsic::loongarch_lsx_vfsub_s:
3016 case Intrinsic::loongarch_lsx_vfsub_d:
3017 case Intrinsic::loongarch_lasx_xvfsub_s:
3018 case Intrinsic::loongarch_lasx_xvfsub_d:
3021 case Intrinsic::loongarch_lsx_vfmul_s:
3022 case Intrinsic::loongarch_lsx_vfmul_d:
3023 case Intrinsic::loongarch_lasx_xvfmul_s:
3024 case Intrinsic::loongarch_lasx_xvfmul_d:
3027 case Intrinsic::loongarch_lsx_vfdiv_s:
3028 case Intrinsic::loongarch_lsx_vfdiv_d:
3029 case Intrinsic::loongarch_lasx_xvfdiv_s:
3030 case Intrinsic::loongarch_lasx_xvfdiv_d:
3033 case Intrinsic::loongarch_lsx_vfmadd_s:
3034 case Intrinsic::loongarch_lsx_vfmadd_d:
3035 case Intrinsic::loongarch_lasx_xvfmadd_s:
3036 case Intrinsic::loongarch_lasx_xvfmadd_d:
3038 N->getOperand(2),
N->getOperand(3));
3039 case Intrinsic::loongarch_lsx_vinsgr2vr_b:
3041 N->getOperand(1),
N->getOperand(2),
3042 legalizeIntrinsicImmArg<4>(
N, 3, DAG, Subtarget));
3043 case Intrinsic::loongarch_lsx_vinsgr2vr_h:
3044 case Intrinsic::loongarch_lasx_xvinsgr2vr_w:
3046 N->getOperand(1),
N->getOperand(2),
3047 legalizeIntrinsicImmArg<3>(
N, 3, DAG, Subtarget));
3048 case Intrinsic::loongarch_lsx_vinsgr2vr_w:
3049 case Intrinsic::loongarch_lasx_xvinsgr2vr_d:
3051 N->getOperand(1),
N->getOperand(2),
3052 legalizeIntrinsicImmArg<2>(
N, 3, DAG, Subtarget));
3053 case Intrinsic::loongarch_lsx_vinsgr2vr_d:
3055 N->getOperand(1),
N->getOperand(2),
3056 legalizeIntrinsicImmArg<1>(
N, 3, DAG, Subtarget));
3057 case Intrinsic::loongarch_lsx_vreplgr2vr_b:
3058 case Intrinsic::loongarch_lsx_vreplgr2vr_h:
3059 case Intrinsic::loongarch_lsx_vreplgr2vr_w:
3060 case Intrinsic::loongarch_lsx_vreplgr2vr_d:
3061 case Intrinsic::loongarch_lasx_xvreplgr2vr_b:
3062 case Intrinsic::loongarch_lasx_xvreplgr2vr_h:
3063 case Intrinsic::loongarch_lasx_xvreplgr2vr_w:
3064 case Intrinsic::loongarch_lasx_xvreplgr2vr_d: {
3065 EVT ResTy =
N->getValueType(0);
3069 case Intrinsic::loongarch_lsx_vreplve_b:
3070 case Intrinsic::loongarch_lsx_vreplve_h:
3071 case Intrinsic::loongarch_lsx_vreplve_w:
3072 case Intrinsic::loongarch_lsx_vreplve_d:
3073 case Intrinsic::loongarch_lasx_xvreplve_b:
3074 case Intrinsic::loongarch_lasx_xvreplve_h:
3075 case Intrinsic::loongarch_lasx_xvreplve_w:
3076 case Intrinsic::loongarch_lasx_xvreplve_d:
3088 switch (
N->getOpcode()) {
3123 MF->
insert(It, BreakMBB);
3127 SinkMBB->splice(SinkMBB->end(),
MBB, std::next(
MI.getIterator()),
MBB->
end());
3128 SinkMBB->transferSuccessorsAndUpdatePHIs(
MBB);
3146 BreakMBB->addSuccessor(SinkMBB);
3158 switch (
MI.getOpcode()) {
3161 case LoongArch::PseudoVBZ:
3162 CondOpc = LoongArch::VSETEQZ_V;
3164 case LoongArch::PseudoVBZ_B:
3165 CondOpc = LoongArch::VSETANYEQZ_B;
3167 case LoongArch::PseudoVBZ_H:
3168 CondOpc = LoongArch::VSETANYEQZ_H;
3170 case LoongArch::PseudoVBZ_W:
3171 CondOpc = LoongArch::VSETANYEQZ_W;
3173 case LoongArch::PseudoVBZ_D:
3174 CondOpc = LoongArch::VSETANYEQZ_D;
3176 case LoongArch::PseudoVBNZ:
3177 CondOpc = LoongArch::VSETNEZ_V;
3179 case LoongArch::PseudoVBNZ_B:
3180 CondOpc = LoongArch::VSETALLNEZ_B;
3182 case LoongArch::PseudoVBNZ_H:
3183 CondOpc = LoongArch::VSETALLNEZ_H;
3185 case LoongArch::PseudoVBNZ_W:
3186 CondOpc = LoongArch::VSETALLNEZ_W;
3188 case LoongArch::PseudoVBNZ_D:
3189 CondOpc = LoongArch::VSETALLNEZ_D;
3191 case LoongArch::PseudoXVBZ:
3192 CondOpc = LoongArch::XVSETEQZ_V;
3194 case LoongArch::PseudoXVBZ_B:
3195 CondOpc = LoongArch::XVSETANYEQZ_B;
3197 case LoongArch::PseudoXVBZ_H:
3198 CondOpc = LoongArch::XVSETANYEQZ_H;
3200 case LoongArch::PseudoXVBZ_W:
3201 CondOpc = LoongArch::XVSETANYEQZ_W;
3203 case LoongArch::PseudoXVBZ_D:
3204 CondOpc = LoongArch::XVSETANYEQZ_D;
3206 case LoongArch::PseudoXVBNZ:
3207 CondOpc = LoongArch::XVSETNEZ_V;
3209 case LoongArch::PseudoXVBNZ_B:
3210 CondOpc = LoongArch::XVSETALLNEZ_B;
3212 case LoongArch::PseudoXVBNZ_H:
3213 CondOpc = LoongArch::XVSETALLNEZ_H;
3215 case LoongArch::PseudoXVBNZ_W:
3216 CondOpc = LoongArch::XVSETALLNEZ_W;
3218 case LoongArch::PseudoXVBNZ_D:
3219 CondOpc = LoongArch::XVSETALLNEZ_D;
3234 F->insert(It, FalseBB);
3235 F->insert(It, TrueBB);
3236 F->insert(It, SinkBB);
3239 SinkBB->
splice(SinkBB->
end(), BB, std::next(
MI.getIterator()), BB->
end());
3243 Register FCC =
MRI.createVirtualRegister(&LoongArch::CFRRegClass);
3252 Register RD1 =
MRI.createVirtualRegister(&LoongArch::GPRRegClass);
3260 Register RD2 =
MRI.createVirtualRegister(&LoongArch::GPRRegClass);
3268 MI.getOperand(0).getReg())
3275 MI.eraseFromParent();
3284 switch (
MI.getOpcode()) {
3287 case LoongArch::PseudoXVINSGR2VR_B:
3289 InsOp = LoongArch::VINSGR2VR_B;
3291 case LoongArch::PseudoXVINSGR2VR_H:
3293 InsOp = LoongArch::VINSGR2VR_H;
3305 unsigned Idx =
MI.getOperand(3).getImm();
3308 if (
Idx >= HalfSize) {
3309 ScratchReg1 =
MRI.createVirtualRegister(RC);
3310 BuildMI(*BB,
MI,
DL,
TII->get(LoongArch::XVPERMI_Q), ScratchReg1)
3316 Register ScratchSubReg1 =
MRI.createVirtualRegister(SubRC);
3317 Register ScratchSubReg2 =
MRI.createVirtualRegister(SubRC);
3319 .
addReg(ScratchReg1, 0, LoongArch::sub_128);
3326 if (
Idx >= HalfSize)
3327 ScratchReg2 =
MRI.createVirtualRegister(RC);
3329 BuildMI(*BB,
MI,
DL,
TII->get(LoongArch::SUBREG_TO_REG), ScratchReg2)
3332 .
addImm(LoongArch::sub_128);
3334 if (
Idx >= HalfSize)
3340 MI.eraseFromParent();
3349 switch (
MI.getOpcode()) {
3352 case LoongArch::DIV_W:
3353 case LoongArch::DIV_WU:
3354 case LoongArch::MOD_W:
3355 case LoongArch::MOD_WU:
3356 case LoongArch::DIV_D:
3357 case LoongArch::DIV_DU:
3358 case LoongArch::MOD_D:
3359 case LoongArch::MOD_DU:
3362 case LoongArch::WRFCSR: {
3364 LoongArch::FCSR0 +
MI.getOperand(0).getImm())
3365 .
addReg(
MI.getOperand(1).getReg());
3366 MI.eraseFromParent();
3369 case LoongArch::RDFCSR: {
3372 MI.getOperand(0).getReg())
3373 .
addReg(LoongArch::FCSR0 +
MI.getOperand(1).getImm());
3375 MI.eraseFromParent();
3378 case LoongArch::PseudoVBZ:
3379 case LoongArch::PseudoVBZ_B:
3380 case LoongArch::PseudoVBZ_H:
3381 case LoongArch::PseudoVBZ_W:
3382 case LoongArch::PseudoVBZ_D:
3383 case LoongArch::PseudoVBNZ:
3384 case LoongArch::PseudoVBNZ_B:
3385 case LoongArch::PseudoVBNZ_H:
3386 case LoongArch::PseudoVBNZ_W:
3387 case LoongArch::PseudoVBNZ_D:
3388 case LoongArch::PseudoXVBZ:
3389 case LoongArch::PseudoXVBZ_B:
3390 case LoongArch::PseudoXVBZ_H:
3391 case LoongArch::PseudoXVBZ_W:
3392 case LoongArch::PseudoXVBZ_D:
3393 case LoongArch::PseudoXVBNZ:
3394 case LoongArch::PseudoXVBNZ_B:
3395 case LoongArch::PseudoXVBNZ_H:
3396 case LoongArch::PseudoXVBNZ_W:
3397 case LoongArch::PseudoXVBNZ_D:
3399 case LoongArch::PseudoXVINSGR2VR_B:
3400 case LoongArch::PseudoXVINSGR2VR_H:
3407 unsigned *
Fast)
const {
3408 if (!Subtarget.hasUAL())
3422#define NODE_NAME_CASE(node) \
3423 case LoongArchISD::node: \
3424 return "LoongArchISD::" #node;
3486#undef NODE_NAME_CASE
3499 LoongArch::R7, LoongArch::R8, LoongArch::R9,
3500 LoongArch::R10, LoongArch::R11};
3504 LoongArch::F3, LoongArch::F4, LoongArch::F5,
3505 LoongArch::F6, LoongArch::F7};
3508 LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64,
3509 LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64};
3512 LoongArch::VR3, LoongArch::VR4, LoongArch::VR5,
3513 LoongArch::VR6, LoongArch::VR7};
3516 LoongArch::XR3, LoongArch::XR4, LoongArch::XR5,
3517 LoongArch::XR6, LoongArch::XR7};
3523 unsigned ValNo2,
MVT ValVT2,
MVT LocVT2,
3525 unsigned GRLenInBytes = GRLen / 8;
3558 unsigned ValNo,
MVT ValVT,
3560 CCState &State,
bool IsFixed,
bool IsRet,
3562 unsigned GRLen =
DL.getLargestLegalIntTypeSizeInBits();
3563 assert((GRLen == 32 || GRLen == 64) &&
"Unspport GRLen");
3564 MVT GRLenVT = GRLen == 32 ? MVT::i32 : MVT::i64;
3569 if (IsRet && ValNo > 1)
3573 bool UseGPRForFloat =
true;
3585 UseGPRForFloat = !IsFixed;
3593 UseGPRForFloat =
true;
3595 if (UseGPRForFloat && ValVT == MVT::f32) {
3598 }
else if (UseGPRForFloat && GRLen == 64 && ValVT == MVT::f64) {
3601 }
else if (UseGPRForFloat && GRLen == 32 && ValVT == MVT::f64) {
3612 unsigned TwoGRLenInBytes = (2 * GRLen) / 8;
3614 DL.getTypeAllocSize(OrigTy) == TwoGRLenInBytes) {
3617 if (RegIdx != std::size(
ArgGPRs) && RegIdx % 2 == 1)
3626 "PendingLocs and PendingArgFlags out of sync");
3644 PendingLocs.
size() <= 2) {
3645 assert(PendingLocs.
size() == 2 &&
"Unexpected PendingLocs.size()");
3650 PendingLocs.
clear();
3651 PendingArgFlags.
clear();
3658 unsigned StoreSizeBytes = GRLen / 8;
3661 if (ValVT == MVT::f32 && !UseGPRForFloat)
3663 else if (ValVT == MVT::f64 && !UseGPRForFloat)
3677 if (!PendingLocs.
empty()) {
3679 assert(PendingLocs.
size() > 2 &&
"Unexpected PendingLocs.size()");
3680 for (
auto &It : PendingLocs) {
3682 It.convertToReg(Reg);
3687 PendingLocs.clear();
3688 PendingArgFlags.
clear();
3691 assert((!UseGPRForFloat || LocVT == GRLenVT) &&
3692 "Expected an GRLenVT at this stage");
3709void LoongArchTargetLowering::analyzeInputArgs(
3712 LoongArchCCAssignFn Fn)
const {
3714 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
3716 Type *ArgTy =
nullptr;
3718 ArgTy = FType->getReturnType();
3719 else if (Ins[i].isOrigArg())
3720 ArgTy = FType->getParamType(Ins[i].getOrigArgIndex());
3724 CCInfo,
true, IsRet, ArgTy)) {
3725 LLVM_DEBUG(
dbgs() <<
"InputArg #" << i <<
" has unhandled type " << ArgVT
3732void LoongArchTargetLowering::analyzeOutputArgs(
3735 CallLoweringInfo *CLI, LoongArchCCAssignFn Fn)
const {
3736 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
3737 MVT ArgVT = Outs[i].VT;
3738 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty :
nullptr;
3742 CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
3743 LLVM_DEBUG(
dbgs() <<
"OutputArg #" << i <<
" has unhandled type " << ArgVT
3784 if (In.isOrigArg()) {
3789 if ((
BitWidth <= 32 && In.Flags.isSExt()) ||
3790 (
BitWidth < 32 && In.Flags.isZExt())) {
3850 if (LocVT == MVT::i32 || LocVT == MVT::i64) {
3854 LoongArch::R23, LoongArch::R24, LoongArch::R25,
3855 LoongArch::R26, LoongArch::R27, LoongArch::R28,
3856 LoongArch::R29, LoongArch::R30, LoongArch::R31};
3863 if (LocVT == MVT::f32) {
3866 static const MCPhysReg FPR32List[] = {LoongArch::F24, LoongArch::F25,
3867 LoongArch::F26, LoongArch::F27};
3868 if (
unsigned Reg = State.
AllocateReg(FPR32List)) {
3874 if (LocVT == MVT::f64) {
3877 static const MCPhysReg FPR64List[] = {LoongArch::F28_64, LoongArch::F29_64,
3878 LoongArch::F30_64, LoongArch::F31_64};
3879 if (
unsigned Reg = State.
AllocateReg(FPR64List)) {
3907 "GHC calling convention requires the F and D extensions");
3912 unsigned GRLenInBytes = Subtarget.
getGRLen() / 8;
3914 std::vector<SDValue> OutChains;
3923 analyzeInputArgs(MF, CCInfo, Ins,
false,
CC_LoongArch);
3925 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
3937 unsigned ArgIndex = Ins[i].OrigArgIndex;
3938 unsigned ArgPartOffset = Ins[i].PartOffset;
3939 assert(ArgPartOffset == 0);
3940 while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
3942 unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset;
3965 int VaArgOffset, VarArgsSaveSize;
3971 VarArgsSaveSize = 0;
3973 VarArgsSaveSize = GRLenInBytes * (ArgRegs.
size() -
Idx);
3974 VaArgOffset = -VarArgsSaveSize;
3980 LoongArchFI->setVarArgsFrameIndex(FI);
3988 VarArgsSaveSize += GRLenInBytes;
3993 for (
unsigned I =
Idx;
I < ArgRegs.
size();
3994 ++
I, VaArgOffset += GRLenInBytes) {
4002 cast<StoreSDNode>(Store.getNode())
4004 ->setValue((
Value *)
nullptr);
4005 OutChains.push_back(Store);
4007 LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize);
4012 if (!OutChains.empty()) {
4013 OutChains.push_back(Chain);
4028 if (
N->getNumValues() != 1)
4030 if (!
N->hasNUsesOfValue(1, 0))
4033 SDNode *Copy = *
N->use_begin();
4039 if (Copy->getGluedNode())
4043 bool HasRet =
false;
4044 for (
SDNode *Node : Copy->uses()) {
4053 Chain = Copy->getOperand(0);
4058bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
4062 auto CalleeCC = CLI.CallConv;
4063 auto &Outs = CLI.Outs;
4065 auto CallerCC = Caller.getCallingConv();
4072 for (
auto &VA : ArgLocs)
4078 auto IsCallerStructRet = Caller.hasStructRetAttr();
4079 auto IsCalleeStructRet = Outs.
empty() ?
false : Outs[0].Flags.isSRet();
4080 if (IsCallerStructRet || IsCalleeStructRet)
4084 for (
auto &Arg : Outs)
4085 if (Arg.Flags.isByVal())
4090 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
4091 if (CalleeCC != CallerCC) {
4092 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
4093 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
4131 analyzeOutputArgs(MF, ArgCCInfo, Outs,
false, &CLI,
CC_LoongArch);
4135 IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
4141 "site marked musttail");
4148 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
4150 if (!Flags.isByVal())
4154 unsigned Size = Flags.getByValSize();
4155 Align Alignment = Flags.getNonZeroByValAlign();
4162 Chain = DAG.
getMemcpy(Chain,
DL, FIPtr, Arg, SizeNode, Alignment,
4176 for (
unsigned i = 0, j = 0, e = ArgLocs.
size(); i != e; ++i) {
4178 SDValue ArgValue = OutVals[i];
4191 unsigned ArgIndex = Outs[i].OrigArgIndex;
4192 unsigned ArgPartOffset = Outs[i].PartOffset;
4193 assert(ArgPartOffset == 0);
4198 while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
4199 SDValue PartValue = OutVals[i + 1];
4200 unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset;
4210 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
4214 for (
const auto &Part : Parts) {
4215 SDValue PartValue = Part.first;
4216 SDValue PartOffset = Part.second;
4223 ArgValue = SpillSlot;
4229 if (Flags.isByVal())
4230 ArgValue = ByValArgs[j++];
4237 assert(!IsTailCall &&
"Tail call not allowed if stack is used "
4238 "for passing parameters");
4241 if (!StackPtr.getNode())
4254 if (!MemOpChains.
empty())
4260 for (
auto &Reg : RegsToPass) {
4261 Chain = DAG.
getCopyToReg(Chain,
DL, Reg.first, Reg.second, Glue);
4288 for (
auto &Reg : RegsToPass)
4294 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
4295 assert(Mask &&
"Missing call preserved mask for calling convention");
4313 assert(Subtarget.
is64Bit() &&
"Medium code model requires LA64");
4317 assert(Subtarget.
is64Bit() &&
"Large code model requires LA64");
4340 analyzeInputArgs(MF, RetCCInfo, Ins,
true,
CC_LoongArch);
4343 for (
auto &VA : RVLocs) {
4365 for (
unsigned i = 0, e = Outs.
size(); i != e; ++i) {
4369 Outs[i].Flags, CCInfo,
true,
true,
4396 for (
unsigned i = 0, e = RVLocs.
size(); i < e; ++i) {
4418bool LoongArchTargetLowering::isFPImmLegal(
const APFloat &Imm,
EVT VT,
4419 bool ForCodeSize)
const {
4421 if (VT == MVT::f32 && !Subtarget.hasBasicF())
4423 if (VT == MVT::f64 && !Subtarget.hasBasicD())
4425 return (Imm.isZero() || Imm.isExactlyValue(+1.0));
4436bool LoongArchTargetLowering::shouldInsertFencesForAtomic(
4439 return isa<LoadInst>(
I) || isa<StoreInst>(
I);
4441 if (isa<LoadInst>(
I))
4446 if (isa<StoreInst>(
I)) {
4447 unsigned Size =
I->getOperand(0)->getType()->getIntegerBitWidth();
4464 return Y.getValueType().isScalarInteger() && !isa<ConstantSDNode>(
Y);
4470 unsigned Intrinsic)
const {
4471 switch (Intrinsic) {
4474 case Intrinsic::loongarch_masked_atomicrmw_xchg_i32:
4475 case Intrinsic::loongarch_masked_atomicrmw_add_i32:
4476 case Intrinsic::loongarch_masked_atomicrmw_sub_i32:
4477 case Intrinsic::loongarch_masked_atomicrmw_nand_i32:
4479 Info.memVT = MVT::i32;
4480 Info.ptrVal =
I.getArgOperand(0);
4515 return Intrinsic::loongarch_masked_atomicrmw_xchg_i64;
4517 return Intrinsic::loongarch_masked_atomicrmw_add_i64;
4519 return Intrinsic::loongarch_masked_atomicrmw_sub_i64;
4521 return Intrinsic::loongarch_masked_atomicrmw_nand_i64;
4523 return Intrinsic::loongarch_masked_atomicrmw_umax_i64;
4525 return Intrinsic::loongarch_masked_atomicrmw_umin_i64;
4527 return Intrinsic::loongarch_masked_atomicrmw_max_i64;
4529 return Intrinsic::loongarch_masked_atomicrmw_min_i64;
4539 return Intrinsic::loongarch_masked_atomicrmw_xchg_i32;
4541 return Intrinsic::loongarch_masked_atomicrmw_add_i32;
4543 return Intrinsic::loongarch_masked_atomicrmw_sub_i32;
4545 return Intrinsic::loongarch_masked_atomicrmw_nand_i32;
4566 Value *FailureOrdering =
4570 Intrinsic::ID CmpXchgIntrID = Intrinsic::loongarch_masked_cmpxchg_i64;
4578 MaskedCmpXchg, {AlignedAddr, CmpVal, NewVal, Mask, FailureOrdering});
4602 unsigned GRLen = Subtarget.
getGRLen();
4631 {AlignedAddr, Incr, Mask, SextShamt, Ordering});
4634 Builder.
CreateCall(LlwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering});
4661 const Constant *PersonalityFn)
const {
4662 return LoongArch::R4;
4666 const Constant *PersonalityFn)
const {
4667 return LoongArch::R5;
4675LoongArchTargetLowering::getConstraintType(
StringRef Constraint)
const {
4693 if (Constraint.
size() == 1) {
4694 switch (Constraint[0]) {
4709 if (Constraint ==
"ZC" || Constraint ==
"ZB")
4725std::pair<unsigned, const TargetRegisterClass *>
4726LoongArchTargetLowering::getRegForInlineAsmConstraint(
4730 if (Constraint.
size() == 1) {
4731 switch (Constraint[0]) {
4736 return std::make_pair(0U, &LoongArch::GPRRegClass);
4738 if (Subtarget.hasBasicF() && VT == MVT::f32)
4739 return std::make_pair(0U, &LoongArch::FPR32RegClass);
4740 if (Subtarget.hasBasicD() && VT == MVT::f64)
4741 return std::make_pair(0U, &LoongArch::FPR64RegClass);
4742 if (Subtarget.hasExtLSX() &&
4743 TRI->isTypeLegalForClass(LoongArch::LSX128RegClass, VT))
4744 return std::make_pair(0U, &LoongArch::LSX128RegClass);
4745 if (Subtarget.hasExtLASX() &&
4746 TRI->isTypeLegalForClass(LoongArch::LASX256RegClass, VT))
4747 return std::make_pair(0U, &LoongArch::LASX256RegClass);
4767 bool IsFP = Constraint[2] ==
'f';
4768 std::pair<StringRef, StringRef> Temp = Constraint.
split(
'$');
4769 std::pair<unsigned, const TargetRegisterClass *>
R;
4771 TRI, join_items(
"", Temp.first, Temp.second), VT);
4774 unsigned RegNo =
R.first;
4775 if (LoongArch::F0 <= RegNo && RegNo <= LoongArch::F31) {
4776 if (Subtarget.hasBasicD() && (VT == MVT::f64 || VT == MVT::Other)) {
4777 unsigned DReg = RegNo - LoongArch::F0 + LoongArch::F0_64;
4778 return std::make_pair(DReg, &LoongArch::FPR64RegClass);
4788void LoongArchTargetLowering::LowerAsmOperandForConstraint(
4792 if (Constraint.
size() == 1) {
4793 switch (Constraint[0]) {
4796 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op)) {
4798 if (isInt<16>(CVal))
4805 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op)) {
4807 if (isInt<12>(CVal))
4814 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
4815 if (
C->getZExtValue() == 0)
4821 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op)) {
4823 if (isUInt<12>(CVal))
4835#define GET_REGISTER_MATCHER
4836#include "LoongArchGenAsmMatcher.inc"
4842 std::string NewRegName =
Name.second.str();
4844 if (Reg == LoongArch::NoRegister)
4846 if (Reg == LoongArch::NoRegister)
4850 if (!ReservedRegs.
test(Reg))
4866 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
4867 const APInt &Imm = ConstNode->getAPIntValue();
4869 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
4870 (1 - Imm).isPowerOf2() || (-1 - Imm).isPowerOf2())
4873 if (ConstNode->hasOneUse() &&
4874 ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2() ||
4875 (Imm - 8).isPowerOf2() || (Imm - 16).isPowerOf2()))
4881 if (ConstNode->hasOneUse() && !(Imm.sge(-2048) && Imm.sle(4095))) {
4882 unsigned Shifts = Imm.countr_zero();
4888 APInt ImmPop = Imm.ashr(Shifts);
4889 if (ImmPop == 3 || ImmPop == 5 || ImmPop == 9 || ImmPop == 17)
4893 APInt ImmSmall =
APInt(Imm.getBitWidth(), 1ULL << Shifts,
true);
4894 if ((Imm - ImmSmall).isPowerOf2() || (Imm + ImmSmall).isPowerOf2() ||
4895 (ImmSmall - Imm).isPowerOf2())
4905 Type *Ty,
unsigned AS,
4921 !(isShiftedInt<14, 2>(AM.
BaseOffs) && Subtarget.hasUAL()))
4948 return isInt<12>(Imm);
4952 return isInt<12>(Imm);
4959 if (
auto *LD = dyn_cast<LoadSDNode>(Val)) {
4960 EVT MemVT = LD->getMemoryVT();
4961 if ((MemVT == MVT::i8 || MemVT == MVT::i16) &&
4972 return Subtarget.
is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
4977 if (
Y.getValueType().isVector())
4980 return !isa<ConstantSDNode>(
Y);
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)
static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define NODE_NAME_CASE(node)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
Function Alias Analysis Results
static uint64_t getConstant(const Value *IndexValue)
static SDValue getTargetNode(GlobalAddressSDNode *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flags)
Analysis containing CSE Info
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget, SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &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
const HexagonInstrInfo * TII
static SDValue performINTRINSIC_WO_CHAINCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
const MCPhysReg ArgFPR32s[]
static SDValue emitIntrinsicErrorMessage(SDValue Op, StringRef ErrorMsg, SelectionDAG &DAG)
static cl::opt< bool > ZeroDivCheck("loongarch-check-zero-division", cl::Hidden, cl::desc("Trap on integer division by zero."), cl::init(false))
static void emitErrorAndReplaceIntrinsicResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, StringRef ErrorMsg, bool WithChain=true)
static SDValue checkIntrinsicImmArg(SDValue Op, unsigned ImmOp, SelectionDAG &DAG, bool IsSigned=false)
static Align getPrefTypeAlign(EVT VT, SelectionDAG &DAG)
static bool CC_LoongArch(const DataLayout &DL, LoongArchABI::ABI ABI, unsigned ValNo, MVT ValVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, bool IsRet, Type *OrigTy)
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
static SDValue lowerVectorBitSetImm(SDNode *Node, SelectionDAG &DAG)
#define CRC_CASE_EXT_BINARYOP(NAME, NODE)
static SDValue lowerVectorBitRevImm(SDNode *Node, SelectionDAG &DAG)
static SDValue truncateVecElts(SDNode *Node, SelectionDAG &DAG)
static MachineBasicBlock * insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *MBB)
static SDValue lowerVectorBitClear(SDNode *Node, SelectionDAG &DAG)
static bool CC_LoongArch_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static void replaceVPICKVE2GRResults(SDNode *Node, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, const LoongArchSubtarget &Subtarget, unsigned ResOp)
static SDValue legalizeIntrinsicImmArg(SDNode *Node, unsigned ImmOp, SelectionDAG &DAG, const LoongArchSubtarget &Subtarget, bool IsSigned=false)
static SDValue emitIntrinsicWithChainErrorMessage(SDValue Op, StringRef ErrorMsg, SelectionDAG &DAG)
static bool CC_LoongArchAssign2GRLen(unsigned GRLen, CCState &State, CCValAssign VA1, ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2, MVT ValVT2, MVT LocVT2, ISD::ArgFlagsTy ArgFlags2)
const MCPhysReg ArgFPR64s[]
#define IOCSRWR_CASE(NAME, NODE)
#define CRC_CASE_EXT_UNARYOP(NAME, NODE)
static MachineBasicBlock * emitPseudoXVINSGR2VR(MachineInstr &MI, MachineBasicBlock *BB, const LoongArchSubtarget &Subtarget)
static SDValue lowerVectorSplatImm(SDNode *Node, unsigned ImmOp, SelectionDAG &DAG, bool IsSigned=false)
const MCPhysReg ArgGPRs[]
static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp, unsigned ExtOpc=ISD::ANY_EXTEND)
static void replaceVecCondBranchResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, const LoongArchSubtarget &Subtarget, unsigned ResOp)
#define ASRT_LE_GT_CASE(NAME)
static bool isConstantOrUndef(const SDValue Op)
static MachineBasicBlock * emitVecCondBranchPseudo(MachineInstr &MI, MachineBasicBlock *BB, const LoongArchSubtarget &Subtarget)
static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
#define IOCSRRD_CASE(NAME, NODE)
static SDValue lowerVectorBitClearImm(SDNode *Node, SelectionDAG &DAG)
static bool isConstantOrUndefBUILD_VECTOR(const BuildVectorSDNode *Op)
static void replaceINTRINSIC_WO_CHAINResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG, const LoongArchSubtarget &Subtarget)
static Intrinsic::ID getIntrinsicForMaskedAtomicRMWBinOp(unsigned GRLen, AtomicRMWInst::BinOp BinOp)
static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode)
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getCompareOperand()
AtomicOrdering getFailureOrdering() const
Returns the failure ordering constraint of this cmpxchg instruction.
an instruction that atomically reads a memory location, combines it with another value,...
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ Min
*p = old <signed v ? old : v
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ UMax
*p = old >unsigned v ? old : v
@ UDecWrap
Decrement one until a minimum value or zero.
bool isFloatingPointOperation() const
BinOp getOperation() const
AtomicOrdering getOrdering() const
Returns the ordering constraint of this rmw instruction.
LLVM Basic Block Representation.
bool test(unsigned Idx) const
A "pseudo-class" with methods for operating on BUILD_VECTORs.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
SmallVectorImpl< ISD::ArgFlagsTy > & getPendingArgFlags()
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
SmallVectorImpl< CCValAssign > & getPendingLocs()
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
uint64_t getZExtValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Argument * getArg(unsigned i) const
Common base class shared among various IRBuilders.
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
AtomicRMWInst * CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
void emitError(uint64_t LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
LoongArchMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private Lo...
void addSExt32Register(Register Reg)
const LoongArchRegisterInfo * getRegisterInfo() const override
const LoongArchInstrInfo * getInstrInfo() const override
unsigned getMaxBytesForAlignment() const
Align getPrefFunctionAlignment() const
unsigned getGRLen() const
Align getPrefLoopAlignment() const
bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override
Return true if result of the specified node is used by a return node only.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override
Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension.
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Determine if the target supports unaligned memory accesses.
bool isCheapToSpeculateCtlz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic ctlz.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
bool isCheapToSpeculateCttz(Type *Ty) const override
Return true if it is cheap to speculate a call to intrinsic cttz.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
ISD::NodeType getExtendForAtomicCmpSwapArg() const override
Returns how the platform's atomic compare and swap expects its comparison value to be extended (ZERO_...
LoongArchTargetLowering(const TargetMachine &TM, const LoongArchSubtarget &STI)
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
bool hasAndNotCompare(SDValue Y) const override
Return true if the target should transform: (X & Y) == Y —> (~X & Y) == 0 (X & Y) !...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool hasFeature(unsigned Feature) const
bool is128BitVector() const
Return true if this is a 128-bit vector type.
bool isVector() const
Return true if this is a vector value type.
static auto fixedlen_vector_valuetypes()
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setIsKill(bool Val=true)
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
size_t use_size() const
Return the number of uses of this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getScalarValueSizeInBits() const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
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 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,...
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
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 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 getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setMaxBytesForAlignment(unsigned MaxBytes)
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const
Return how we should legalize values of this type, either it is already legal (return 'Legal') or we ...
std::vector< ArgListEntry > ArgListTy
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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).
virtual InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
bool useTLSDESC() const
Returns true if this target uses TLS Descriptors.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ 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.
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ UNDEF
UNDEF - An undefined node.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
ABI getTargetABI(StringRef ABIName)
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
AtomicOrdering
Atomic ordering for LLVM's memory model.
unsigned getKillRegState(bool B)
DWARFExpression::Operation Op
constexpr unsigned BitWidth
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getFloatingPointVT(unsigned BitWidth)
Returns the EVT that represents a floating-point type with the given number of bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Align getNonZeroOrigAlign() const
Register getFrameRegister(const MachineFunction &MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
This structure is used to pass arguments to makeLibCall function.
MakeLibCallOptions & setTypeListBeforeSoften(ArrayRef< EVT > OpsVT, EVT RetVT, bool Value=true)