107 std::initializer_list<LLT> PackedVectorAllTypeList = {
113 std::initializer_list<LLT> ScalarAndPtrTypesList = {s8, s16, s32, s64, p0};
117 const TargetMachine &TM = ST.getTargetLowering()->getTargetMachine();
120 if (!ST.hasNEON() || !ST.hasFPARMv8())
125 const bool HasFP16 = ST.hasFullFP16();
126 const bool HasCSSC = ST.hasCSSC();
127 const bool HasRCPC3 = ST.hasRCPC3();
128 const bool HasSVE = ST.hasSVE();
131 {G_IMPLICIT_DEF, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
132 .legalFor({p0, s8, s16, s32, s64, s128})
133 .legalFor({v2s8, v4s8, v8s8, v16s8, v2s16, v4s16, v8s16, v2s32, v4s32,
135 .widenScalarToNextPow2(0)
148 .legalFor(PackedVectorAllTypeList)
163 .widenScalarToNextPow2(0)
168 .maxScalarIf(
typeInSet(0, {s64, p0}), 1, s32);
173 .widenScalarToNextPow2(1)
178 .maxScalarIf(
typeInSet(1, {s64, p0}), 0, s32)
179 .maxScalarIf(
typeInSet(1, {s128}), 0, s64);
182 .legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
183 .legalFor(HasSVE, {nxv16i8, nxv8i16, nxv4i32, nxv2i64})
184 .widenScalarToNextPow2(0)
192 return Query.
Types[0].getNumElements() <= 2;
197 return Query.
Types[0].getNumElements() <= 4;
202 return Query.
Types[0].getNumElements() <= 16;
209 .
legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
210 .widenScalarToNextPow2(0)
218 return Query.
Types[0].getNumElements() <= 2;
223 return Query.
Types[0].getNumElements() <= 4;
228 return Query.
Types[0].getNumElements() <= 16;
236 const auto &SrcTy = Query.
Types[0];
237 const auto &AmtTy = Query.
Types[1];
238 return !SrcTy.isVector() && SrcTy.getSizeInBits() == 32 &&
239 AmtTy.getSizeInBits() == 32;
253 .widenScalarToNextPow2(1)
268 .
legalFor({{p0, i64}, {v2p0, v2i64}})
269 .clampScalarOrElt(1, s64, s64)
275 .legalFor({i32, i64})
277 .clampScalar(0, s32, s64)
282 .lowerFor({i8, i16, i32, i64, v2i32, v4i32, v2i64})
291 .widenScalarToNextPow2(0, 32)
296 .legalFor({i64, v16i8, v8i16, v4i32})
300 {G_SMULFIX, G_UMULFIX, G_SMULFIXSAT, G_UMULFIXSAT})
304 .legalFor({v8i8, v16i8, v4i16, v8i16, v2i32, v4i32})
305 .legalFor(HasCSSC, {i32, i64})
306 .minScalar(HasCSSC, 0, s32)
315 .legalFor({v16i8, v8i16, v4i32, v2i64, v2p0, v8i8, v4i16, v2i32})
319 return SrcTy.isScalar() && SrcTy.getSizeInBits() < 128;
323 [=](
const LegalityQuery &Query) {
return std::make_pair(0, v4i16); })
326 [=](
const LegalityQuery &Query) {
return std::make_pair(0, v2i32); })
327 .clampNumElements(0, v8s8, v16s8)
335 {G_ABDS, G_ABDU, G_UAVGFLOOR, G_UAVGCEIL, G_SAVGFLOOR, G_SAVGCEIL})
336 .legalFor({v8i8, v16i8, v4i16, v8i16, v2i32, v4i32})
340 {G_SADDE, G_SSUBE, G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_UADDO, G_USUBO})
341 .legalFor({{i32, i32}, {i64, i32}})
342 .clampScalar(0, s32, s64)
348 .customFor({{i32, i32}, {i32, i64}, {i64, i64}})
354 return Q.
Types[0].isScalar() && Q.
Types[1].getScalarSizeInBits() < 64;
360 .customFor({{s32, s32}, {s64, s64}});
364 .
legalFor(HasCSSC, {{i32, i32}, {i64, i64}})
365 .legalFor({{v8i8, v8i8}, {v16i8, v16i8}})
366 .customFor(!HasCSSC, {{s32, s32}, {s64, s64}})
367 .customFor({{s128, s128},
373 .clampScalar(0, s32, s128)
386 .legalFor({{i32, i32},
394 .widenScalarToNextPow2(1, 32)
414 .customFor(!HasCSSC, {s32, s64});
420 .widenScalarToNextPow2(0, 32)
434 .
legalFor({i32, i64, v4i16, v8i16, v2i32, v4i32, v2i64})
443 .legalFor({v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
444 .legalFor(HasSVE, {nxv16i8, nxv8i16, nxv4i32, nxv2i64})
445 .clampNumElements(0, v8s8, v16s8)
454 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM,
455 G_FMAXIMUM, G_FMINIMUM, G_FCEIL, G_FFLOOR, G_FRINT, G_FNEARBYINT,
456 G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND, G_INTRINSIC_ROUNDEVEN})
457 .legalFor({f32, f64, v2f32, v4f32, v2f64})
458 .legalFor(HasFP16, {f16, v4f16, v8f16})
463 return (!HasFP16 && Q.
Types[0].getScalarType().isFloat16()) ||
464 Q.
Types[0].getScalarType().isBFloat16();
467 .clampNumElements(0, v4s16, v8s16)
473 .legalFor({f32, f64, v2f32, v4f32, v2f64})
474 .legalFor(HasFP16, {f16, bf16, v4f16, v4bf16, v8f16, v8bf16})
481 .
lowerFor({f16, bf16, v4f16, v4bf16, v8f16, v8bf16});
484 G_FLOG10, G_FTAN, G_FEXP, G_FEXP2, G_FEXP10,
485 G_FACOS, G_FASIN, G_FATAN, G_FATAN2, G_FCOSH,
486 G_FSINH, G_FTANH, G_FMODF})
487 .libcallFor({f32, f64, f128})
491 .libcallFor({{f32, i32}, {f64, i32}, {f128, i32}})
496 .legalFor({{i32, f32}, {i32, f64}, {i64, f32}, {i64, f64}})
497 .legalFor(HasFP16, {{i32, f16}, {i64, f16}})
502 .legalFor({{i64, f32}, {i64, f64}})
503 .legalFor(HasFP16, {{i64, f16}})
521 for (
unsigned Op : {G_SEXTLOAD, G_ZEXTLOAD}) {
524 if (
Op == G_SEXTLOAD)
529 .legalForTypesWithMemDesc({{s32, p0, s8, 8},
537 {v2s32, p0, s64, 8}})
538 .widenScalarToNextPow2(0)
539 .clampScalar(0, s32, s64)
542 .unsupportedIfMemSizeNotPow2()
554 return HasRCPC3 && Query.
Types[0] == s128 &&
558 return Query.
Types[0] == s128 &&
561 .legalForTypesWithMemDesc({{s8, p0, s8, 8},
568 {v16s8, p0, s128, 8},
570 {v8s16, p0, s128, 8},
572 {v4s32, p0, s128, 8},
573 {v2s64, p0, s128, 8}})
575 .legalForTypesWithMemDesc(
576 {{s32, p0, s8, 8}, {s32, p0, s16, 8}, {s64, p0, s32, 8}})
577 .legalForTypesWithMemDesc({
579 {nxv16s8, p0, nxv16s8, 8},
580 {nxv8s16, p0, nxv8s16, 8},
581 {nxv4s32, p0, nxv4s32, 8},
582 {nxv2s64, p0, nxv2s64, 8},
584 .widenScalarToNextPow2(0, 8)
595 return Query.
Types[0].isScalar() &&
597 Query.
Types[0].getSizeInBits() > 32;
606 .customIf(IsPtrVecPred)
612 return HasRCPC3 && Query.
Types[0] == s128 &&
616 return Query.
Types[0] == s128 &&
624 {{s8, p0, s8, 8}, {s16, p0, s8, 8},
627 {s16, p0, s16, 8}, {s32, p0, s16, 8},
629 {s32, p0, s8, 8}, {s32, p0, s16, 8}, {s32, p0, s32, 8},
630 {s64, p0, s64, 8}, {s64, p0, s32, 8},
631 {p0, p0, s64, 8}, {s128, p0, s128, 8}, {v16s8, p0, s128, 8},
632 {v8s8, p0, s64, 8}, {v4s16, p0, s64, 8}, {v8s16, p0, s128, 8},
633 {v2s32, p0, s64, 8}, {v4s32, p0, s128, 8}, {v2s64, p0, s128, 8}})
634 .legalForTypesWithMemDesc({
639 {nxv16s8, p0, nxv16s8, 8},
640 {nxv8s16, p0, nxv8s16, 8},
641 {nxv4s32, p0, nxv4s32, 8},
642 {nxv2s64, p0, nxv2s64, 8},
644 .clampScalar(0, s8, s64)
647 return Query.
Types[0].isScalar() &&
651 .clampMaxNumElements(0, s8, 16)
660 return Query.
Types[0].getSizeInBits() ==
661 Query.
MMODescrs[0].MemoryTy.getSizeInBits();
667 .customIf(IsPtrVecPred)
685 {p0, v16s8, v16s8, 8},
686 {p0, v4s16, v4s16, 8},
687 {p0, v8s16, v8s16, 8},
688 {p0, v2s32, v2s32, 8},
689 {p0, v4s32, v4s32, 8},
690 {p0, v2s64, v2s64, 8},
696 auto IndexedLoadBasicPred = [=](
const LegalityQuery &Query) {
724 return MemTy == s8 || MemTy == s16;
726 return MemTy == s8 || MemTy == s16 || MemTy == s32;
734 .widenScalarToNextPow2(0)
741 .
legalFor({{i32, i32}, {i32, i64}, {i32, p0}})
751 return Ty.isVector() && !SrcTy.isPointerVector() &&
752 Ty.getElementType() != SrcTy.getElementType();
760 return Query.
Types[1].isPointerVector();
777 .legalFor(HasFP16, {{i32, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
782 return (!HasFP16 && Q.
Types[1].getScalarType().isFloat16()) ||
783 Q.
Types[1].getScalarType().isBFloat16();
791 return Ty.isVector() && !SrcTy.isPointerVector() &&
792 Ty.getElementType() != SrcTy.getElementType();
795 .clampNumElements(1, v4s16, v8s16)
803 unsigned DstSize = Query.
Types[0].getSizeInBits();
806 if (Query.
Types[0].isVector())
809 if (DstSize < 8 || DstSize >= 128 || !
isPowerOf2_32(DstSize))
817 unsigned SrcSize = SrcTy.getSizeInBits();
824 .legalIf(ExtLegalFunc)
825 .
legalFor({{v8s16, v8s8}, {v4s32, v4s16}, {v2s64, v2s32}})
826 .clampScalar(0, s64, s64)
833 return (Query.
Types[0].getScalarSizeInBits() >
834 Query.
Types[1].getScalarSizeInBits() * 2) &&
835 Query.
Types[0].isVector() &&
836 (Query.
Types[1].getScalarSizeInBits() == 8 ||
837 Query.
Types[1].getScalarSizeInBits() == 16);
839 .clampMinNumElements(1, s8, 8)
844 .
legalFor({{v8s8, v8s16}, {v4s16, v4s32}, {v2s32, v2s64}})
855 return DstTy.
isVector() && SrcTy.getSizeInBits() > 128 &&
858 .clampMinNumElements(0, s8, 8)
863 .legalFor({{v8i8, v8i16}, {v4i16, v4i32}, {v2i32, v2i64}})
864 .clampNumElements(0, v8s8, v8s8)
870 .
legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
881 {{f16, f32}, {f16, f64}, {f32, f64}, {v4f16, v4f32}, {v2f32, v2f64}})
882 .legalFor(ST.hasBF16(), {{bf16, f32}, {v4bf16, v4f32}})
883 .libcallFor({{f16, f128}, {f32, f128}, {f64, f128}})
891 .lowerFor({{bf16, f32}, {v4bf16, v4f32}})
893 .clampNumElements(1, v4s32, v4s32)
897 getActionDefinitionsBuilder(G_FPEXT)
905 .libcallFor({{f128, f64}, {f128, f32}, {f128, f16}})
916 .clampNumElements(0, v4s32, v4s32)
921 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
922 .legalFor({{i32, f32},
930 {{i32, f16}, {i64, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
937 return Query.
Types[1] == f16 && Query.
Types[0].getSizeInBits() > 64;
945 return (!HasFP16 && Query.
Types[1].getScalarType().isFloat16()) ||
946 Query.
Types[1].getScalarType().isBFloat16();
951 return Query.
Types[0].getScalarSizeInBits() <= 64 &&
952 Query.
Types[0].getScalarSizeInBits() >
953 Query.
Types[1].getScalarSizeInBits();
958 return Query.
Types[1].getScalarSizeInBits() <= 64 &&
959 Query.
Types[0].getScalarSizeInBits() <
960 Query.
Types[1].getScalarSizeInBits();
963 .clampNumElements(0, v4s16, v8s16)
967 {{i32, f128}, {i64, f128}, {i128, f128}, {i128, f32}, {i128, f64}});
969 getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
970 .legalFor({{i32, f32},
979 {{i16, f16}, {i32, f16}, {i64, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
987 return Query.
Types[1] == f16 && Query.
Types[0].getSizeInBits() > 64;
996 return (!HasFP16 && Query.
Types[1].getScalarType().isFloat16()) ||
997 Query.
Types[1].getScalarType().isBFloat16();
1002 unsigned ITySize = Query.
Types[0].getScalarSizeInBits();
1003 return (ITySize == 16 || ITySize == 32 || ITySize == 64) &&
1004 ITySize > Query.
Types[1].getScalarSizeInBits();
1009 unsigned FTySize = Query.
Types[1].getScalarSizeInBits();
1010 return (FTySize == 16 || FTySize == 32 || FTySize == 64) &&
1011 Query.
Types[0].getScalarSizeInBits() < FTySize;
1019 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
1020 .legalFor({{f32, i32},
1028 {{f16, i32}, {f16, i64}, {v4f16, v4i16}, {v8f16, v8i16}})
1030 return Query.
Types[0].getScalarType().isBFloat16();
1038 return Query.
Types[1].isVector() &&
1039 Query.
Types[1].getScalarSizeInBits() == 64 &&
1040 Query.
Types[0].getScalarSizeInBits() == 16;
1042 .widenScalarOrEltToNextPow2OrMinSize(0, HasFP16 ? 16 : 32)
1046 return Query.
Types[0].getScalarSizeInBits() == 32 &&
1047 Query.
Types[1].getScalarSizeInBits() == 64;
1052 return Query.
Types[1].getScalarSizeInBits() <= 64 &&
1053 Query.
Types[0].getScalarSizeInBits() <
1054 Query.
Types[1].getScalarSizeInBits();
1059 return Query.
Types[0].getScalarSizeInBits() <= 64 &&
1060 Query.
Types[0].getScalarSizeInBits() >
1061 Query.
Types[1].getScalarSizeInBits();
1064 .clampNumElements(0, v4s16, v8s16)
1076 getActionDefinitionsBuilder(G_BRCOND)
1078 .clampScalar(0, s32, s32);
1079 getActionDefinitionsBuilder(G_BRINDIRECT).
legalFor({p0});
1081 getActionDefinitionsBuilder(G_SELECT)
1082 .
legalFor({{s32, s32}, {s64, s32}, {p0, s32}})
1083 .widenScalarToNextPow2(0)
1091 getActionDefinitionsBuilder(G_FRAME_INDEX).
legalFor({p0});
1094 getActionDefinitionsBuilder(G_GLOBAL_VALUE).
custom();
1096 getActionDefinitionsBuilder(G_GLOBAL_VALUE).
legalFor({p0});
1098 getActionDefinitionsBuilder(G_PTRAUTH_GLOBAL_VALUE)
1101 getActionDefinitionsBuilder(G_PTRTOINT)
1102 .
legalFor({{i64, p0}, {v2i64, v2p0}})
1103 .widenScalarToNextPow2(0, 64)
1107 getActionDefinitionsBuilder(G_INTTOPTR)
1109 return Query.
Types[0].getSizeInBits() != Query.
Types[1].getSizeInBits();
1111 .legalFor({{p0, i64}, {v2p0, v2i64}})
1112 .clampMaxNumElements(1, s64, 2);
1116 getActionDefinitionsBuilder(G_BITCAST)
1119 .legalForCartesianProduct({s32, v2s16, v4s8})
1120 .legalForCartesianProduct({s64, v8s8, v4s16, v2s32})
1121 .legalForCartesianProduct({s128, v16s8, v8s16, v4s32, v2s64, v2p0})
1130 return Query.
Types[0].isVector() != Query.
Types[1].isVector();
1139 getActionDefinitionsBuilder(G_VASTART).
legalFor({p0});
1143 getActionDefinitionsBuilder(G_VAARG)
1145 .clampScalar(0, s8, s64)
1148 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS)
1152 bool UseOutlineAtomics =
ST.outlineAtomics() && !
ST.hasLSE();
1154 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG)
1155 .legalFor(!UseOutlineAtomics, {{s32, p0}, {s64, p0}})
1156 .customFor(!UseOutlineAtomics, {{s128, p0}})
1157 .libcallFor(UseOutlineAtomics,
1158 {{s8, p0}, {s16, p0}, {s32, p0}, {s64, p0}, {s128, p0}})
1159 .clampScalar(0, s32, s64);
1161 getActionDefinitionsBuilder({G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD,
1162 G_ATOMICRMW_SUB, G_ATOMICRMW_AND, G_ATOMICRMW_OR,
1164 .legalFor(!UseOutlineAtomics, {{s32, p0}, {s64, p0}})
1165 .libcallFor(UseOutlineAtomics,
1166 {{s8, p0}, {s16, p0}, {s32, p0}, {s64, p0}})
1167 .clampScalar(0, s32, s64);
1171 getActionDefinitionsBuilder(
1172 {G_ATOMICRMW_MIN, G_ATOMICRMW_MAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX})
1174 .clampScalar(0, s32, s64);
1176 getActionDefinitionsBuilder(G_BLOCK_ADDR).legalFor({p0});
1179 for (
unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
1180 unsigned BigTyIdx =
Op == G_MERGE_VALUES ? 0 : 1;
1181 unsigned LitTyIdx =
Op == G_MERGE_VALUES ? 1 : 0;
1182 getActionDefinitionsBuilder(
Op)
1183 .widenScalarToNextPow2(LitTyIdx, 8)
1184 .widenScalarToNextPow2(BigTyIdx, 32)
1185 .clampScalar(LitTyIdx, s8, s64)
1186 .clampScalar(BigTyIdx, s32, s128)
1188 switch (Q.
Types[BigTyIdx].getSizeInBits()) {
1196 switch (Q.
Types[LitTyIdx].getSizeInBits()) {
1209 getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT)
1210 .legalFor(HasSVE, {{s16, nxv16s8, s64},
1211 {s16, nxv8s16, s64},
1212 {s32, nxv4s32, s64},
1213 {s64, nxv2s64, s64}})
1215 const LLT &EltTy = Query.
Types[1].getElementType();
1216 if (Query.
Types[1].isScalableVector())
1218 return Query.
Types[0] != EltTy;
1223 return VecTy == v8s8 || VecTy == v16s8 || VecTy == v2s16 ||
1224 VecTy == v4s16 || VecTy == v8s16 || VecTy == v2s32 ||
1225 VecTy == v4s32 || VecTy == v2s64 || VecTy == v2p0;
1231 return Query.
Types[1].isFixedVector() &&
1232 Query.
Types[1].getNumElements() <= 2;
1237 return Query.
Types[1].isFixedVector() &&
1238 Query.
Types[1].getNumElements() <= 4;
1243 return Query.
Types[1].isFixedVector() &&
1244 Query.
Types[1].getNumElements() <= 8;
1249 return Query.
Types[1].isFixedVector() &&
1250 Query.
Types[1].getNumElements() <= 16;
1253 .minScalarOrElt(0, s8)
1254 .moreElementsToNextPow2(1)
1255 .clampMaxNumElements(1, s64, 2)
1256 .clampMaxNumElements(1, s32, 4)
1257 .clampMaxNumElements(1, s16, 8)
1258 .clampMaxNumElements(1, s8, 16)
1259 .clampMaxNumElements(1, p0, 2)
1262 getActionDefinitionsBuilder(G_INSERT_VECTOR_ELT)
1264 typeInSet(0, {v8s8, v16s8, v4s16, v8s16, v2s32, v4s32, v2s64, v2p0}))
1265 .legalFor(HasSVE, {{nxv16s8, s32, s64},
1266 {nxv8s16, s32, s64},
1267 {nxv4s32, s32, s64},
1268 {nxv2s64, s64, s64}})
1270 .widenVectorEltsToVectorMinSize(0, 64)
1271 .clampNumElements(0, v8s8, v16s8)
1272 .clampNumElements(0, v4s16, v8s16)
1273 .clampNumElements(0, v2s32, v4s32)
1274 .clampMaxNumElements(0, s64, 2)
1275 .clampMaxNumElements(0, p0, 2)
1278 getActionDefinitionsBuilder(G_BUILD_VECTOR)
1279 .legalFor({{v8s8, s8},
1287 .clampNumElements(0, v4s32, v4s32)
1288 .clampNumElements(0, v2s64, v2s64)
1289 .minScalarOrElt(0, s8)
1290 .widenVectorEltsToVectorMinSize(0, 64)
1291 .widenScalarOrEltToNextPow2(0)
1292 .minScalarSameAs(1, 0);
1294 getActionDefinitionsBuilder(G_BUILD_VECTOR_TRUNC).lower();
1296 getActionDefinitionsBuilder(G_SHUFFLE_VECTOR)
1305 {v8s8, v16s8, v4s16, v8s16, v2s32, v4s32, v2s64}, DstTy);
1309 return Query.
Types[0].getNumElements() >
1310 Query.
Types[1].getNumElements();
1316 return Query.
Types[0].getNumElements() <
1317 Query.
Types[1].getNumElements();
1320 .widenScalarOrEltToNextPow2OrMinSize(0, 8)
1321 .clampNumElements(0, v8s8, v16s8)
1322 .clampNumElements(0, v4s16, v8s16)
1323 .clampNumElements(0, v4s32, v4s32)
1324 .clampNumElements(0, v2s64, v2s64)
1333 getActionDefinitionsBuilder(G_CONCAT_VECTORS)
1334 .legalFor({{v16s8, v8s8}, {v8s16, v4s16}, {v4s32, v2s32}})
1336 return Query.
Types[0].isFixedVector() &&
1337 Query.
Types[0].getScalarSizeInBits() < 8;
1341 return Query.
Types[0].isFixedVector() &&
1342 Query.
Types[1].isFixedVector() &&
1343 Query.
Types[0].getScalarSizeInBits() >= 8 &&
1345 Query.
Types[0].getSizeInBits() <= 128 &&
1346 Query.
Types[1].getSizeInBits() <= 64;
1358 getActionDefinitionsBuilder(G_EXTRACT_SUBVECTOR)
1359 .legalFor({{v8s8, v16s8}, {v4s16, v8s16}, {v2s32, v4s32}})
1361 .clampMaxNumElements(0, s8, 16)
1362 .clampMaxNumElements(0, s16, 8)
1363 .clampMaxNumElements(0, s32, 4)
1364 .clampNumElements(1, v8s8, v16s8)
1365 .clampNumElements(1, v4s16, v8s16)
1366 .clampNumElements(1, v2s32, v4s32)
1371 getActionDefinitionsBuilder(G_SPLAT_VECTOR)
1372 .legalFor(HasSVE, {{nxv4s32, s32}, {nxv2s64, s64}});
1374 getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({p0});
1376 getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, s64}});
1378 getActionDefinitionsBuilder({G_TRAP, G_DEBUGTRAP, G_UBSANTRAP}).alwaysLegal();
1380 getActionDefinitionsBuilder(G_DYN_STACKALLOC).custom();
1382 getActionDefinitionsBuilder({G_STACKSAVE, G_STACKRESTORE}).lower();
1387 getActionDefinitionsBuilder(G_BZERO).unsupported();
1389 getActionDefinitionsBuilder(G_MEMSET)
1390 .legalForCartesianProduct({p0}, {s64}, {s64})
1391 .customForCartesianProduct({p0}, {s8}, {s64})
1394 getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE})
1395 .legalForCartesianProduct({p0}, {p0}, {s64})
1399 getActionDefinitionsBuilder(G_MEMCPY_INLINE)
1400 .legalForCartesianProduct({p0}, {p0}, {s64});
1402 getActionDefinitionsBuilder(G_MEMSET_INLINE)
1403 .legalForCartesianProduct({p0}, {s64}, {s64})
1404 .customForCartesianProduct({p0}, {s8}, {s64});
1406 getActionDefinitionsBuilder({G_BZERO, G_MEMCPY, G_MEMMOVE, G_MEMSET})
1413 getActionDefinitionsBuilder(G_VECREDUCE_FADD)
1414 .legalFor({{f32, v2f32}, {f32, v4f32}, {f64, v2f64}})
1415 .legalFor(HasFP16, {{f16, v4f16}, {f16, v8f16}})
1418 return (!HasFP16 && Query.
Types[0].getScalarType().isFloat16()) ||
1419 Query.
Types[0].getScalarType().isBFloat16();
1422 .clampMaxNumElements(1, s64, 2)
1423 .clampMaxNumElements(1, s32, 4)
1424 .clampMaxNumElements(1, s16, 8)
1425 .moreElementsToNextPow2(1)
1432 getActionDefinitionsBuilder(G_VECREDUCE_FMUL)
1435 return (!HasFP16 && Query.
Types[0].getScalarType().isFloat16()) ||
1436 Query.
Types[0].getScalarType().isBFloat16();
1439 .clampMaxNumElements(1, s64, 2)
1440 .clampMaxNumElements(1, s32, 4)
1441 .clampMaxNumElements(1, s16, 8)
1442 .clampMaxNumElements(1, s32, 2)
1443 .clampMaxNumElements(1, s16, 4)
1447 getActionDefinitionsBuilder({G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL})
1451 getActionDefinitionsBuilder(G_VECREDUCE_ADD)
1452 .legalFor({{i8, v8i8},
1460 .clampMaxNumElements(1, s64, 2)
1461 .clampMaxNumElements(1, s32, 4)
1462 .clampMaxNumElements(1, s16, 8)
1463 .clampMaxNumElements(1, s8, 16)
1464 .widenVectorEltsToVectorMinSize(1, 64)
1467 getActionDefinitionsBuilder({G_VECREDUCE_FMIN, G_VECREDUCE_FMAX,
1468 G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM})
1469 .legalFor({{f32, v2f32}, {f32, v4f32}, {f64, v2f64}})
1470 .legalFor(HasFP16, {{f16, v4f16}, {f16, v8f16}})
1473 return (!HasFP16 && Query.
Types[0].getScalarType().isFloat16()) ||
1474 Query.
Types[0].getScalarType().isBFloat16();
1477 .clampMaxNumElements(1, s64, 2)
1478 .clampMaxNumElements(1, s32, 4)
1479 .clampMaxNumElements(1, s16, 8)
1483 getActionDefinitionsBuilder(G_VECREDUCE_MUL)
1484 .clampMaxNumElements(1, s32, 2)
1485 .clampMaxNumElements(1, s16, 4)
1486 .clampMaxNumElements(1, s8, 8)
1490 getActionDefinitionsBuilder(
1491 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX})
1492 .legalFor({{i8, v8i8},
1500 return Query.
Types[1].isVector() &&
1501 Query.
Types[1].getElementType() != s8 &&
1502 Query.
Types[1].getNumElements() & 1;
1505 .clampMaxNumElements(1, s64, 2)
1506 .clampMaxNumElements(1, s32, 4)
1507 .clampMaxNumElements(1, s16, 8)
1508 .clampMaxNumElements(1, s8, 16)
1512 getActionDefinitionsBuilder(
1513 {G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
1529 return std::make_pair(1, SrcTy.
divide(2));
1535 getActionDefinitionsBuilder(G_VECTOR_COMPRESS).lower();
1538 getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV, G_RESET_FPENV,
1539 G_GET_FPMODE, G_SET_FPMODE, G_RESET_FPMODE})
1542 getActionDefinitionsBuilder({G_GET_ROUNDING, G_SET_ROUNDING})
1545 getActionDefinitionsBuilder(G_IS_FPCLASS).lower();
1547 getActionDefinitionsBuilder(G_PREFETCH).custom();
1549 getActionDefinitionsBuilder({G_SCMP, G_UCMP}).lower();
1551 getActionDefinitionsBuilder({G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS})
1553 getActionDefinitionsBuilder(G_FENCE).alwaysLegal();
1554 getActionDefinitionsBuilder(G_INVOKE_REGION_START).alwaysLegal();
1806 auto LowerUnaryOp = [&
MI, &MIB](
unsigned Opcode) {
1808 MI.eraseFromParent();
1811 auto LowerBinOp = [&
MI, &MIB](
unsigned Opcode) {
1813 {
MI.getOperand(2),
MI.getOperand(3)});
1814 MI.eraseFromParent();
1817 auto LowerTriOp = [&
MI, &MIB](
unsigned Opcode) {
1819 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4)});
1820 MI.eraseFromParent();
1825 switch (IntrinsicID) {
1826 case Intrinsic::vacopy: {
1827 unsigned PtrSize = ST->isTargetILP32() ? 4 : 8;
1828 unsigned VaListSize =
1829 (ST->isTargetDarwin() || ST->isTargetWindows())
1831 : ST->isTargetILP32() ? 20 : 32;
1839 VaListSize,
Align(PtrSize)));
1843 VaListSize,
Align(PtrSize)));
1844 MI.eraseFromParent();
1847 case Intrinsic::get_dynamic_area_offset: {
1849 MI.eraseFromParent();
1852 case Intrinsic::aarch64_mops_memset_tag: {
1853 assert(
MI.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS);
1856 auto &
Value =
MI.getOperand(3);
1858 Value.setReg(ExtValueReg);
1861 case Intrinsic::aarch64_prefetch: {
1862 auto &AddrVal =
MI.getOperand(1);
1864 int64_t IsWrite =
MI.getOperand(2).getImm();
1865 int64_t
Target =
MI.getOperand(3).getImm();
1866 int64_t IsStream =
MI.getOperand(4).getImm();
1867 int64_t IsData =
MI.getOperand(5).getImm();
1869 unsigned PrfOp = (IsWrite << 4) |
1875 MI.eraseFromParent();
1878 case Intrinsic::aarch64_range_prefetch: {
1879 auto &AddrVal =
MI.getOperand(1);
1881 int64_t IsWrite =
MI.getOperand(2).getImm();
1882 int64_t IsStream =
MI.getOperand(3).getImm();
1883 unsigned PrfOp = (IsStream << 2) | IsWrite;
1885 MIB.
buildInstr(AArch64::G_AARCH64_RANGE_PREFETCH)
1888 .
addUse(
MI.getOperand(4).getReg());
1889 MI.eraseFromParent();
1892 case Intrinsic::aarch64_prefetch_ir: {
1893 auto &AddrVal =
MI.getOperand(1);
1895 MI.eraseFromParent();
1898 case Intrinsic::aarch64_neon_uaddv:
1899 case Intrinsic::aarch64_neon_saddv:
1900 case Intrinsic::aarch64_neon_umaxv:
1901 case Intrinsic::aarch64_neon_smaxv:
1902 case Intrinsic::aarch64_neon_uminv:
1903 case Intrinsic::aarch64_neon_sminv: {
1904 bool IsSigned = IntrinsicID == Intrinsic::aarch64_neon_saddv ||
1905 IntrinsicID == Intrinsic::aarch64_neon_smaxv ||
1906 IntrinsicID == Intrinsic::aarch64_neon_sminv;
1908 auto OldDst =
MI.getOperand(0).getReg();
1909 auto OldDstTy = MRI.
getType(OldDst);
1911 if (OldDstTy == NewDstTy)
1917 MI.getOperand(0).setReg(NewDst);
1921 MIB.
buildExtOrTrunc(IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT,
1926 case Intrinsic::aarch64_neon_uaddlp:
1927 case Intrinsic::aarch64_neon_saddlp: {
1928 unsigned Opc = IntrinsicID == Intrinsic::aarch64_neon_uaddlp
1930 : AArch64::G_SADDLP;
1932 MI.eraseFromParent();
1936 case Intrinsic::aarch64_neon_uaddlv:
1937 case Intrinsic::aarch64_neon_saddlv: {
1938 unsigned Opc = IntrinsicID == Intrinsic::aarch64_neon_uaddlv
1940 : AArch64::G_SADDLV;
1967 MI.eraseFromParent();
1971 case Intrinsic::aarch64_neon_smax:
1972 return LowerBinOp(TargetOpcode::G_SMAX);
1973 case Intrinsic::aarch64_neon_smin:
1974 return LowerBinOp(TargetOpcode::G_SMIN);
1975 case Intrinsic::aarch64_neon_umax:
1976 return LowerBinOp(TargetOpcode::G_UMAX);
1977 case Intrinsic::aarch64_neon_umin:
1978 return LowerBinOp(TargetOpcode::G_UMIN);
1979 case Intrinsic::aarch64_neon_fmax:
1980 return LowerBinOp(TargetOpcode::G_FMAXIMUM);
1981 case Intrinsic::aarch64_neon_fmin:
1982 return LowerBinOp(TargetOpcode::G_FMINIMUM);
1983 case Intrinsic::aarch64_neon_fmaxnm:
1984 return LowerBinOp(TargetOpcode::G_FMAXNUM);
1985 case Intrinsic::aarch64_neon_fminnm:
1986 return LowerBinOp(TargetOpcode::G_FMINNUM);
1987 case Intrinsic::aarch64_neon_pmul:
1988 return LowerBinOp(TargetOpcode::G_CLMUL);
1989 case Intrinsic::aarch64_neon_pmull:
1990 case Intrinsic::aarch64_neon_pmull64:
1991 return LowerBinOp(AArch64::G_PMULL);
1992 case Intrinsic::aarch64_neon_smull:
1993 return LowerBinOp(AArch64::G_SMULL);
1994 case Intrinsic::aarch64_neon_umull:
1995 return LowerBinOp(AArch64::G_UMULL);
1996 case Intrinsic::aarch64_neon_sabd:
1997 return LowerBinOp(TargetOpcode::G_ABDS);
1998 case Intrinsic::aarch64_neon_uabd:
1999 return LowerBinOp(TargetOpcode::G_ABDU);
2000 case Intrinsic::aarch64_neon_uhadd:
2001 return LowerBinOp(TargetOpcode::G_UAVGFLOOR);
2002 case Intrinsic::aarch64_neon_urhadd:
2003 return LowerBinOp(TargetOpcode::G_UAVGCEIL);
2004 case Intrinsic::aarch64_neon_shadd:
2005 return LowerBinOp(TargetOpcode::G_SAVGFLOOR);
2006 case Intrinsic::aarch64_neon_srhadd:
2007 return LowerBinOp(TargetOpcode::G_SAVGCEIL);
2008 case Intrinsic::aarch64_neon_sqshrn: {
2013 {MRI.
getType(
MI.getOperand(2).getReg())},
2014 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2016 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {
MI.getOperand(0)}, {Shr});
2017 MI.eraseFromParent();
2020 case Intrinsic::aarch64_neon_sqshrun: {
2025 {MRI.
getType(
MI.getOperand(2).getReg())},
2026 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2028 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {
MI.getOperand(0)}, {Shr});
2029 MI.eraseFromParent();
2032 case Intrinsic::aarch64_neon_sqrshrn: {
2036 auto Shr = MIB.
buildInstr(AArch64::G_SRSHR_I,
2037 {MRI.
getType(
MI.getOperand(2).getReg())},
2038 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2040 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {
MI.getOperand(0)}, {Shr});
2041 MI.eraseFromParent();
2044 case Intrinsic::aarch64_neon_sqrshrun: {
2048 auto Shr = MIB.
buildInstr(AArch64::G_SRSHR_I,
2049 {MRI.
getType(
MI.getOperand(2).getReg())},
2050 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2052 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {
MI.getOperand(0)}, {Shr});
2053 MI.eraseFromParent();
2056 case Intrinsic::aarch64_neon_uqrshrn: {
2060 auto Shr = MIB.
buildInstr(AArch64::G_URSHR_I,
2061 {MRI.
getType(
MI.getOperand(2).getReg())},
2062 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2064 MIB.
buildInstr(TargetOpcode::G_TRUNC_USAT_U, {
MI.getOperand(0)}, {Shr});
2065 MI.eraseFromParent();
2068 case Intrinsic::aarch64_neon_uqshrn: {
2073 {MRI.
getType(
MI.getOperand(2).getReg())},
2074 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2076 MIB.
buildInstr(TargetOpcode::G_TRUNC_USAT_U, {
MI.getOperand(0)}, {Shr});
2077 MI.eraseFromParent();
2080 case Intrinsic::aarch64_neon_sqshlu: {
2086 MIB.
buildInstr(AArch64::G_SQSHLU_I, {
MI.getOperand(0)},
2088 .addImm(ShiftAmount->getSExtValue());
2089 MI.eraseFromParent();
2094 case Intrinsic::aarch64_neon_vsli: {
2096 AArch64::G_SLI, {
MI.getOperand(0)},
2097 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4).getImm()});
2098 MI.eraseFromParent();
2101 case Intrinsic::aarch64_neon_vsri: {
2103 AArch64::G_SRI, {
MI.getOperand(0)},
2104 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4).getImm()});
2105 MI.eraseFromParent();
2108 case Intrinsic::aarch64_neon_abs: {
2110 MIB.
buildInstr(TargetOpcode::G_ABS, {
MI.getOperand(0)}, {
MI.getOperand(2)});
2111 MI.eraseFromParent();
2114 case Intrinsic::aarch64_neon_addhn:
2115 return LowerBinOp(AArch64::G_ADDHN);
2116 case Intrinsic::aarch64_neon_sqadd: {
2118 return LowerBinOp(TargetOpcode::G_SADDSAT);
2121 case Intrinsic::aarch64_neon_sqsub: {
2123 return LowerBinOp(TargetOpcode::G_SSUBSAT);
2126 case Intrinsic::aarch64_neon_uqadd: {
2128 return LowerBinOp(TargetOpcode::G_UADDSAT);
2131 case Intrinsic::aarch64_neon_uqsub: {
2133 return LowerBinOp(TargetOpcode::G_USUBSAT);
2136 case Intrinsic::aarch64_neon_udot:
2137 return LowerTriOp(AArch64::G_UDOT);
2138 case Intrinsic::aarch64_neon_sdot:
2139 return LowerTriOp(AArch64::G_SDOT);
2140 case Intrinsic::aarch64_neon_usdot:
2141 return LowerTriOp(AArch64::G_USDOT);
2142 case Intrinsic::aarch64_neon_sqxtn:
2143 return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_S);
2144 case Intrinsic::aarch64_neon_sqxtun:
2145 return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_U);
2146 case Intrinsic::aarch64_neon_uqxtn:
2147 return LowerUnaryOp(TargetOpcode::G_TRUNC_USAT_U);
2148 case Intrinsic::aarch64_neon_fcvtzu:
2149 return LowerUnaryOp(TargetOpcode::G_FPTOUI_SAT);
2150 case Intrinsic::aarch64_neon_fcvtzs:
2151 return LowerUnaryOp(TargetOpcode::G_FPTOSI_SAT);
2152 case Intrinsic::aarch64_neon_cls:
2153 return LowerUnaryOp(TargetOpcode::G_CTLS);
2155 case Intrinsic::vector_reverse: