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()) {
127 const bool HasFP16 = ST.hasFullFP16();
128 const LLT &MinFPScalar = HasFP16 ? f16 : f32;
130 const bool HasCSSC = ST.hasCSSC();
131 const bool HasRCPC3 = ST.hasRCPC3();
132 const bool HasSVE = ST.hasSVE();
135 {G_IMPLICIT_DEF, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
136 .legalFor({p0, s8, s16, s32, s64})
137 .legalFor({v2s8, v4s8, v8s8, v16s8, v2s16, v4s16, v8s16, v2s32, v4s32,
139 .widenScalarToNextPow2(0)
152 .legalFor(PackedVectorAllTypeList)
166 .widenScalarToNextPow2(0)
171 .maxScalarIf(
typeInSet(0, {s64, p0}), 1, s32);
176 .widenScalarToNextPow2(1)
181 .maxScalarIf(
typeInSet(1, {s64, p0}), 0, s32)
182 .maxScalarIf(
typeInSet(1, {s128}), 0, s64);
185 .legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
186 .legalFor(HasSVE, {nxv16i8, nxv8i16, nxv4i32, nxv2i64})
187 .widenScalarToNextPow2(0)
195 return Query.
Types[0].getNumElements() <= 2;
200 return Query.
Types[0].getNumElements() <= 4;
205 return Query.
Types[0].getNumElements() <= 16;
212 .
legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
213 .widenScalarToNextPow2(0)
221 return Query.
Types[0].getNumElements() <= 2;
226 return Query.
Types[0].getNumElements() <= 4;
231 return Query.
Types[0].getNumElements() <= 16;
239 const auto &SrcTy = Query.
Types[0];
240 const auto &AmtTy = Query.
Types[1];
241 return !SrcTy.isVector() && SrcTy.getSizeInBits() == 32 &&
242 AmtTy.getSizeInBits() == 32;
256 .widenScalarToNextPow2(0)
270 .
legalFor({{p0, i64}, {v2p0, v2i64}})
271 .clampScalarOrElt(1, s64, s64)
277 .legalFor({i32, i64})
279 .clampScalar(0, s32, s64)
284 .lowerFor({i8, i16, i32, i64, v2i32, v4i32, v2i64})
293 .widenScalarToNextPow2(0, 32)
298 .legalFor({i64, v16i8, v8i16, v4i32})
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)
347 .customFor({{i32, i32}, {i32, i64}, {i64, i64}})
353 return Q.
Types[0].isScalar() && Q.
Types[1].getScalarSizeInBits() < 64;
359 .customFor({{s32, s32}, {s64, s64}});
363 .
legalFor(HasCSSC, {{i32, i32}, {i64, i64}})
364 .legalFor({{v8i8, v8i8}, {v16i8, v16i8}})
365 .customFor(!HasCSSC, {{s32, s32}, {s64, s64}})
366 .customFor({{s128, s128},
372 .clampScalar(0, s32, s128)
385 .legalFor({{i32, i32},
393 .widenScalarToNextPow2(1, 32)
411 .customFor(!HasCSSC, {s32, s64});
417 .widenScalarToNextPow2(0, 32)
431 .
legalFor({i32, i64, v4i16, v8i16, v2i32, v4i32, v2i64})
440 .legalFor({v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
441 .legalFor(HasSVE, {nxv16i8, nxv8i16, nxv4i32, nxv2i64})
442 .clampNumElements(0, v8s8, v16s8)
451 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM,
452 G_FMAXIMUM, G_FMINIMUM, G_FCEIL, G_FFLOOR, G_FRINT, G_FNEARBYINT,
453 G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND, G_INTRINSIC_ROUNDEVEN})
454 .legalFor({f32, f64, v2f32, v4f32, v2f64})
455 .legalFor(HasFP16, {f16, v4f16, v8f16})
460 return (!HasFP16 && Q.
Types[0].getScalarType().isFloat16()) ||
461 Q.
Types[0].getScalarType().isBFloat16();
464 .clampNumElements(0, v4s16, v8s16)
470 .legalFor({f32, f64, v2f32, v4f32, v2f64})
471 .legalFor(HasFP16, {f16, bf16, v4f16, v4bf16, v8f16, v8bf16})
478 .
lowerFor({f16, bf16, v4f16, v4bf16, v8f16, v8bf16});
486 G_FLOG10, G_FTAN, G_FEXP, G_FEXP2, G_FEXP10,
487 G_FACOS, G_FASIN, G_FATAN, G_FATAN2, G_FCOSH,
488 G_FSINH, G_FTANH, G_FMODF})
497 .
libcallFor({{f32, i32}, {f64, i32}, {f128, i32}});
500 .legalFor({{i32, f32}, {i32, f64}, {i64, f32}, {i64, f64}})
501 .legalFor(HasFP16, {{i32, f16}, {i64, f16}})
506 .legalFor({{i64, f32}, {i64, f64}})
507 .legalFor(HasFP16, {{i64, f16}})
525 for (
unsigned Op : {G_SEXTLOAD, G_ZEXTLOAD}) {
528 if (
Op == G_SEXTLOAD)
533 .legalForTypesWithMemDesc({{s32, p0, s8, 8},
541 {v2s32, p0, s64, 8}})
542 .widenScalarToNextPow2(0)
543 .clampScalar(0, s32, s64)
546 .unsupportedIfMemSizeNotPow2()
558 return HasRCPC3 && Query.
Types[0] == s128 &&
562 return Query.
Types[0] == s128 &&
565 .legalForTypesWithMemDesc({{s8, p0, s8, 8},
572 {v16s8, p0, s128, 8},
574 {v8s16, p0, s128, 8},
576 {v4s32, p0, s128, 8},
577 {v2s64, p0, s128, 8}})
579 .legalForTypesWithMemDesc(
580 {{s32, p0, s8, 8}, {s32, p0, s16, 8}, {s64, p0, s32, 8}})
581 .legalForTypesWithMemDesc({
583 {nxv16s8, p0, nxv16s8, 8},
584 {nxv8s16, p0, nxv8s16, 8},
585 {nxv4s32, p0, nxv4s32, 8},
586 {nxv2s64, p0, nxv2s64, 8},
588 .widenScalarToNextPow2(0, 8)
599 return Query.
Types[0].isScalar() &&
601 Query.
Types[0].getSizeInBits() > 32;
610 .customIf(IsPtrVecPred)
616 return HasRCPC3 && Query.
Types[0] == s128 &&
620 return Query.
Types[0] == s128 &&
628 {{s8, p0, s8, 8}, {s16, p0, s8, 8},
631 {s16, p0, s16, 8}, {s32, p0, s16, 8},
633 {s32, p0, s8, 8}, {s32, p0, s16, 8}, {s32, p0, s32, 8},
634 {s64, p0, s64, 8}, {s64, p0, s32, 8},
635 {p0, p0, s64, 8}, {s128, p0, s128, 8}, {v16s8, p0, s128, 8},
636 {v8s8, p0, s64, 8}, {v4s16, p0, s64, 8}, {v8s16, p0, s128, 8},
637 {v2s32, p0, s64, 8}, {v4s32, p0, s128, 8}, {v2s64, p0, s128, 8}})
638 .legalForTypesWithMemDesc({
643 {nxv16s8, p0, nxv16s8, 8},
644 {nxv8s16, p0, nxv8s16, 8},
645 {nxv4s32, p0, nxv4s32, 8},
646 {nxv2s64, p0, nxv2s64, 8},
648 .clampScalar(0, s8, s64)
651 return Query.
Types[0].isScalar() &&
655 .clampMaxNumElements(0, s8, 16)
664 return Query.
Types[0].getSizeInBits() ==
665 Query.
MMODescrs[0].MemoryTy.getSizeInBits();
671 .customIf(IsPtrVecPred)
689 {p0, v16s8, v16s8, 8},
690 {p0, v4s16, v4s16, 8},
691 {p0, v8s16, v8s16, 8},
692 {p0, v2s32, v2s32, 8},
693 {p0, v4s32, v4s32, 8},
694 {p0, v2s64, v2s64, 8},
700 auto IndexedLoadBasicPred = [=](
const LegalityQuery &Query) {
728 return MemTy == s8 || MemTy == s16;
730 return MemTy == s8 || MemTy == s16 || MemTy == s32;
738 .widenScalarToNextPow2(0)
745 .
legalFor({{i32, i32}, {i32, i64}, {i32, p0}})
755 return Ty.isVector() && !SrcTy.isPointerVector() &&
756 Ty.getElementType() != SrcTy.getElementType();
764 return Query.
Types[1].isPointerVector();
781 .legalFor(HasFP16, {{i32, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
786 return (!HasFP16 && Q.
Types[1].getScalarType().isFloat16()) ||
787 Q.
Types[1].getScalarType().isBFloat16();
795 return Ty.isVector() && !SrcTy.isPointerVector() &&
796 Ty.getElementType() != SrcTy.getElementType();
799 .clampNumElements(1, v4s16, v8s16)
807 unsigned DstSize = Query.
Types[0].getSizeInBits();
810 if (Query.
Types[0].isVector())
813 if (DstSize < 8 || DstSize >= 128 || !
isPowerOf2_32(DstSize))
821 unsigned SrcSize = SrcTy.getSizeInBits();
828 .legalIf(ExtLegalFunc)
829 .
legalFor({{v8s16, v8s8}, {v4s32, v4s16}, {v2s64, v2s32}})
830 .clampScalar(0, s64, s64)
837 return (Query.
Types[0].getScalarSizeInBits() >
838 Query.
Types[1].getScalarSizeInBits() * 2) &&
839 Query.
Types[0].isVector() &&
840 (Query.
Types[1].getScalarSizeInBits() == 8 ||
841 Query.
Types[1].getScalarSizeInBits() == 16);
843 .clampMinNumElements(1, s8, 8)
848 .
legalFor({{v8s8, v8s16}, {v4s16, v4s32}, {v2s32, v2s64}})
859 return DstTy.
isVector() && SrcTy.getSizeInBits() > 128 &&
862 .clampMinNumElements(0, s8, 8)
867 .legalFor({{v8i8, v8i16}, {v4i16, v4i32}, {v2i32, v2i64}})
868 .clampNumElements(0, v2s32, v2s32);
871 .
legalFor({i32, i64, v8i8, v16i8, v4i16, v8i16, v2i32, v4i32, v2i64})
882 {{f16, f32}, {f16, f64}, {f32, f64}, {v4f16, v4f32}, {v2f32, v2f64}})
883 .legalFor(ST.hasBF16(), {{bf16, f32}, {v4bf16, v4f32}})
884 .libcallFor({{f16, f128}, {f32, f128}, {f64, f128}})
892 .lowerFor({{bf16, f32}, {v4bf16, v4f32}})
894 .clampNumElements(1, v4s32, v4s32)
898 getActionDefinitionsBuilder(G_FPEXT)
906 .libcallFor({{f128, f64}, {f128, f32}, {f128, f16}})
917 .clampNumElements(0, v4s32, v4s32)
922 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
923 .legalFor({{i32, f32},
931 {{i32, f16}, {i64, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
938 return Query.
Types[1] == f16 && Query.
Types[0].getSizeInBits() > 64;
947 return Query.
Types[0].getScalarSizeInBits() <= 64 &&
948 Query.
Types[0].getScalarSizeInBits() >
949 Query.
Types[1].getScalarSizeInBits();
954 return Query.
Types[1].getScalarSizeInBits() <= 64 &&
955 Query.
Types[0].getScalarSizeInBits() <
956 Query.
Types[1].getScalarSizeInBits();
959 .clampNumElements(0, v4s16, v8s16)
963 {{i32, f128}, {i64, f128}, {i128, f128}, {i128, f32}, {i128, f64}});
965 getActionDefinitionsBuilder({G_FPTOSI_SAT, G_FPTOUI_SAT})
966 .legalFor({{i32, f32},
975 {{i16, f16}, {i32, f16}, {i64, f16}, {v4i16, v4f16}, {v8i16, v8f16}})
983 return Query.
Types[1] == f16 && Query.
Types[0].getSizeInBits() > 64;
993 unsigned ITySize = Query.
Types[0].getScalarSizeInBits();
994 return (ITySize == 16 || ITySize == 32 || ITySize == 64) &&
995 ITySize > Query.
Types[1].getScalarSizeInBits();
1000 unsigned FTySize = Query.
Types[1].getScalarSizeInBits();
1001 return (FTySize == 16 || FTySize == 32 || FTySize == 64) &&
1002 Query.
Types[0].getScalarSizeInBits() < FTySize;
1010 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
1011 .legalFor({{f32, i32},
1019 {{f16, i32}, {f16, i64}, {v4f16, v4i16}, {v8f16, v8i16}})
1021 return Query.
Types[0].getScalarType().isBFloat16();
1029 return Query.
Types[1].isVector() &&
1030 Query.
Types[1].getScalarSizeInBits() == 64 &&
1031 Query.
Types[0].getScalarSizeInBits() == 16;
1033 .widenScalarOrEltToNextPow2OrMinSize(0, HasFP16 ? 16 : 32)
1037 return Query.
Types[0].getScalarSizeInBits() == 32 &&
1038 Query.
Types[1].getScalarSizeInBits() == 64;
1043 return Query.
Types[1].getScalarSizeInBits() <= 64 &&
1044 Query.
Types[0].getScalarSizeInBits() <
1045 Query.
Types[1].getScalarSizeInBits();
1050 return Query.
Types[0].getScalarSizeInBits() <= 64 &&
1051 Query.
Types[0].getScalarSizeInBits() >
1052 Query.
Types[1].getScalarSizeInBits();
1055 .clampNumElements(0, v4s16, v8s16)
1067 getActionDefinitionsBuilder(G_BRCOND)
1069 .clampScalar(0, s32, s32);
1070 getActionDefinitionsBuilder(G_BRINDIRECT).
legalFor({p0});
1072 getActionDefinitionsBuilder(G_SELECT)
1073 .
legalFor({{s32, s32}, {s64, s32}, {p0, s32}})
1074 .widenScalarToNextPow2(0)
1082 getActionDefinitionsBuilder(G_FRAME_INDEX).
legalFor({p0});
1085 getActionDefinitionsBuilder(G_GLOBAL_VALUE).
custom();
1087 getActionDefinitionsBuilder(G_GLOBAL_VALUE).
legalFor({p0});
1089 getActionDefinitionsBuilder(G_PTRAUTH_GLOBAL_VALUE)
1092 getActionDefinitionsBuilder(G_PTRTOINT)
1093 .
legalFor({{i64, p0}, {v2i64, v2p0}})
1094 .widenScalarToNextPow2(0, 64)
1098 getActionDefinitionsBuilder(G_INTTOPTR)
1100 return Query.
Types[0].getSizeInBits() != Query.
Types[1].getSizeInBits();
1102 .legalFor({{p0, i64}, {v2p0, v2i64}})
1103 .clampMaxNumElements(1, s64, 2);
1107 getActionDefinitionsBuilder(G_BITCAST)
1110 .legalForCartesianProduct({s32, v2s16, v4s8})
1111 .legalForCartesianProduct({s64, v8s8, v4s16, v2s32})
1112 .legalForCartesianProduct({s128, v16s8, v8s16, v4s32, v2s64, v2p0})
1121 return Query.
Types[0].isVector() != Query.
Types[1].isVector();
1130 getActionDefinitionsBuilder(G_VASTART).
legalFor({p0});
1134 getActionDefinitionsBuilder(G_VAARG)
1136 .clampScalar(0, s8, s64)
1139 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS)
1143 bool UseOutlineAtomics =
ST.outlineAtomics() && !
ST.hasLSE();
1145 getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG)
1146 .legalFor(!UseOutlineAtomics, {{s32, p0}, {s64, p0}})
1147 .customFor(!UseOutlineAtomics, {{s128, p0}})
1148 .libcallFor(UseOutlineAtomics,
1149 {{s8, p0}, {s16, p0}, {s32, p0}, {s64, p0}, {s128, p0}})
1150 .clampScalar(0, s32, s64);
1152 getActionDefinitionsBuilder({G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD,
1153 G_ATOMICRMW_SUB, G_ATOMICRMW_AND, G_ATOMICRMW_OR,
1155 .legalFor(!UseOutlineAtomics, {{s32, p0}, {s64, p0}})
1156 .libcallFor(UseOutlineAtomics,
1157 {{s8, p0}, {s16, p0}, {s32, p0}, {s64, p0}})
1158 .clampScalar(0, s32, s64);
1162 getActionDefinitionsBuilder(
1163 {G_ATOMICRMW_MIN, G_ATOMICRMW_MAX, G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX})
1165 .clampScalar(0, s32, s64);
1167 getActionDefinitionsBuilder(G_BLOCK_ADDR).legalFor({p0});
1170 for (
unsigned Op : {G_MERGE_VALUES, G_UNMERGE_VALUES}) {
1171 unsigned BigTyIdx =
Op == G_MERGE_VALUES ? 0 : 1;
1172 unsigned LitTyIdx =
Op == G_MERGE_VALUES ? 1 : 0;
1173 getActionDefinitionsBuilder(
Op)
1174 .widenScalarToNextPow2(LitTyIdx, 8)
1175 .widenScalarToNextPow2(BigTyIdx, 32)
1176 .clampScalar(LitTyIdx, s8, s64)
1177 .clampScalar(BigTyIdx, s32, s128)
1179 switch (Q.
Types[BigTyIdx].getSizeInBits()) {
1187 switch (Q.
Types[LitTyIdx].getSizeInBits()) {
1200 getActionDefinitionsBuilder(G_EXTRACT_VECTOR_ELT)
1201 .legalFor(HasSVE, {{s16, nxv16s8, s64},
1202 {s16, nxv8s16, s64},
1203 {s32, nxv4s32, s64},
1204 {s64, nxv2s64, s64}})
1206 const LLT &EltTy = Query.
Types[1].getElementType();
1207 if (Query.
Types[1].isScalableVector())
1209 return Query.
Types[0] != EltTy;
1214 return VecTy == v8s8 || VecTy == v16s8 || VecTy == v2s16 ||
1215 VecTy == v4s16 || VecTy == v8s16 || VecTy == v2s32 ||
1216 VecTy == v4s32 || VecTy == v2s64 || VecTy == v2p0;
1222 return Query.
Types[1].isFixedVector() &&
1223 Query.
Types[1].getNumElements() <= 2;
1228 return Query.
Types[1].isFixedVector() &&
1229 Query.
Types[1].getNumElements() <= 4;
1234 return Query.
Types[1].isFixedVector() &&
1235 Query.
Types[1].getNumElements() <= 8;
1240 return Query.
Types[1].isFixedVector() &&
1241 Query.
Types[1].getNumElements() <= 16;
1244 .minScalarOrElt(0, s8)
1245 .moreElementsToNextPow2(1)
1246 .clampMaxNumElements(1, s64, 2)
1247 .clampMaxNumElements(1, s32, 4)
1248 .clampMaxNumElements(1, s16, 8)
1249 .clampMaxNumElements(1, s8, 16)
1250 .clampMaxNumElements(1, p0, 2)
1253 getActionDefinitionsBuilder(G_INSERT_VECTOR_ELT)
1255 typeInSet(0, {v8s8, v16s8, v4s16, v8s16, v2s32, v4s32, v2s64, v2p0}))
1256 .legalFor(HasSVE, {{nxv16s8, s32, s64},
1257 {nxv8s16, s32, s64},
1258 {nxv4s32, s32, s64},
1259 {nxv2s64, s64, s64}})
1261 .widenVectorEltsToVectorMinSize(0, 64)
1262 .clampNumElements(0, v8s8, v16s8)
1263 .clampNumElements(0, v4s16, v8s16)
1264 .clampNumElements(0, v2s32, v4s32)
1265 .clampMaxNumElements(0, s64, 2)
1266 .clampMaxNumElements(0, p0, 2)
1269 getActionDefinitionsBuilder(G_BUILD_VECTOR)
1270 .legalFor({{v8s8, s8},
1278 .clampNumElements(0, v4s32, v4s32)
1279 .clampNumElements(0, v2s64, v2s64)
1280 .minScalarOrElt(0, s8)
1281 .widenVectorEltsToVectorMinSize(0, 64)
1282 .widenScalarOrEltToNextPow2(0)
1283 .minScalarSameAs(1, 0);
1285 getActionDefinitionsBuilder(G_BUILD_VECTOR_TRUNC).lower();
1287 getActionDefinitionsBuilder(G_SHUFFLE_VECTOR)
1296 {v8s8, v16s8, v4s16, v8s16, v2s32, v4s32, v2s64}, DstTy);
1300 return Query.
Types[0].getNumElements() >
1301 Query.
Types[1].getNumElements();
1307 return Query.
Types[0].getNumElements() <
1308 Query.
Types[1].getNumElements();
1311 .widenScalarOrEltToNextPow2OrMinSize(0, 8)
1312 .clampNumElements(0, v8s8, v16s8)
1313 .clampNumElements(0, v4s16, v8s16)
1314 .clampNumElements(0, v4s32, v4s32)
1315 .clampNumElements(0, v2s64, v2s64)
1324 getActionDefinitionsBuilder(G_CONCAT_VECTORS)
1325 .legalFor({{v16s8, v8s8}, {v8s16, v4s16}, {v4s32, v2s32}})
1327 return Query.
Types[0].isFixedVector() &&
1328 Query.
Types[0].getScalarSizeInBits() < 8;
1332 return Query.
Types[0].isFixedVector() &&
1333 Query.
Types[1].isFixedVector() &&
1334 Query.
Types[0].getScalarSizeInBits() >= 8 &&
1336 Query.
Types[0].getSizeInBits() <= 128 &&
1337 Query.
Types[1].getSizeInBits() <= 64;
1349 getActionDefinitionsBuilder(G_EXTRACT_SUBVECTOR)
1350 .legalFor({{v8s8, v16s8}, {v4s16, v8s16}, {v2s32, v4s32}})
1355 getActionDefinitionsBuilder(G_SPLAT_VECTOR)
1356 .legalFor(HasSVE, {{nxv4s32, s32}, {nxv2s64, s64}});
1358 getActionDefinitionsBuilder(G_JUMP_TABLE).legalFor({p0});
1360 getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, s64}});
1362 getActionDefinitionsBuilder({G_TRAP, G_DEBUGTRAP, G_UBSANTRAP}).alwaysLegal();
1364 getActionDefinitionsBuilder(G_DYN_STACKALLOC).custom();
1366 getActionDefinitionsBuilder({G_STACKSAVE, G_STACKRESTORE}).lower();
1371 getActionDefinitionsBuilder(G_BZERO).unsupported();
1373 getActionDefinitionsBuilder(G_MEMSET)
1374 .legalForCartesianProduct({p0}, {s64}, {s64})
1375 .customForCartesianProduct({p0}, {s8}, {s64})
1378 getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE})
1379 .legalForCartesianProduct({p0}, {p0}, {s64})
1383 getActionDefinitionsBuilder(G_MEMCPY_INLINE)
1384 .legalForCartesianProduct({p0}, {p0}, {s64});
1387 getActionDefinitionsBuilder({G_BZERO, G_MEMCPY, G_MEMMOVE, G_MEMSET})
1394 getActionDefinitionsBuilder(G_VECREDUCE_FADD)
1395 .legalFor({{f32, v2f32}, {f32, v4f32}, {f64, v2f64}})
1396 .legalFor(HasFP16, {{f16, v4f16}, {f16, v8f16}})
1397 .minScalarOrElt(0, MinFPScalar)
1398 .clampMaxNumElements(1, s64, 2)
1399 .clampMaxNumElements(1, s32, 4)
1400 .clampMaxNumElements(1, s16, 8)
1401 .moreElementsToNextPow2(1)
1408 getActionDefinitionsBuilder(G_VECREDUCE_FMUL)
1409 .minScalarOrElt(0, MinFPScalar)
1410 .clampMaxNumElements(1, s64, 2)
1411 .clampMaxNumElements(1, s32, 4)
1412 .clampMaxNumElements(1, s16, 8)
1413 .clampMaxNumElements(1, s32, 2)
1414 .clampMaxNumElements(1, s16, 4)
1418 getActionDefinitionsBuilder({G_VECREDUCE_SEQ_FADD, G_VECREDUCE_SEQ_FMUL})
1422 getActionDefinitionsBuilder(G_VECREDUCE_ADD)
1423 .legalFor({{i8, v8i8},
1431 .clampMaxNumElements(1, s64, 2)
1432 .clampMaxNumElements(1, s32, 4)
1433 .clampMaxNumElements(1, s16, 8)
1434 .clampMaxNumElements(1, s8, 16)
1435 .widenVectorEltsToVectorMinSize(1, 64)
1438 getActionDefinitionsBuilder({G_VECREDUCE_FMIN, G_VECREDUCE_FMAX,
1439 G_VECREDUCE_FMINIMUM, G_VECREDUCE_FMAXIMUM})
1440 .legalFor({{f32, v2f32}, {f32, v4f32}, {f64, v2f64}})
1441 .legalFor(HasFP16, {{f16, v4f16}, {f16, v8f16}})
1442 .minScalarOrElt(0, MinFPScalar)
1443 .clampMaxNumElements(1, s64, 2)
1444 .clampMaxNumElements(1, s32, 4)
1445 .clampMaxNumElements(1, s16, 8)
1449 getActionDefinitionsBuilder(G_VECREDUCE_MUL)
1450 .clampMaxNumElements(1, s32, 2)
1451 .clampMaxNumElements(1, s16, 4)
1452 .clampMaxNumElements(1, s8, 8)
1456 getActionDefinitionsBuilder(
1457 {G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX})
1458 .legalFor({{i8, v8i8},
1466 return Query.
Types[1].isVector() &&
1467 Query.
Types[1].getElementType() != s8 &&
1468 Query.
Types[1].getNumElements() & 1;
1471 .clampMaxNumElements(1, s64, 2)
1472 .clampMaxNumElements(1, s32, 4)
1473 .clampMaxNumElements(1, s16, 8)
1474 .clampMaxNumElements(1, s8, 16)
1478 getActionDefinitionsBuilder(
1479 {G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
1495 return std::make_pair(1, SrcTy.
divide(2));
1501 getActionDefinitionsBuilder(G_VECTOR_COMPRESS).lower();
1504 getActionDefinitionsBuilder({G_GET_FPENV, G_SET_FPENV, G_RESET_FPENV,
1505 G_GET_FPMODE, G_SET_FPMODE, G_RESET_FPMODE})
1508 getActionDefinitionsBuilder(G_IS_FPCLASS).lower();
1510 getActionDefinitionsBuilder(G_PREFETCH).custom();
1512 getActionDefinitionsBuilder({G_SCMP, G_UCMP}).lower();
1514 getActionDefinitionsBuilder({G_INTRINSIC, G_INTRINSIC_W_SIDE_EFFECTS})
1516 getActionDefinitionsBuilder(G_FENCE).alwaysLegal();
1517 getActionDefinitionsBuilder(G_INVOKE_REGION_START).alwaysLegal();
1519 getLegacyLegalizerInfo().computeTables();
1765 auto LowerUnaryOp = [&
MI, &MIB](
unsigned Opcode) {
1767 MI.eraseFromParent();
1770 auto LowerBinOp = [&
MI, &MIB](
unsigned Opcode) {
1772 {
MI.getOperand(2),
MI.getOperand(3)});
1773 MI.eraseFromParent();
1776 auto LowerTriOp = [&
MI, &MIB](
unsigned Opcode) {
1778 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4)});
1779 MI.eraseFromParent();
1784 switch (IntrinsicID) {
1785 case Intrinsic::vacopy: {
1786 unsigned PtrSize = ST->isTargetILP32() ? 4 : 8;
1787 unsigned VaListSize =
1788 (ST->isTargetDarwin() || ST->isTargetWindows())
1790 : ST->isTargetILP32() ? 20 : 32;
1798 VaListSize,
Align(PtrSize)));
1802 VaListSize,
Align(PtrSize)));
1803 MI.eraseFromParent();
1806 case Intrinsic::get_dynamic_area_offset: {
1808 MI.eraseFromParent();
1811 case Intrinsic::aarch64_mops_memset_tag: {
1812 assert(
MI.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS);
1815 auto &
Value =
MI.getOperand(3);
1817 Value.setReg(ExtValueReg);
1820 case Intrinsic::aarch64_prefetch: {
1821 auto &AddrVal =
MI.getOperand(1);
1823 int64_t IsWrite =
MI.getOperand(2).getImm();
1824 int64_t
Target =
MI.getOperand(3).getImm();
1825 int64_t IsStream =
MI.getOperand(4).getImm();
1826 int64_t IsData =
MI.getOperand(5).getImm();
1828 unsigned PrfOp = (IsWrite << 4) |
1834 MI.eraseFromParent();
1837 case Intrinsic::aarch64_range_prefetch: {
1838 auto &AddrVal =
MI.getOperand(1);
1840 int64_t IsWrite =
MI.getOperand(2).getImm();
1841 int64_t IsStream =
MI.getOperand(3).getImm();
1842 unsigned PrfOp = (IsStream << 2) | IsWrite;
1844 MIB.
buildInstr(AArch64::G_AARCH64_RANGE_PREFETCH)
1847 .
addUse(
MI.getOperand(4).getReg());
1848 MI.eraseFromParent();
1851 case Intrinsic::aarch64_prefetch_ir: {
1852 auto &AddrVal =
MI.getOperand(1);
1854 MI.eraseFromParent();
1857 case Intrinsic::aarch64_neon_uaddv:
1858 case Intrinsic::aarch64_neon_saddv:
1859 case Intrinsic::aarch64_neon_umaxv:
1860 case Intrinsic::aarch64_neon_smaxv:
1861 case Intrinsic::aarch64_neon_uminv:
1862 case Intrinsic::aarch64_neon_sminv: {
1863 bool IsSigned = IntrinsicID == Intrinsic::aarch64_neon_saddv ||
1864 IntrinsicID == Intrinsic::aarch64_neon_smaxv ||
1865 IntrinsicID == Intrinsic::aarch64_neon_sminv;
1867 auto OldDst =
MI.getOperand(0).getReg();
1868 auto OldDstTy = MRI.
getType(OldDst);
1870 if (OldDstTy == NewDstTy)
1876 MI.getOperand(0).setReg(NewDst);
1880 MIB.
buildExtOrTrunc(IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT,
1885 case Intrinsic::aarch64_neon_uaddlp:
1886 case Intrinsic::aarch64_neon_saddlp: {
1887 unsigned Opc = IntrinsicID == Intrinsic::aarch64_neon_uaddlp
1889 : AArch64::G_SADDLP;
1891 MI.eraseFromParent();
1895 case Intrinsic::aarch64_neon_uaddlv:
1896 case Intrinsic::aarch64_neon_saddlv: {
1897 unsigned Opc = IntrinsicID == Intrinsic::aarch64_neon_uaddlv
1899 : AArch64::G_SADDLV;
1926 MI.eraseFromParent();
1930 case Intrinsic::aarch64_neon_smax:
1931 return LowerBinOp(TargetOpcode::G_SMAX);
1932 case Intrinsic::aarch64_neon_smin:
1933 return LowerBinOp(TargetOpcode::G_SMIN);
1934 case Intrinsic::aarch64_neon_umax:
1935 return LowerBinOp(TargetOpcode::G_UMAX);
1936 case Intrinsic::aarch64_neon_umin:
1937 return LowerBinOp(TargetOpcode::G_UMIN);
1938 case Intrinsic::aarch64_neon_fmax:
1939 return LowerBinOp(TargetOpcode::G_FMAXIMUM);
1940 case Intrinsic::aarch64_neon_fmin:
1941 return LowerBinOp(TargetOpcode::G_FMINIMUM);
1942 case Intrinsic::aarch64_neon_fmaxnm:
1943 return LowerBinOp(TargetOpcode::G_FMAXNUM);
1944 case Intrinsic::aarch64_neon_fminnm:
1945 return LowerBinOp(TargetOpcode::G_FMINNUM);
1946 case Intrinsic::aarch64_neon_pmul:
1947 return LowerBinOp(TargetOpcode::G_CLMUL);
1948 case Intrinsic::aarch64_neon_pmull:
1949 case Intrinsic::aarch64_neon_pmull64:
1950 return LowerBinOp(AArch64::G_PMULL);
1951 case Intrinsic::aarch64_neon_smull:
1952 return LowerBinOp(AArch64::G_SMULL);
1953 case Intrinsic::aarch64_neon_umull:
1954 return LowerBinOp(AArch64::G_UMULL);
1955 case Intrinsic::aarch64_neon_sabd:
1956 return LowerBinOp(TargetOpcode::G_ABDS);
1957 case Intrinsic::aarch64_neon_uabd:
1958 return LowerBinOp(TargetOpcode::G_ABDU);
1959 case Intrinsic::aarch64_neon_uhadd:
1960 return LowerBinOp(TargetOpcode::G_UAVGFLOOR);
1961 case Intrinsic::aarch64_neon_urhadd:
1962 return LowerBinOp(TargetOpcode::G_UAVGCEIL);
1963 case Intrinsic::aarch64_neon_shadd:
1964 return LowerBinOp(TargetOpcode::G_SAVGFLOOR);
1965 case Intrinsic::aarch64_neon_srhadd:
1966 return LowerBinOp(TargetOpcode::G_SAVGCEIL);
1967 case Intrinsic::aarch64_neon_sqshrn: {
1972 {MRI.
getType(
MI.getOperand(2).getReg())},
1973 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
1975 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {
MI.getOperand(0)}, {Shr});
1976 MI.eraseFromParent();
1979 case Intrinsic::aarch64_neon_sqshrun: {
1984 {MRI.
getType(
MI.getOperand(2).getReg())},
1985 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
1987 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {
MI.getOperand(0)}, {Shr});
1988 MI.eraseFromParent();
1991 case Intrinsic::aarch64_neon_sqrshrn: {
1995 auto Shr = MIB.
buildInstr(AArch64::G_SRSHR_I,
1996 {MRI.
getType(
MI.getOperand(2).getReg())},
1997 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
1999 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {
MI.getOperand(0)}, {Shr});
2000 MI.eraseFromParent();
2003 case Intrinsic::aarch64_neon_sqrshrun: {
2007 auto Shr = MIB.
buildInstr(AArch64::G_SRSHR_I,
2008 {MRI.
getType(
MI.getOperand(2).getReg())},
2009 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2011 MIB.
buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {
MI.getOperand(0)}, {Shr});
2012 MI.eraseFromParent();
2015 case Intrinsic::aarch64_neon_uqrshrn: {
2019 auto Shr = MIB.
buildInstr(AArch64::G_URSHR_I,
2020 {MRI.
getType(
MI.getOperand(2).getReg())},
2021 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2023 MIB.
buildInstr(TargetOpcode::G_TRUNC_USAT_U, {
MI.getOperand(0)}, {Shr});
2024 MI.eraseFromParent();
2027 case Intrinsic::aarch64_neon_uqshrn: {
2032 {MRI.
getType(
MI.getOperand(2).getReg())},
2033 {
MI.getOperand(2),
MI.getOperand(3).getImm()});
2035 MIB.
buildInstr(TargetOpcode::G_TRUNC_USAT_U, {
MI.getOperand(0)}, {Shr});
2036 MI.eraseFromParent();
2039 case Intrinsic::aarch64_neon_sqshlu: {
2045 MIB.
buildInstr(AArch64::G_SQSHLU_I, {
MI.getOperand(0)},
2047 .addImm(ShiftAmount->getSExtValue());
2048 MI.eraseFromParent();
2053 case Intrinsic::aarch64_neon_vsli: {
2055 AArch64::G_SLI, {
MI.getOperand(0)},
2056 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4).getImm()});
2057 MI.eraseFromParent();
2060 case Intrinsic::aarch64_neon_vsri: {
2062 AArch64::G_SRI, {
MI.getOperand(0)},
2063 {
MI.getOperand(2),
MI.getOperand(3),
MI.getOperand(4).getImm()});
2064 MI.eraseFromParent();
2067 case Intrinsic::aarch64_neon_abs: {
2069 MIB.
buildInstr(TargetOpcode::G_ABS, {
MI.getOperand(0)}, {
MI.getOperand(2)});
2070 MI.eraseFromParent();
2073 case Intrinsic::aarch64_neon_sqadd: {
2075 return LowerBinOp(TargetOpcode::G_SADDSAT);
2078 case Intrinsic::aarch64_neon_sqsub: {
2080 return LowerBinOp(TargetOpcode::G_SSUBSAT);
2083 case Intrinsic::aarch64_neon_uqadd: {
2085 return LowerBinOp(TargetOpcode::G_UADDSAT);
2088 case Intrinsic::aarch64_neon_uqsub: {
2090 return LowerBinOp(TargetOpcode::G_USUBSAT);
2093 case Intrinsic::aarch64_neon_udot:
2094 return LowerTriOp(AArch64::G_UDOT);
2095 case Intrinsic::aarch64_neon_sdot:
2096 return LowerTriOp(AArch64::G_SDOT);
2097 case Intrinsic::aarch64_neon_usdot:
2098 return LowerTriOp(AArch64::G_USDOT);
2099 case Intrinsic::aarch64_neon_sqxtn:
2100 return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_S);
2101 case Intrinsic::aarch64_neon_sqxtun:
2102 return LowerUnaryOp(TargetOpcode::G_TRUNC_SSAT_U);
2103 case Intrinsic::aarch64_neon_uqxtn:
2104 return LowerUnaryOp(TargetOpcode::G_TRUNC_USAT_U);
2105 case Intrinsic::aarch64_neon_fcvtzu:
2106 return LowerUnaryOp(TargetOpcode::G_FPTOUI_SAT);
2107 case Intrinsic::aarch64_neon_fcvtzs:
2108 return LowerUnaryOp(TargetOpcode::G_FPTOSI_SAT);
2110 case Intrinsic::vector_reverse: