76#include "llvm/IR/IntrinsicsAArch64.h"
111#define DEBUG_TYPE "aarch64-lower"
114STATISTIC(NumOptimizedImms,
"Number of times immediates were optimized");
121 cl::desc(
"Allow AArch64 Local Dynamic TLS code generation"),
126 cl::desc(
"Enable AArch64 logical imm instruction "
136 cl::desc(
"Combine extends of AArch64 masked "
137 "gather intrinsics"),
141 cl::desc(
"Combine ext and trunc to TBL"),
156 cl::desc(
"Enable / disable SVE scalable vectors in Global ISel"),
160 "aarch64-br-merging-base-cost",
cl::init(2),
162 "Cost threshold for merging multiple conditionals into one branch "
163 "versus splitting into multiple branches: conditionals are merged when "
164 "their instruction cost is below this limit and split above it. Set to "
165 "-1 to never merge branches."),
169 "aarch64-br-merging-ccmp-bias",
cl::init(6),
170 cl::desc(
"Increases 'aarch64-br-merging-base-cost' to account for the "
171 "CCMP instruction, which is always available on AArch64 and "
172 "makes merging branch conditions cheaper."),
176 "aarch64-br-merging-cbz-tbnz-bias",
cl::init(6),
177 cl::desc(
"Decreases 'aarch64-br-merging-base-cost' when a condition can "
178 "lower to a single CBZ/CBNZ or TBZ/TBNZ compare-and-branch, to "
179 "bias toward splitting. Set to 0 to disable."),
183 "aarch64-br-merging-likely-bias",
cl::init(0),
184 cl::desc(
"Increases 'aarch64-br-merging-base-cost' when all conditionals "
185 "are likely to be executed, biasing toward merging. Set to -1 to "
186 "never merge likely branches."),
190 "aarch64-br-merging-unlikely-bias",
cl::init(-1),
192 "Decreases 'aarch64-br-merging-base-cost' when all conditionals are "
193 "unlikely to be executed, biasing toward splitting. Set to -1 to never "
194 "merge unlikely branches."),
201 cl::desc(
"Generate ISD::PTRADD nodes for pointer arithmetic in "
202 "SelectionDAG for FEAT_CPA"),
209 "aarch64-use-conditional-fpmr-write",
cl::Hidden,
210 cl::desc(
"Only write FPMR when the requested value differs from the "
218 cl::desc(
"Use SVE for fixed-length vector bfloat operations"),
228 AArch64::X3, AArch64::X4, AArch64::X5,
229 AArch64::X6, AArch64::X7};
231 AArch64::Q3, AArch64::Q4, AArch64::Q5,
232 AArch64::Q6, AArch64::Q7};
257 return MVT::nxv8bf16;
264 switch (EC.getKnownMinValue()) {
280 "Expected scalable predicate vector type!");
302 "Expected legal vector type!");
309 "Expected legal type!");
310 return VT == MVT::nxv16i1;
323 "Unexpected fixed-size unpacked type.");
333 case AArch64ISD::BITREVERSE_MERGE_PASSTHRU:
334 case AArch64ISD::BSWAP_MERGE_PASSTHRU:
335 case AArch64ISD::REVH_MERGE_PASSTHRU:
336 case AArch64ISD::REVW_MERGE_PASSTHRU:
337 case AArch64ISD::REVD_MERGE_PASSTHRU:
338 case AArch64ISD::CTLZ_MERGE_PASSTHRU:
339 case AArch64ISD::CTPOP_MERGE_PASSTHRU:
340 case AArch64ISD::DUP_MERGE_PASSTHRU:
341 case AArch64ISD::ABS_MERGE_PASSTHRU:
342 case AArch64ISD::NEG_MERGE_PASSTHRU:
343 case AArch64ISD::FNEG_MERGE_PASSTHRU:
344 case AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU:
345 case AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU:
346 case AArch64ISD::FCEIL_MERGE_PASSTHRU:
347 case AArch64ISD::FFLOOR_MERGE_PASSTHRU:
348 case AArch64ISD::FNEARBYINT_MERGE_PASSTHRU:
349 case AArch64ISD::FRINT_MERGE_PASSTHRU:
350 case AArch64ISD::FRINT32_MERGE_PASSTHRU:
351 case AArch64ISD::FRINT64_MERGE_PASSTHRU:
352 case AArch64ISD::FROUND_MERGE_PASSTHRU:
353 case AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU:
354 case AArch64ISD::FTRUNC_MERGE_PASSTHRU:
355 case AArch64ISD::FTRUNC32_MERGE_PASSTHRU:
356 case AArch64ISD::FTRUNC64_MERGE_PASSTHRU:
357 case AArch64ISD::FP_ROUND_MERGE_PASSTHRU:
358 case AArch64ISD::FP_EXTEND_MERGE_PASSTHRU:
359 case AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU:
360 case AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU:
361 case AArch64ISD::FCVTX_MERGE_PASSTHRU:
362 case AArch64ISD::FCVTZU_MERGE_PASSTHRU:
363 case AArch64ISD::FCVTZS_MERGE_PASSTHRU:
364 case AArch64ISD::FSQRT_MERGE_PASSTHRU:
365 case AArch64ISD::FRECPX_MERGE_PASSTHRU:
366 case AArch64ISD::FABS_MERGE_PASSTHRU:
367 case AArch64ISD::STRICT_FCEIL_MERGE_PASSTHRU:
368 case AArch64ISD::STRICT_FFLOOR_MERGE_PASSTHRU:
369 case AArch64ISD::STRICT_FNEARBYINT_MERGE_PASSTHRU:
370 case AArch64ISD::STRICT_FROUND_MERGE_PASSTHRU:
371 case AArch64ISD::STRICT_FROUNDEVEN_MERGE_PASSTHRU:
372 case AArch64ISD::STRICT_FTRUNC_MERGE_PASSTHRU:
373 case AArch64ISD::STRICT_FSQRT_MERGE_PASSTHRU:
380 switch (
Op.getOpcode()) {
386 case AArch64ISD::PTRUE:
387 case AArch64ISD::SETCC_MERGE_ZERO:
390 switch (
Op.getConstantOperandVal(0)) {
393 case Intrinsic::aarch64_sve_ptrue:
394 case Intrinsic::aarch64_sve_pnext:
395 case Intrinsic::aarch64_sve_cmpeq:
396 case Intrinsic::aarch64_sve_cmpne:
397 case Intrinsic::aarch64_sve_cmpge:
398 case Intrinsic::aarch64_sve_cmpgt:
399 case Intrinsic::aarch64_sve_cmphs:
400 case Intrinsic::aarch64_sve_cmphi:
401 case Intrinsic::aarch64_sve_cmpeq_wide:
402 case Intrinsic::aarch64_sve_cmpne_wide:
403 case Intrinsic::aarch64_sve_cmpge_wide:
404 case Intrinsic::aarch64_sve_cmpgt_wide:
405 case Intrinsic::aarch64_sve_cmplt_wide:
406 case Intrinsic::aarch64_sve_cmple_wide:
407 case Intrinsic::aarch64_sve_cmphs_wide:
408 case Intrinsic::aarch64_sve_cmphi_wide:
409 case Intrinsic::aarch64_sve_cmplo_wide:
410 case Intrinsic::aarch64_sve_cmpls_wide:
411 case Intrinsic::aarch64_sve_fcmpeq:
412 case Intrinsic::aarch64_sve_fcmpne:
413 case Intrinsic::aarch64_sve_fcmpge:
414 case Intrinsic::aarch64_sve_fcmpgt:
415 case Intrinsic::aarch64_sve_fcmpuo:
416 case Intrinsic::aarch64_sve_facgt:
417 case Intrinsic::aarch64_sve_facge:
418 case Intrinsic::aarch64_sve_whilege:
419 case Intrinsic::aarch64_sve_whilegt:
420 case Intrinsic::aarch64_sve_whilehi:
421 case Intrinsic::aarch64_sve_whilehs:
422 case Intrinsic::aarch64_sve_whilele:
423 case Intrinsic::aarch64_sve_whilelo:
424 case Intrinsic::aarch64_sve_whilels:
425 case Intrinsic::aarch64_sve_whilelt:
426 case Intrinsic::aarch64_sve_match:
427 case Intrinsic::aarch64_sve_nmatch:
428 case Intrinsic::aarch64_sve_whilege_x2:
429 case Intrinsic::aarch64_sve_whilegt_x2:
430 case Intrinsic::aarch64_sve_whilehi_x2:
431 case Intrinsic::aarch64_sve_whilehs_x2:
432 case Intrinsic::aarch64_sve_whilele_x2:
433 case Intrinsic::aarch64_sve_whilelo_x2:
434 case Intrinsic::aarch64_sve_whilels_x2:
435 case Intrinsic::aarch64_sve_whilelt_x2:
441static std::tuple<SDValue, SDValue>
462 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
468 AddrDisc = DAG->
getRegister(AArch64::NoRegister, MVT::i64);
470 return std::make_tuple(
489 if (Subtarget->hasLS64()) {
495 if (Subtarget->hasFPARMv8()) {
504 if (Subtarget->hasNEON()) {
508 addDRType(MVT::v2f32);
509 addDRType(MVT::v8i8);
510 addDRType(MVT::v4i16);
511 addDRType(MVT::v2i32);
512 addDRType(MVT::v1i64);
513 addDRType(MVT::v1f64);
514 addDRType(MVT::v4f16);
515 addDRType(MVT::v4bf16);
517 addQRType(MVT::v4f32);
518 addQRType(MVT::v2f64);
519 addQRType(MVT::v16i8);
520 addQRType(MVT::v8i16);
521 addQRType(MVT::v4i32);
522 addQRType(MVT::v2i64);
523 addQRType(MVT::v8f16);
524 addQRType(MVT::v8bf16);
527 if (Subtarget->isSVEorStreamingSVEAvailable()) {
555 if (Subtarget->useSVEForFixedLengthVectors()) {
597 if (Subtarget->hasFPARMv8()) {
688 if (Subtarget->hasFPARMv8()) {
694 if (Subtarget->hasFPARMv8()) {
748 if (Subtarget->hasCSSC()) {
827 if (Subtarget->hasFullFP16()) {
859 if (Subtarget->hasFullFP16()) {
872 auto LegalizeNarrowFP = [
this](
MVT ScalarVT) {
980 if (!Subtarget->hasFullFP16()) {
981 LegalizeNarrowFP(MVT::f16);
983 LegalizeNarrowFP(MVT::bf16);
1001 for (
MVT Ty : {MVT::f32, MVT::f64})
1003 if (Subtarget->hasFullFP16())
1011 for (
MVT Ty : {MVT::f32, MVT::f64})
1013 if (Subtarget->hasFullFP16())
1026 if (!Subtarget->hasLSE() && !Subtarget->outlineAtomics()) {
1038 if (Subtarget->outlineAtomics() && !Subtarget->hasLSE()) {
1066 if (Subtarget->hasLSE128()) {
1080 if (Subtarget->hasLSE2()) {
1137 if (WideVT.getScalarSizeInBits() > NarrowVT.getScalarSizeInBits()) {
1143 if (Subtarget->hasFPARMv8()) {
1241 if (Subtarget->isSVEorStreamingSVEAvailable())
1275 if (!Subtarget->isTargetWindows())
1291 if (Subtarget->hasSME())
1294 if (Subtarget->isNeonAvailable()) {
1339 for (
auto VT : {MVT::v2i32, MVT::v2i64, MVT::v4i32})
1342 if (Subtarget->hasFullFP16()) {
1371 for (
auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v2i32,
1380 for (
auto VT : {MVT::v1i64, MVT::v2i64}) {
1396 for (
MVT VT : { MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v1i64,
1397 MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
1404 for (
MVT VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32, MVT::v16i8, MVT::v8i16,
1415 for (
MVT VT : { MVT::v4f16, MVT::v2f32,
1416 MVT::v8f16, MVT::v4f32, MVT::v2f64 }) {
1417 if (VT.getVectorElementType() != MVT::f16 || Subtarget->hasFullFP16()) {
1426 if (Subtarget->hasFullFP16())
1429 for (
MVT VT : { MVT::v8i8, MVT::v4i16, MVT::v2i32,
1430 MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
1445 for (
MVT VT : {MVT::v4i16, MVT::v8i16, MVT::v2i32, MVT::v4i32})
1455 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32) {
1465 if (VT == MVT::v4i16 || VT == MVT::v8i16 || VT == MVT::v2i32 ||
1466 VT == MVT::v4i32 || VT == MVT::v2i64)
1471 if (VT == MVT::v8i8 || VT == MVT::v16i8 || VT == MVT::v8i16 ||
1472 VT == MVT::v4i16 || VT == MVT::v2i32 || VT == MVT::v4i32)
1491 for (
MVT Ty : {MVT::v2f32, MVT::v4f32, MVT::v2f64})
1493 if (Subtarget->hasFullFP16())
1494 for (
MVT Ty : {MVT::v4f16, MVT::v8f16})
1500 for (
MVT Ty : {MVT::v2f32, MVT::v4f32, MVT::v2f64})
1502 if (Subtarget->hasFullFP16())
1503 for (
MVT Ty : {MVT::v4f16, MVT::v8f16})
1538 for (
MVT VT : { MVT::v32i8, MVT::v16i16, MVT::v8i32, MVT::v4i64 })
1541 for (
MVT VT : { MVT::v16f16, MVT::v8f32, MVT::v4f64 })
1556 if (Subtarget->hasDotProd()) {
1573 if (Subtarget->hasMatMulInt8()) {
1588 if (Subtarget->hasF16F32DOT() || Subtarget->hasFP16FML()) {
1595 if (Subtarget->hasBF16())
1597 MVT::v8bf16,
Legal);
1601 if (Subtarget->hasAES()) {
1613 if (VT.is128BitVector() || VT.is64BitVector()) {
1628 for (
MVT VT : {MVT::v8i16, MVT::v4i32, MVT::v2i64}) {
1638 if (Subtarget->isSVEorStreamingSVEAvailable()) {
1640 {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1, MVT::nxv1i1}) {
1646 for (
auto VT : {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1}) {
1653 if (Subtarget->hasSVE2() && Subtarget->isSVEAvailable()) {
1654 for (
MVT VT : {MVT::nxv16i1, MVT::nxv8i1})
1657 for (
MVT VT : {MVT::v16i1, MVT::v8i1, MVT::v16i8, MVT::v8i8})
1663 if (Subtarget->isSVEorStreamingSVEAvailable() &&
1664 (Subtarget->hasSVE2p1() || Subtarget->hasSME2()))
1667 for (
auto VT : {MVT::v16i8, MVT::v8i8, MVT::v4i16, MVT::v2i32})
1670 for (
auto VT : {MVT::v8f16, MVT::v4f32, MVT::v2f64})
1674 if (Subtarget->isSVEorStreamingSVEAvailable()) {
1675 for (
auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
1746 if (!Subtarget->isLittleEndian())
1749 if (Subtarget->hasSVE2() ||
1750 (Subtarget->hasSME() && Subtarget->isStreaming()))
1755 for (
auto VT : {MVT::nxv4i32, MVT::nxv2i64}) {
1761 for (
auto VT : {MVT::nxv8i8, MVT::nxv4i16, MVT::nxv2i32}) {
1767 for (
auto VT : {MVT::nxv2i16, MVT::nxv4i16, MVT::nxv2i32})
1771 { MVT::nxv2i8, MVT::nxv2i16, MVT::nxv2i32, MVT::nxv2i64, MVT::nxv4i8,
1772 MVT::nxv4i16, MVT::nxv4i32, MVT::nxv8i8, MVT::nxv8i16 })
1784 {MVT::nxv16i1, MVT::nxv8i1, MVT::nxv4i1, MVT::nxv2i1, MVT::nxv1i1}) {
1798 if (VT != MVT::nxv16i1) {
1808 {MVT::v4f16, MVT::v8f16, MVT::v4bf16, MVT::v8bf16, MVT::v2f32,
1809 MVT::v4f32, MVT::v1f64, MVT::v2f64, MVT::v8i8, MVT::v16i8, MVT::v4i16,
1810 MVT::v8i16, MVT::v2i32, MVT::v4i32, MVT::v1i64, MVT::v2i64}) {
1848 for (
auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
1849 MVT::nxv4f32, MVT::nxv2f64}) {
1949 for (
auto VT : {MVT::nxv2bf16, MVT::nxv4bf16, MVT::nxv8bf16}) {
1968 if (Subtarget->hasSVEB16B16() &&
1969 Subtarget->isNonStreamingSVEorSME2Available()) {
1971 for (
auto VT : {MVT::v4bf16, MVT::v8bf16, MVT::nxv2bf16, MVT::nxv4bf16,
1994 if (!Subtarget->hasSVEB16B16() ||
1995 !Subtarget->isNonStreamingSVEorSME2Available()) {
1996 for (
MVT VT : {MVT::nxv2bf16, MVT::nxv4bf16, MVT::nxv8bf16}) {
2006 if (VT != MVT::nxv2bf16 && Subtarget->hasBF16())
2012 if (Subtarget->hasBF16() && Subtarget->isNeonAvailable())
2021 for (
auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v2i32,
2022 MVT::v4i32, MVT::v1i64, MVT::v2i64}) {
2031 for (
auto VT : {MVT::v4i16, MVT::v8i16, MVT::v2i32, MVT::v4i32, MVT::v1i64,
2045 for (
auto VT : {MVT::v1i64, MVT::v2i64}) {
2052 if (Subtarget->useSVEForFixedLengthVectors()) {
2055 VT, !Subtarget->isNeonAvailable()))
2056 addTypeForFixedLengthSVE(VT);
2060 VT, !Subtarget->isNeonAvailable()))
2061 addTypeForFixedLengthSVE(VT);
2065 for (
auto VT : {MVT::v8i8, MVT::v4i16})
2070 for (
auto VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
2072 for (
auto VT : {MVT::v8f16, MVT::v4f32, MVT::v8bf16})
2090 for (
auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v2i32,
2091 MVT::v4i32, MVT::v2i64}) {
2098 for (
auto VT : {MVT::v4f16, MVT::v8f16, MVT::v4f32})
2121 for (
auto VT : {MVT::v16i1, MVT::v8i1, MVT::v4i1, MVT::v2i1})
2128 if (Subtarget->enableSubRegLiveness() &&
2129 (Subtarget->hasSVE2p1() ||
2130 (Subtarget->hasSME2() && Subtarget->isStreaming()))) {
2157 if (Subtarget->isSVEorStreamingSVEAvailable()) {
2167 if (Subtarget->hasMatMulInt8()) {
2169 MVT::nxv16i8,
Legal);
2174 if (Subtarget->hasSVE2() || Subtarget->hasSME()) {
2184 MVT::nxv8f16,
Legal);
2188 if (!Subtarget->isNeonAvailable() ||
2189 (!Subtarget->hasF16F32DOT() && !Subtarget->hasFP16FML())) {
2198 if (Subtarget->hasSVEBitPerm() &&
2199 (Subtarget->isSVEAvailable() ||
2200 (Subtarget->isSVEorStreamingSVEAvailable() &&
2201 Subtarget->hasSSVE_BitPerm()))) {
2202 for (
auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64}) {
2209 if (Subtarget->hasBF16())
2211 MVT::nxv8bf16,
Legal);
2215 if (Subtarget->isSVEAvailable() ||
2216 (Subtarget->isSVEorStreamingSVEAvailable() && Subtarget->hasSME2p2())) {
2219 {MVT::nxv4i32, MVT::nxv2i64, MVT::nxv2f32, MVT::nxv4f32, MVT::nxv2f64})
2224 for (
auto VT : {MVT::v2i32, MVT::v4i32, MVT::v2i64, MVT::v2f32, MVT::v4f32,
2228 if (Subtarget->hasSVE2p2() || Subtarget->hasSME2p2()) {
2230 for (
auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv8f16, MVT::nxv8bf16})
2233 for (
auto VT : {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v4f16,
2234 MVT::v8f16, MVT::v4bf16, MVT::v8bf16})
2246 if (Subtarget->hasSVE2() ||
2247 (Subtarget->hasSME() && Subtarget->isStreaming())) {
2249 for (
auto VT : {MVT::v2i32, MVT::v4i16, MVT::v8i8, MVT::v16i8}) {
2253 for (
auto VT : {MVT::nxv2i1, MVT::nxv4i1, MVT::nxv8i1, MVT::nxv16i1}) {
2260 if (Subtarget->isSVEAvailable()) {
2261 for (
auto VT : {MVT::nxv16i8, MVT::nxv8i16, MVT::nxv4i32, MVT::nxv2i64,
2262 MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
2263 MVT::nxv4f32, MVT::nxv2f64, MVT::nxv2bf16, MVT::nxv4bf16,
2264 MVT::nxv8bf16, MVT::v4f16, MVT::v8f16, MVT::v4bf16,
2265 MVT::v8bf16, MVT::v2f32, MVT::v4f32, MVT::v1f64,
2266 MVT::v2f64, MVT::v8i8, MVT::v16i8, MVT::v4i16,
2267 MVT::v8i16, MVT::v2i32, MVT::v4i32, MVT::v1i64,
2273 for (
auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
2274 MVT::nxv4f32, MVT::nxv2f64, MVT::v4f16, MVT::v8f16,
2275 MVT::v2f32, MVT::v4f32, MVT::v2f64})
2278 for (
auto VT : {MVT::nxv2i8, MVT::nxv2i16, MVT::nxv2i32, MVT::nxv2i64,
2279 MVT::nxv2f32, MVT::nxv2f64, MVT::nxv4i8, MVT::nxv4i16,
2280 MVT::nxv4i32, MVT::nxv4f32}) {
2288 if (Subtarget->hasSVE2()) {
2306 if (Subtarget->hasMOPS() && Subtarget->hasMTE()) {
2313 if (Subtarget->hasSVE()) {
2327 if (Subtarget->isTargetWindows()) {
2347void AArch64TargetLowering::addTypeForNEON(
MVT VT) {
2357 if (VT == MVT::v2f32 || VT == MVT::v4f32 || VT == MVT::v2f64) {
2379 if (VT == MVT::v2f32 || VT == MVT::v4f32 || VT == MVT::v2f64 ||
2380 ((VT == MVT::v4bf16 || VT == MVT::v8bf16 || VT == MVT::v4f16 ||
2381 VT == MVT::v8f16) &&
2382 Subtarget->hasFullFP16()))
2407 if (VT != MVT::v8i8 && VT != MVT::v16i8)
2416 for (
unsigned Opcode :
2434 for (
unsigned Opcode :
2469 if (Subtarget->isLittleEndian()) {
2480 if (Subtarget->hasD128()) {
2498 if (!Subtarget->isSVEorStreamingSVEAvailable() ||
2514void AArch64TargetLowering::addTypeForFixedLengthSVE(
MVT VT) {
2539 while (InnerVT != VT) {
2553 while (InnerVT != VT) {
2562 bool PreferSVE = !PreferNEON && Subtarget->isSVEAvailable();
2583 if (Subtarget->hasMatMulInt8()) {
2700void AArch64TargetLowering::addDRType(
MVT VT) {
2702 if (Subtarget->isNeonAvailable())
2706void AArch64TargetLowering::addQRType(
MVT VT) {
2708 if (Subtarget->isNeonAvailable())
2725 Imm =
C->getZExtValue();
2733 case AArch64ISD::SQDMULH:
2745 return N->getOpcode() ==
Opc &&
2750 const APInt &Demanded,
2758 if (
Imm == 0 ||
Imm == Mask ||
2762 unsigned EltSize =
Size;
2779 ((InvertedImm << 1) | (InvertedImm >> (EltSize - 1) & 1)) &
2781 uint64_t Sum = RotatedImm + NonDemandedBits;
2782 bool Carry = NonDemandedBits & ~Sum & (1ULL << (EltSize - 1));
2783 uint64_t Ones = (Sum + Carry) & NonDemandedBits;
2784 NewImm = (
Imm | Ones) & Mask;
2812 while (EltSize <
Size) {
2813 NewImm |= NewImm << EltSize;
2819 "demanded bits should never be altered");
2820 assert(OldImm != NewImm &&
"the new imm shouldn't be equal to the old imm");
2823 EVT VT =
Op.getValueType();
2829 if (NewImm == 0 || NewImm == OrigMask) {
2854 EVT VT =
Op.getValueType();
2868 switch (
Op.getOpcode()) {
2872 NewOpc =
Size == 32 ? AArch64::ANDWri : AArch64::ANDXri;
2875 NewOpc =
Size == 32 ? AArch64::ORRWri : AArch64::ORRXri;
2878 NewOpc =
Size == 32 ? AArch64::EORWri : AArch64::EORXri;
2884 uint64_t
Imm =
C->getZExtValue();
2893 switch (
Op.getOpcode()) {
2896 case AArch64ISD::DUP: {
2899 if (
SrcOp.getValueSizeInBits() !=
Op.getScalarValueSizeInBits()) {
2900 assert(
SrcOp.getValueSizeInBits() >
Op.getScalarValueSizeInBits() &&
2901 "Expected DUP implicit truncation");
2906 case AArch64ISD::CSEL: {
2913 case AArch64ISD::CSNEG:
2914 case AArch64ISD::CSINC:
2915 case AArch64ISD::CSINV: {
2923 if (
Op.getOpcode() == AArch64ISD::CSINC)
2927 else if (
Op.getOpcode() == AArch64ISD::CSINV)
2929 else if (
Op.getOpcode() == AArch64ISD::CSNEG)
2932 Op.getScalarValueSizeInBits())));
2937 case AArch64ISD::BICi: {
2940 ~(
Op->getConstantOperandAPInt(1) <<
Op->getConstantOperandAPInt(2))
2941 .trunc(
Known.getBitWidth());
2946 case AArch64ISD::VLSHR: {
2953 case AArch64ISD::VASHR: {
2960 case AArch64ISD::VSHL: {
2967 case AArch64ISD::MOVI: {
2969 APInt(
Known.getBitWidth(),
Op->getConstantOperandVal(0)));
2972 case AArch64ISD::MOVIshift: {
2974 APInt(
Known.getBitWidth(),
Op->getConstantOperandVal(0)
2975 <<
Op->getConstantOperandVal(1)));
2978 case AArch64ISD::MOVImsl: {
2981 Known.getBitWidth(), ~(~
Op->getConstantOperandVal(0) << ShiftAmt)));
2984 case AArch64ISD::MOVIedit: {
2986 Known.getBitWidth(),
2990 case AArch64ISD::MVNIshift: {
2993 ~(
Op->getConstantOperandVal(0) <<
Op->getConstantOperandVal(1)),
2997 case AArch64ISD::MVNImsl: {
3000 APInt(
Known.getBitWidth(), (~
Op->getConstantOperandVal(0) << ShiftAmt),
3004 case AArch64ISD::LOADgot:
3005 case AArch64ISD::ADDlow: {
3006 if (!Subtarget->isTargetILP32())
3012 case AArch64ISD::ASSERT_ZEXT_BOOL: {
3022 case Intrinsic::aarch64_ldaxr:
3023 case Intrinsic::aarch64_ldxr: {
3033 case AArch64ISD::SHL_PRED:
3034 case AArch64ISD::SRL_PRED:
3035 case AArch64ISD::SRA_PRED: {
3045 if (
Op.getOpcode() == AArch64ISD::SHL_PRED)
3047 else if (
Op.getOpcode() == AArch64ISD::SRL_PRED)
3055 unsigned IntNo =
Op.getConstantOperandVal(0);
3059 case Intrinsic::aarch64_neon_uaddlv: {
3060 MVT VT =
Op.getOperand(1).getValueType().getSimpleVT();
3062 if (VT == MVT::v8i8 || VT == MVT::v16i8) {
3063 unsigned Bound = (VT == MVT::v8i8) ? 11 : 12;
3070 case Intrinsic::aarch64_neon_umaxv:
3071 case Intrinsic::aarch64_neon_uminv: {
3076 MVT VT =
Op.getOperand(1).getValueType().getSimpleVT();
3078 if (VT == MVT::v8i8 || VT == MVT::v16i8) {
3082 }
else if (VT == MVT::v4i16 || VT == MVT::v8i16) {
3096 unsigned Depth)
const {
3097 EVT VT =
Op.getValueType();
3099 unsigned Opcode =
Op.getOpcode();
3101 case AArch64ISD::FCMEQ:
3102 case AArch64ISD::FCMGE:
3103 case AArch64ISD::FCMGT:
3106 case AArch64ISD::VASHR: {
3109 return std::min<uint64_t>(Tmp +
Op.getConstantOperandVal(1), VTBits);
3123 switch (
MI->getOpcode()) {
3124 case AArch64::G_FCMEQ:
3125 case AArch64::G_FCMGE:
3126 case AArch64::G_FCMGT: {
3130 case AArch64::G_VASHR: {
3131 unsigned Tmp =
Analysis.computeNumSignBits(
MI->getOperand(1).getReg(),
3132 DemandedElts,
Depth + 1);
3134 return std::min<uint64_t>(Tmp +
MI->getOperand(2).getImm(),
3149 unsigned *
Fast)
const {
3161 bool UseNEONLd1 = Subtarget->requiresStrictAlign() &&
3166 if (ElementSizeBits % 8 == 0 && Alignment >=
Align(ElementSizeBits / 8))
3170 if (Subtarget->requiresStrictAlign())
3175 *
Fast = !Subtarget->isMisaligned128StoreSlow() || VT.
getStoreSize() != 16 ||
3194 unsigned *
Fast)
const {
3195 if (Subtarget->requiresStrictAlign())
3200 *
Fast = !Subtarget->isMisaligned128StoreSlow() ||
3201 Ty.getSizeInBytes() != 16 ||
3244 Register DestReg =
MI.getOperand(0).getReg();
3245 Register IfTrueReg =
MI.getOperand(1).getReg();
3246 Register IfFalseReg =
MI.getOperand(2).getReg();
3247 unsigned CondCode =
MI.getOperand(3).getImm();
3248 bool NZCVKilled =
MI.getOperand(4).isKill();
3262 MBB->addSuccessor(TrueBB);
3263 MBB->addSuccessor(EndBB);
3279 MI.eraseFromParent();
3287 "SEH does not use catchret!");
3301 .
add(
MI.getOperand(0))
3303 MI.eraseFromParent();
3307 Register NewFpmrVal =
MI.getOperand(0).getReg();
3311 MF->
insert(++
MBB->getIterator(), MsrBB);
3330 MBB->addSuccessor(MsrBB);
3333 MI.eraseFromParent();
3344 Register TargetReg =
MI.getOperand(0).getReg();
3346 TII.probedStackAlloc(
MBBI, TargetReg,
false);
3348 MI.eraseFromParent();
3349 return NextInst->getParent();
3402 MBB->addSuccessor(TrapBB);
3403 MBB->addSuccessor(PassBB);
3405 MI.eraseFromParent();
3417 MIB.
add(
MI.getOperand(1));
3418 MIB.
add(
MI.getOperand(2));
3419 MIB.
add(
MI.getOperand(3));
3420 MIB.
add(
MI.getOperand(4));
3421 MIB.
add(
MI.getOperand(5));
3423 MI.eraseFromParent();
3434 MIB.
add(
MI.getOperand(0));
3435 MIB.
add(
MI.getOperand(1));
3436 MIB.
add(
MI.getOperand(2));
3437 MIB.
add(
MI.getOperand(1));
3439 MI.eraseFromParent();
3446 bool Op0IsDef)
const {
3452 for (
unsigned I = 1;
I <
MI.getNumOperands(); ++
I)
3453 MIB.
add(
MI.getOperand(
I));
3455 MI.eraseFromParent();
3465 unsigned StartIdx = 0;
3467 bool HasTile = BaseReg != AArch64::ZA;
3468 bool HasZPROut = HasTile &&
MI.getOperand(0).isReg();
3470 MIB.
add(
MI.getOperand(StartIdx));
3474 MIB.
addReg(BaseReg +
MI.getOperand(StartIdx).getImm(),
3476 MIB.
addReg(BaseReg +
MI.getOperand(StartIdx).getImm());
3480 if (
MI.getOperand(0).isReg() && !
MI.getOperand(1).isImm()) {
3481 MIB.
add(
MI.getOperand(StartIdx));
3486 for (
unsigned I = StartIdx;
I <
MI.getNumOperands(); ++
I)
3487 MIB.
add(
MI.getOperand(
I));
3489 MI.eraseFromParent();
3498 MIB.
add(
MI.getOperand(0));
3500 unsigned Mask =
MI.getOperand(0).getImm();
3501 for (
unsigned I = 0;
I < 8;
I++) {
3502 if (Mask & (1 <<
I))
3506 MI.eraseFromParent();
3516 Register ResultReg =
MI.getOperand(0).getReg();
3519 }
else if (Subtarget->hasSME()) {
3521 .
addImm(AArch64SysReg::SVCR)
3524 RTLIB::Libcall LC = RTLIB::SMEABI_SME_STATE;
3533 MI.eraseFromParent();
3541 while (
Reg.isVirtual()) {
3543 assert(
DefMI &&
"Virtual register definition not found");
3544 unsigned Opcode =
DefMI->getOpcode();
3546 if (Opcode == AArch64::COPY) {
3547 Reg =
DefMI->getOperand(1).getReg();
3549 if (
Reg.isPhysical())
3553 if (Opcode == AArch64::SUBREG_TO_REG) {
3554 Reg =
DefMI->getOperand(1).getReg();
3571 int64_t IntDisc = IntDiscOp.
getImm();
3572 assert(IntDisc == 0 &&
"Blend components are already expanded");
3577 case AArch64::MOVKXi:
3586 case AArch64::MOVi32imm:
3587 case AArch64::MOVi64imm:
3591 AddrDisc = AArch64::NoRegister;
3600 if (AddrDisc == AArch64::XZR)
3601 AddrDisc = AArch64::NoRegister;
3604 if (AddrDisc && MRI.
getRegClass(AddrDisc) != AddrDiscRC) {
3610 if (AddrDiscOp.
getReg() != AddrDisc)
3613 AddrDiscOp.
setReg(AddrDisc);
3614 IntDiscOp.
setImm(IntDisc);
3621 if (SMEOrigInstr != -1) {
3623 uint64_t SMEMatrixType =
3625 switch (SMEMatrixType) {
3641 switch (
MI.getOpcode()) {
3647 case AArch64::EntryPStateSM:
3649 case AArch64::F128CSEL:
3651 case TargetOpcode::STATEPOINT:
3657 MI.addOperand(*
MI.getMF(),
3663 case TargetOpcode::STACKMAP:
3664 case TargetOpcode::PATCHPOINT:
3667 case TargetOpcode::PATCHABLE_EVENT_CALL:
3668 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
3671 case AArch64::CATCHRET:
3674 case AArch64::PROBED_STACKALLOC_DYN:
3677 case AArch64::CHECK_MATCHING_VL_PSEUDO:
3680 case AArch64::LD1_MXIPXX_H_PSEUDO_B:
3681 return EmitTileLoad(AArch64::LD1_MXIPXX_H_B, AArch64::ZAB0,
MI, BB);
3682 case AArch64::LD1_MXIPXX_H_PSEUDO_H:
3683 return EmitTileLoad(AArch64::LD1_MXIPXX_H_H, AArch64::ZAH0,
MI, BB);
3684 case AArch64::LD1_MXIPXX_H_PSEUDO_S:
3685 return EmitTileLoad(AArch64::LD1_MXIPXX_H_S, AArch64::ZAS0,
MI, BB);
3686 case AArch64::LD1_MXIPXX_H_PSEUDO_D:
3687 return EmitTileLoad(AArch64::LD1_MXIPXX_H_D, AArch64::ZAD0,
MI, BB);
3688 case AArch64::LD1_MXIPXX_H_PSEUDO_Q:
3689 return EmitTileLoad(AArch64::LD1_MXIPXX_H_Q, AArch64::ZAQ0,
MI, BB);
3690 case AArch64::LD1_MXIPXX_V_PSEUDO_B:
3691 return EmitTileLoad(AArch64::LD1_MXIPXX_V_B, AArch64::ZAB0,
MI, BB);
3692 case AArch64::LD1_MXIPXX_V_PSEUDO_H:
3693 return EmitTileLoad(AArch64::LD1_MXIPXX_V_H, AArch64::ZAH0,
MI, BB);
3694 case AArch64::LD1_MXIPXX_V_PSEUDO_S:
3695 return EmitTileLoad(AArch64::LD1_MXIPXX_V_S, AArch64::ZAS0,
MI, BB);
3696 case AArch64::LD1_MXIPXX_V_PSEUDO_D:
3697 return EmitTileLoad(AArch64::LD1_MXIPXX_V_D, AArch64::ZAD0,
MI, BB);
3698 case AArch64::LD1_MXIPXX_V_PSEUDO_Q:
3699 return EmitTileLoad(AArch64::LD1_MXIPXX_V_Q, AArch64::ZAQ0,
MI, BB);
3700 case AArch64::LDR_ZA_PSEUDO:
3702 case AArch64::LDR_TX_PSEUDO:
3704 case AArch64::STR_TX_PSEUDO:
3706 case AArch64::ZERO_M_PSEUDO:
3708 case AArch64::ZERO_T_PSEUDO:
3710 case AArch64::MOVT_TIZ_PSEUDO:
3712 case AArch64::MSR_FPMR:
3717 &AArch64::GPR64noipRegClass);
3747 N =
N->getOperand(0).getNode();
3752 if (
N->getOpcode() != AArch64ISD::DUP)
3755 auto Opnd0 =
N->getOperand(0);
3761 (V.getOpcode() == AArch64ISD::DUP &&
isOneConstant(V.getOperand(0)));
3922 CondCode, CondCode2);
3942 if (
Op->getFlags().hasNoSignedWrap())
3968 (isIntEqualitySetCC(CC) ||
3976 EVT VT =
LHS.getValueType();
3981 if ((VT == MVT::f16 && !FullFP16) || VT == MVT::bf16) {
3986 Chain =
RHS.getValue(1);
3989 IsSignaling ? AArch64ISD::STRICT_FCMPE : AArch64ISD::STRICT_FCMP;
3995 EVT VT =
LHS.getValueType();
4000 if ((VT == MVT::f16 && !FullFP16) || VT == MVT::bf16) {
4011 unsigned Opcode = AArch64ISD::SUBS;
4015 Opcode = AArch64ISD::ADDS;
4018 isIntEqualitySetCC(CC)) {
4021 Opcode = AArch64ISD::ADDS;
4030 LHS.getOperand(0),
LHS.getOperand(1));
4034 }
else if (
LHS.getOpcode() == AArch64ISD::ANDS) {
4036 return LHS.getValue(1);
4102 unsigned Opcode = 0;
4105 if (
LHS.getValueType().isFloatingPoint()) {
4106 assert(
LHS.getValueType() != MVT::f128);
4107 if ((
LHS.getValueType() == MVT::f16 && !FullFP16) ||
4108 LHS.getValueType() == MVT::bf16) {
4112 Opcode = AArch64ISD::FCCMP;
4114 APInt Imm = Const->getAPIntValue();
4115 if (
Imm.isNegative() &&
Imm.sgt(-32)) {
4116 Opcode = AArch64ISD::CCMN;
4120 Opcode = AArch64ISD::CCMN;
4123 isIntEqualitySetCC(CC)) {
4126 Opcode = AArch64ISD::CCMN;
4130 Opcode = AArch64ISD::CCMP;
4156 bool &CanNegate,
bool &MustBeFirst,
4157 bool &PreferFirst,
bool WillNegate,
4158 unsigned Depth = 0) {
4164 if (VT == MVT::f128)
4167 MustBeFirst =
false;
4171 {Val->getOperand(0), Val->getOperand(1)});
4178 bool IsOR = Opcode ==
ISD::OR;
4194 if (MustBeFirstL && MustBeFirstR)
4200 if (!CanNegateL && !CanNegateR)
4204 CanNegate = WillNegate && CanNegateL && CanNegateR;
4207 MustBeFirst = !CanNegate;
4212 MustBeFirst = MustBeFirstL || MustBeFirstR;
4214 PreferFirst = PreferFirstL || PreferFirstR;
4237 bool isInteger =
LHS.getValueType().isInteger();
4239 CC = getSetCCInverse(CC,
LHS.getValueType());
4245 assert(
LHS.getValueType().isFloatingPoint());
4271 bool IsOR = Opcode ==
ISD::OR;
4278 PreferFirstL, IsOR);
4279 assert(ValidL &&
"Valid conjunction/disjunction tree");
4287 PreferFirstR, IsOR);
4288 assert(ValidR &&
"Valid conjunction/disjunction tree");
4291 bool ShouldFirstL = PreferFirstL && !PreferFirstR && !MustBeFirstR;
4294 if (MustBeFirstL || ShouldFirstL) {
4295 assert(!MustBeFirstR &&
"Valid conjunction/disjunction tree");
4304 bool NegateAfterAll;
4308 assert(CanNegateR &&
"at least one side must be negatable");
4309 assert(!MustBeFirstR &&
"invalid conjunction/disjunction tree");
4313 NegateAfterR =
true;
4316 NegateR = CanNegateR;
4317 NegateAfterR = !CanNegateR;
4320 NegateAfterAll = !Negate;
4322 assert(Opcode ==
ISD::AND &&
"Valid conjunction/disjunction tree");
4323 assert(!Negate &&
"Valid conjunction/disjunction tree");
4327 NegateAfterR =
false;
4328 NegateAfterAll =
false;
4348 bool DummyCanNegate;
4349 bool DummyMustBeFirst;
4350 bool DummyPreferFirst;
4352 DummyPreferFirst,
false))
4366 uint64_t Mask = MaskCst->getZExtValue();
4367 return (Mask == 0xFF || Mask == 0xFFFF || Mask == 0xFFFFFFFF);
4375 if (!
Op.hasOneUse())
4381 unsigned Opc =
Op.getOpcode();
4384 uint64_t Shift = ShiftCst->getZExtValue();
4386 return (Shift <= 4) ? 2 : 1;
4387 EVT VT =
Op.getValueType();
4388 if ((VT == MVT::i32 && Shift <= 31) || (VT == MVT::i64 && Shift <= 63))
4408 if (
LHS.getOpcode() !=
ISD::AND &&
LHS.getOpcode() != AArch64ISD::ANDS)
4428 EVT VT =
RHS.getValueType();
4429 APInt C = RHSC->getAPIntValue();
4444 if (!
C.isMinSignedValue()) {
4456 assert(!
C.isZero() &&
"C should not be zero here");
4467 if (!
C.isMaxSignedValue()) {
4478 if (!
C.isAllOnes()) {
4538 LHS->hasNUsesOfValue(1, 0)) {
4539 int16_t ValueofRHS =
RHS->getAsZExtVal();
4567static std::pair<SDValue, SDValue>
4569 assert((
Op.getValueType() == MVT::i32 ||
Op.getValueType() == MVT::i64) &&
4570 "Unsupported value type");
4576 switch (
Op.getOpcode()) {
4580 Opc = AArch64ISD::ADDS;
4584 Opc = AArch64ISD::ADDS;
4588 Opc = AArch64ISD::SUBS;
4592 Opc = AArch64ISD::SUBS;
4600 if (
Op.getValueType() == MVT::i32) {
4623 assert(
Op.getValueType() == MVT::i64 &&
"Expected an i64 value type");
4633 Overflow = DAG.
getNode(AArch64ISD::SUBS,
DL, VTs, UpperBits, LowerBits)
4652 Overflow =
Value.getValue(1);
4654 return std::make_pair(
Value, Overflow);
4659 !Subtarget->isNeonAvailable()))
4660 return LowerToScalableOp(
Op, DAG);
4684 return DAG.
getNode(AArch64ISD::CSEL,
DL,
Op.getValueType(), TVal, FVal,
4707 if (
LHS.getValueType() != MVT::i32 &&
LHS.getValueType() != MVT::i64)
4714 if (!CFVal || !CTVal)
4751 return Cmp.getValue(1);
4764 return DAG.
getNode(AArch64ISD::CSEL,
DL, VT, One, Zero, CC, Glue);
4774 return DAG.
getNode(AArch64ISD::CSEL,
DL, VT, One, Zero, CC, Glue);
4780 unsigned Opcode,
bool IsSigned) {
4781 EVT VT0 =
Op.getValue(0).getValueType();
4782 EVT VT1 =
Op.getValue(1).getValueType();
4784 if (VT0 != MVT::i32 && VT0 != MVT::i64)
4787 bool InvertCarry = Opcode == AArch64ISD::SBCS;
4806 bool LastOperandIsImm =
false) {
4807 if (
Op.getValueType().isVector())
4812 const unsigned NumOperands =
Op.getNumOperands();
4813 auto getFloatVT = [](
EVT VT) {
4814 assert((VT == MVT::i32 || VT == MVT::i64) &&
"Unexpected VT");
4815 return VT == MVT::i32 ? MVT::f32 : MVT::f64;
4817 auto bitcastToFloat = [&](
SDValue Val) {
4818 return DAG.
getBitcast(getFloatVT(Val.getValueType()), Val);
4822 for (
unsigned I = 1;
I < NumOperands; ++
I) {
4824 const bool KeepInt = LastOperandIsImm && (
I == NumOperands - 1);
4825 NewOps.
push_back(KeepInt ? Val : bitcastToFloat(Val));
4827 EVT OrigVT =
Op.getValueType();
4852 DAG.
getNode(AArch64ISD::CSEL,
DL, MVT::i32, FVal, TVal, CCVal, Overflow);
4864 unsigned IsWrite =
Op.getConstantOperandVal(2);
4865 unsigned Locality =
Op.getConstantOperandVal(3);
4866 unsigned IsData =
Op.getConstantOperandVal(4);
4868 bool IsStream = !Locality;
4872 assert(Locality <= 3 &&
"Prefetch locality out-of-range");
4876 Locality = 3 - Locality;
4880 unsigned PrfOp = (IsWrite << 4) |
4884 return DAG.
getNode(AArch64ISD::PREFETCH,
DL, MVT::Other,
Op.getOperand(0),
4897 if (LHSConstOp && RHSConst) {
4901 uint64_t NewMaskValue = LHSConstValue & ~(RHSConstant - 1);
4914 EVT VT =
Op.getValueType();
4918 if (VT == MVT::nxv2f64 && SrcVal.
getValueType() == MVT::nxv2bf16) {
4926 return LowerToPredicatedOp(
Op, DAG, AArch64ISD::FP_EXTEND_MERGE_PASSTHRU);
4930 return LowerFixedLengthFPExtendToSVE(
Op, DAG);
4932 bool IsStrict =
Op->isStrictFPOpcode();
4933 SDValue Op0 =
Op.getOperand(IsStrict ? 1 : 0);
4935 if (VT == MVT::f64) {
4937 if (Op0VT == MVT::f32 || Op0VT == MVT::f16)
4940 if (Op0VT == MVT::bf16 && IsStrict) {
4943 {Op0,
Op.getOperand(0)});
4947 if (Op0VT == MVT::bf16)
4953 assert(
Op.getValueType() == MVT::f128 &&
"Unexpected lowering");
4959 EVT VT =
Op.getValueType();
4960 bool IsStrict =
Op->isStrictFPOpcode();
4961 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
4963 bool Trunc =
Op.getConstantOperandVal(IsStrict ? 2 : 1) == 1;
4964 SDNodeFlags
Flags =
Op->getFlags();
4968 if (SrcVT == MVT::nxv8f32)
4972 return LowerToPredicatedOp(
Op, DAG, AArch64ISD::FP_ROUND_MERGE_PASSTHRU);
4975 constexpr EVT
I32 = MVT::nxv4i32;
4981 if (SrcVT == MVT::nxv2f32 || SrcVT == MVT::nxv4f32) {
4982 if (Subtarget->hasBF16())
4983 return LowerToPredicatedOp(
Op, DAG,
4984 AArch64ISD::FP_ROUND_MERGE_PASSTHRU);
4986 Narrow = getSVESafeBitCast(I32, SrcVal, DAG);
4991 }
else if (SrcVT == MVT::nxv2f64 &&
4992 (Subtarget->hasSVE2() || Subtarget->isStreamingSVEAvailable())) {
4995 Narrow = DAG.
getNode(AArch64ISD::FCVTX_MERGE_PASSTHRU,
DL, MVT::nxv2f32,
4996 Pg, SrcVal, DAG.
getPOISON(MVT::nxv2f32));
5002 NewOps.
push_back(
Op.getOperand(IsStrict ? 2 : 1));
5003 return DAG.
getNode(
Op.getOpcode(),
DL, VT, NewOps,
Op->getFlags());
5020 IsNaN = DAG.
getNode(AArch64ISD::REINTERPRET_CAST,
DL, I1, IsNaN);
5021 Narrow = DAG.
getSelect(
DL, I32, IsNaN, NaN, Narrow);
5026 return getSVESafeBitCast(VT, Narrow, DAG);
5030 return LowerFixedLengthFPRoundToSVE(
Op, DAG);
5035 !((Subtarget->hasNEON() || Subtarget->hasSME()) &&
5036 Subtarget->hasBF16())) {
5051 Narrow = DAG.
getNode(AArch64ISD::FCVTXN,
DL,
F32, Narrow);
5072 Narrow = DAG.
getSelect(
DL, I32, IsNaN, NaN, Narrow);
5089 if (SrcVT != MVT::f128) {
5106 bool IsStrict =
Op->isStrictFPOpcode();
5107 EVT InVT =
Op.getOperand(IsStrict ? 1 : 0).getValueType();
5108 EVT VT =
Op.getValueType();
5111 "Unimplemented SVE support for STRICT_FP_to_INT!");
5120 {
Op.getOperand(0),
Op.getOperand(1)});
5121 return DAG.
getNode(
Op.getOpcode(),
DL, {VT, MVT::Other},
5122 {Ext.getValue(1), Ext.getValue(0)});
5125 Op.getOpcode(),
DL,
Op.getValueType(),
5129 if (
SDValue Res = LowerFPToIntToSVE(
Op, DAG))
5134 if (VTSize < InVTSize) {
5139 {Op.getOperand(0), Op.getOperand(1)});
5149 if (VTSize > InVTSize) {
5156 {
Op.getOperand(0),
Op.getOperand(1)});
5157 return DAG.
getNode(
Op.getOpcode(),
DL, {VT, MVT::Other},
5158 {Ext.getValue(1), Ext.getValue(0)});
5173 return DAG.
getNode(
Op.getOpcode(),
DL, {ScalarVT, MVT::Other},
5174 {Op.getOperand(0), Extract});
5175 return DAG.
getNode(
Op.getOpcode(),
DL, ScalarVT, Extract);
5184 bool IsStrict =
Op->isStrictFPOpcode();
5185 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
5188 return LowerVectorFP_TO_INT(
Op, DAG);
5191 if ((SrcVal.
getValueType() == MVT::f16 && !Subtarget->hasFullFP16()) ||
5197 {
Op.getOperand(0), SrcVal});
5198 return DAG.
getNode(
Op.getOpcode(),
DL, {Op.getValueType(), MVT::Other},
5199 {Ext.getValue(1), Ext.getValue(0)});
5214AArch64TargetLowering::LowerVectorFP_TO_INT_SAT(
SDValue Op,
5220 const EVT DstVT =
Op.getValueType();
5227 assert(SatWidth <= DstElementWidth &&
5228 "Saturation width cannot exceed result width");
5231 if (SrcElementVT != MVT::f64 && SrcElementVT != MVT::f32 &&
5232 SrcElementVT != MVT::f16 && SrcElementVT != MVT::bf16)
5235 if (
SDValue Res = LowerFPToIntToSVE(
Op, DAG))
5239 auto CanHandleNatively = [&DstVT, &SatWidth](EVT SrcVT) ->
bool {
5245 auto Expand = [&SatWidth, &CanHandleNatively](EVT SrcVT) ->
bool {
5246 return !CanHandleNatively(SrcVT) &&
5250 (SrcVT == MVT::v1f64 || SrcVT == MVT::v2f64));
5255 std::optional<EVT> PromVT;
5259 if (DstElementVT == MVT::i32 || SrcElementVT == MVT::bf16 ||
5260 !Subtarget->hasFullFP16()) {
5267 if (DstElementVT == MVT::i64) {
5277 unsigned Opc =
Op.getOpcode();
5278 if (PromVT && !
Expand(*PromVT)) {
5281 if (*PromVT != MVT::v8f32 ||
isTypeLegal(MVT::v8f32))
5282 return DAG.
getNode(
Op.getOpcode(),
DL, DstVT, SrcVal,
Op.getOperand(1));
5296 if (CanHandleNatively(SrcVT)) {
5300 }
else if (
Expand(SrcVT)) {
5304 assert((SrcElementWidth > DstElementWidth) ||
5305 (SrcElementWidth == DstElementWidth && SatWidth < DstElementWidth));
5335 return LowerVectorFP_TO_INT_SAT(
Op, DAG);
5337 EVT DstVT =
Op.getValueType();
5341 assert(SatWidth <= DstWidth &&
"Saturation width cannot exceed result width");
5344 if ((SrcVT == MVT::f16 && !Subtarget->hasFullFP16()) || SrcVT == MVT::bf16) {
5347 }
else if (SrcVT != MVT::f64 && SrcVT != MVT::f32 && SrcVT != MVT::f16 &&
5353 if ((SrcVT == MVT::f64 || SrcVT == MVT::f32 ||
5354 (SrcVT == MVT::f16 && Subtarget->hasFullFP16())) &&
5355 DstVT == SatVT && (DstVT == MVT::i64 || DstVT == MVT::i32))
5356 return DAG.
getNode(
Op.getOpcode(),
DL, DstVT, SrcVal,
5362 if (DstWidth < SatWidth)
5365 if (SrcVT == MVT::f16 && SatVT == MVT::i16 && DstVT == MVT::i32) {
5368 DAG.
getNode(AArch64ISD::FCVTZS_HALF,
DL, MVT::f32, SrcVal);
5373 SDValue CVTf32 = DAG.
getNode(AArch64ISD::FCVTZU_HALF,
DL, MVT::f32, SrcVal);
5398 EVT VT =
Op.getValueType();
5405 *DAG.
getContext(), Src.getValueType().getVectorElementType());
5421 bool IsStrict =
Op->isStrictFPOpcode();
5422 EVT VT =
Op.getValueType();
5425 EVT InVT =
In.getValueType();
5426 unsigned Opc =
Op.getOpcode();
5430 "Unimplemented SVE support for ISD:::STRICT_INT_TO_FP!");
5445 {Op.getOperand(0), In});
5447 {
Op.getValueType(), MVT::Other},
5458 if (VT == MVT::nxv8f32)
5461 unsigned Opcode = IsSigned ? AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU
5462 : AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU;
5463 return LowerToPredicatedOp(
Op, DAG, Opcode);
5468 return LowerFixedLengthIntToFPToSVE(
Op, DAG);
5472 if (VTSize < InVTSize) {
5478 bool IsTargetf16 =
false;
5479 if (
Op.hasOneUse() &&
5484 SDNode *
U = *
Op->user_begin();
5485 if (
U->hasOneUse() &&
U->user_begin()->getOpcode() ==
ISD::FP_ROUND) {
5486 EVT TmpVT =
U->user_begin()->getValueType(0);
5492 if (IsTargetf32 && !IsTargetf16) {
5502 {
In.getValue(1),
In.getValue(0),
5510 if (VTSize > InVTSize) {
5527 return DAG.
getNode(
Op.getOpcode(),
DL, {ScalarVT, MVT::Other},
5528 {Op.getOperand(0), Extract});
5529 return DAG.
getNode(
Op.getOpcode(),
DL, ScalarVT, Extract);
5537 if (
Op.getValueType().isVector())
5538 return LowerVectorINT_TO_FP(
Op, DAG);
5540 bool IsStrict =
Op->isStrictFPOpcode();
5541 SDValue SrcVal =
Op.getOperand(IsStrict ? 1 : 0);
5546 auto IntToFpViaPromotion = [&](EVT PromoteVT) {
5550 {Op.getOperand(0), SrcVal});
5552 {
Op.getValueType(), MVT::Other},
5557 DAG.
getNode(
Op.getOpcode(),
DL, PromoteVT, SrcVal),
5561 if (
Op.getValueType() == MVT::bf16) {
5562 unsigned MaxWidth = IsSigned
5566 if (MaxWidth <= 24) {
5567 return IntToFpViaPromotion(MVT::f32);
5571 if (MaxWidth <= 53) {
5572 return IntToFpViaPromotion(MVT::f64);
5623 IsStrict ? DAG.
getNode(
Op.getOpcode(),
DL, {MVT::f64, MVT::Other},
5624 {Op.getOperand(0), ToRound})
5625 : DAG.
getNode(
Op.getOpcode(),
DL, MVT::f64, ToRound);
5652 {
Op.getValueType(), MVT::Other},
5656 DAG.getIntPtrConstant(0,
DL,
true));
5661 if (
Op.getValueType() == MVT::f16 && !Subtarget->hasFullFP16()) {
5662 return IntToFpViaPromotion(MVT::f32);
5671 if (
Op.getValueType() != MVT::f128)
5679AArch64TargetLowering::LowerLOOP_DEPENDENCE_MASK(
SDValue Op,
5681 assert((Subtarget->hasSVE2() ||
5682 (Subtarget->hasSME() && Subtarget->isStreaming())) &&
5683 "Lowering loop_dependence_raw_mask or loop_dependence_war_mask "
5684 "requires SVE or SME");
5687 EVT VT =
Op.getValueType();
5688 unsigned LaneOffset =
Op.getConstantOperandVal(3);
5690 uint64_t EltSizeInBytes =
Op.getConstantOperandVal(2);
5691 EVT AddrTy =
Op->getOperand(0).getValueType();
5694 if (LaneOffset != 0 || !
is_contained({1u, 2u, 4u, 8u}, EltSizeInBytes))
5703 if (AddrTy == MVT::i64)
5707 assert(AddrTy == MVT::i32 &&
"Only expected i32 to be legal!");
5709 Op.getOpcode(),
DL, VT,
5734 EVT OpVT =
Op.getValueType();
5735 EVT ArgVT =
Op.getOperand(0).getValueType();
5738 return LowerFixedLengthBitcastToSVE(
Op, DAG);
5746 "Expected int->fp bitcast!");
5759 return getSVESafeBitCast(OpVT, ExtResult, DAG);
5770 return getSVESafeBitCast(OpVT,
Op.getOperand(0), DAG);
5773 if (OpVT != MVT::f16 && OpVT != MVT::bf16)
5777 if (ArgVT == MVT::f16 || ArgVT == MVT::bf16)
5787 assert(ArgVT == MVT::i16);
5792 Src.getOperand(0).getValueType().changeElementType(
5808static std::optional<uint64_t>
5812 return std::nullopt;
5817 return std::nullopt;
5819 return C->getZExtValue();
5824 EVT VT =
N.getValueType();
5829 for (
const SDValue &Elt :
N->op_values()) {
5832 unsigned HalfSize = EltSize / 2;
5834 if (!
isIntN(HalfSize,
C->getSExtValue()))
5837 if (!
isUIntN(HalfSize,
C->getZExtValue()))
5849 EVT VT =
N.getValueType();
5871 unsigned Opcode =
N.getOpcode();
5882 unsigned Opcode =
N.getOpcode();
6024 if (IsN0SExt && IsN1SExt)
6025 return AArch64ISD::SMULL;
6030 if (IsN0ZExt && IsN1ZExt)
6031 return AArch64ISD::UMULL;
6037 if (IsN0ZExt || IsN1ZExt) {
6039 return AArch64ISD::UMULL;
6044 return AArch64ISD::UMULL;
6047 if (IsN0SExt || IsN1SExt) {
6049 return AArch64ISD::SMULL;
6052 return AArch64ISD::SMULL;
6055 if (!IsN1SExt && !IsN1ZExt)
6062 return AArch64ISD::SMULL;
6066 return AArch64ISD::UMULL;
6071 return AArch64ISD::UMULL;
6092 const SDNode *Operand =
N->getOperand(1).getNode();
6101 SplatValue = SplatValue.
abs();
6110 if ((SplatValue - 1).isPowerOf2())
6112 else if ((SplatValue + 1).isPowerOf2())
6121 EVT VT =
N->getValueType(0);
6124 unsigned ShiftAmt = MathOp ==
ISD::ADD ? (SplatValue - 1).logBase2()
6125 : (SplatValue + 1).logBase2();
6143 EVT VT =
Op.getValueType();
6145 bool OverrideNEON = !Subtarget->isNeonAvailable();
6147 return LowerToPredicatedOp(
Op, DAG, AArch64ISD::MUL_PRED);
6152 "unexpected type for custom-lowering ISD::MUL");
6168 if (VT == MVT::v1i64) {
6169 if (Subtarget->hasSVE())
6170 return LowerToPredicatedOp(
Op, DAG, AArch64ISD::MUL_PRED);
6186 if (Subtarget->hasSVE())
6187 return LowerToPredicatedOp(
Op, DAG, AArch64ISD::MUL_PRED);
6205 "unexpected types for extended operands to VMULL");
6207 DAG.
getNode(NewOpc,
DL, VT, Op0, Op1), 0);
6227 if (
Pattern == AArch64SVEPredPattern::all)
6236 if (PatNumElts == (NumElts * VScale))
6240 return DAG.
getNode(AArch64ISD::PTRUE,
DL, VT,
6251 IID = Intrinsic::aarch64_sve_ptrue_c8;
6254 IID = Intrinsic::aarch64_sve_ptrue_c16;
6257 IID = Intrinsic::aarch64_sve_ptrue_c32;
6260 IID = Intrinsic::aarch64_sve_ptrue_c64;
6269 bool IsSigned,
bool IsEqual) {
6273 if (!
N->getValueType(0).isScalableVector() ||
6278 APInt Y =
N->getConstantOperandAPInt(Op1);
6283 if (IsSigned ?
Y.isMaxSignedValue() :
Y.isMaxValue())
6289 APInt X =
N->getConstantOperandAPInt(Op0);
6292 APInt NumActiveElems =
6293 IsSigned ?
Y.ssub_ov(
X, Overflow) :
Y.usub_ov(
X, Overflow);
6300 NumActiveElems = IsSigned ? NumActiveElems.
sadd_ov(One, Overflow)
6301 : NumActiveElems.
uadd_ov(One, Overflow);
6306 std::optional<unsigned> PredPattern =
6308 unsigned MinSVEVectorSize = std::max(
6310 unsigned ElementSize = 128 /
N->getValueType(0).getVectorMinNumElements();
6311 if (PredPattern != std::nullopt &&
6312 NumActiveElems.
getZExtValue() <= (MinSVEVectorSize / ElementSize))
6313 return getPTrue(DAG,
DL,
N->getValueType(0), *PredPattern);
6322 EVT VT =
N->getValueType(0);
6330 unsigned BrkID = Intrinsic::aarch64_sve_brkb_z;
6333 BrkID = Intrinsic::aarch64_sve_brka_z;
6340 Upper.getOperand(0).getValueType() != VT)
6349 DAG.
getNode(AArch64ISD::REINTERPRET_CAST,
DL, MVT::nxv16i1, Mask);
6353 return DAG.
getNode(AArch64ISD::REINTERPRET_CAST,
DL, VT, Brk);
6360 EVT InVT =
Op.getValueType();
6364 "Expected a predicate-to-predicate bitcast");
6368 "Only expect to cast between legal scalable predicate types!");
6378 Op.getConstantOperandVal(0) == Intrinsic::aarch64_sve_convert_to_svbool &&
6379 Op.getOperand(1).getValueType().bitsGT(VT))
6380 Op =
Op.getOperand(1);
6398 Mask = DAG.
getNode(AArch64ISD::REINTERPRET_CAST,
DL, VT, Mask);
6405 RTLIB::Libcall LC = RTLIB::SMEABI_SME_STATE;
6411 TargetLowering::CallLoweringInfo CLI(DAG);
6413 CLI.setDebugLoc(
DL).setChain(Chain).setLibCallee(
6416 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
6462 SDValue TileSlice =
N->getOperand(2);
6465 int32_t ConstAddend = 0;
6474 ConstAddend = ImmNode->getSExtValue();
6478 int32_t ImmAddend = ConstAddend % 16;
6479 if (int32_t
C = (ConstAddend - ImmAddend)) {
6481 VarAddend = VarAddend
6488 auto SVL = DAG.
getNode(AArch64ISD::RDSVL,
DL, MVT::i64,
6500 return DAG.
getNode(IsLoad ? AArch64ISD::SME_ZA_LDR : AArch64ISD::SME_ZA_STR,
6502 {
N.getOperand(0), TileSlice,
Base,
6508 auto Op1 =
Op.getOperand(0);
6509 auto Op2 =
Op.getOperand(1);
6510 auto Mask =
Op.getOperand(2);
6513 EVT Op2VT = Op2.getValueType();
6514 EVT ResVT =
Op.getValueType();
6518 "Expected 8-bit or 16-bit characters.");
6535 Op2 = DAG.
getNode(AArch64ISD::DUPLANE128,
DL, OpContainerVT, Op2,
6563 ID, Mask, Op1, Op2);
6574 unsigned IntNo =
Op.getConstantOperandVal(1);
6579 case Intrinsic::aarch64_prefetch: {
6583 unsigned IsWrite =
Op.getConstantOperandVal(3);
6584 unsigned Locality =
Op.getConstantOperandVal(4);
6585 unsigned IsStream =
Op.getConstantOperandVal(5);
6586 unsigned IsData =
Op.getConstantOperandVal(6);
6587 unsigned PrfOp = (IsWrite << 4) |
6592 return DAG.
getNode(AArch64ISD::PREFETCH,
DL, MVT::Other, Chain,
6595 case Intrinsic::aarch64_range_prefetch: {
6599 unsigned IsWrite =
Op.getConstantOperandVal(3);
6600 unsigned IsStream =
Op.getConstantOperandVal(4);
6601 unsigned PrfOp = (IsStream << 2) | IsWrite;
6604 return DAG.
getNode(AArch64ISD::RANGE_PREFETCH,
DL, MVT::Other, Chain,
6608 case Intrinsic::aarch64_prefetch_ir:
6609 return DAG.
getNode(AArch64ISD::PREFETCH,
DL, MVT::Other,
6613 case Intrinsic::aarch64_sme_str:
6614 case Intrinsic::aarch64_sme_ldr: {
6617 case Intrinsic::aarch64_sme_za_enable:
6619 AArch64ISD::SMSTART,
DL, DAG.
getVTList(MVT::Other, MVT::Glue),
6622 case Intrinsic::aarch64_sme_za_disable:
6624 AArch64ISD::SMSTOP,
DL, DAG.
getVTList(MVT::Other, MVT::Glue),
6632 unsigned IntNo =
Op.getConstantOperandVal(1);
6637 case Intrinsic::aarch64_svc:
6638 case Intrinsic::aarch64_hvc: {
6645 unsigned Imm =
Op.getConstantOperandVal(2);
6652 for (
unsigned I = 0;
I < std::size(
ArgGPRs); ++
I) {
6662 Ops.push_back(Chain);
6666 Ops.push_back(Glue);
6669 IntNo == Intrinsic::aarch64_svc ? AArch64ISD::SVC : AArch64ISD::HVC;
6672 Chain =
Node.getValue(0);
6673 Glue =
Node.getValue(1);
6678 case Intrinsic::aarch64_mops_memset_tag: {
6686 bool IsVol =
Node->isVolatile();
6687 auto DstPtrInfo =
Node->getPointerInfo();
6691 SDValue MS = SDI.EmitMOPS(AArch64::MOPSMemorySetTaggingPseudo, DAG,
DL,
6692 Chain, Dst, Val,
Size, Alignment, Alignment,
6693 IsVol, DstPtrInfo, MachinePointerInfo{});
6706 unsigned IntNo =
Op.getConstantOperandVal(0);
6710 case Intrinsic::thread_pointer: {
6712 return DAG.
getNode(AArch64ISD::THREAD_POINTER,
DL, PtrVT);
6714 case Intrinsic::aarch64_sve_whilewr_b:
6716 Op.getOperand(1),
Op.getOperand(2),
6719 case Intrinsic::aarch64_sve_whilewr_h:
6721 Op.getOperand(1),
Op.getOperand(2),
6724 case Intrinsic::aarch64_sve_whilewr_s:
6726 Op.getOperand(1),
Op.getOperand(2),
6729 case Intrinsic::aarch64_sve_whilewr_d:
6731 Op.getOperand(1),
Op.getOperand(2),
6734 case Intrinsic::aarch64_sve_whilerw_b:
6736 Op.getOperand(1),
Op.getOperand(2),
6739 case Intrinsic::aarch64_sve_whilerw_h:
6741 Op.getOperand(1),
Op.getOperand(2),
6744 case Intrinsic::aarch64_sve_whilerw_s:
6746 Op.getOperand(1),
Op.getOperand(2),
6749 case Intrinsic::aarch64_sve_whilerw_d:
6751 Op.getOperand(1),
Op.getOperand(2),
6754 case Intrinsic::aarch64_neon_abs: {
6755 EVT Ty =
Op.getValueType();
6756 if (Ty == MVT::i64) {
6768 case Intrinsic::aarch64_neon_addhn: {
6769 return DAG.
getNode(AArch64ISD::ADDHN,
DL,
Op.getValueType(),
6770 Op.getOperand(1),
Op.getOperand(2));
6772 case Intrinsic::aarch64_neon_pmull64: {
6776 std::optional<uint64_t> LHSLane =
6778 std::optional<uint64_t> RHSLane =
6781 assert((!LHSLane || *LHSLane < 2) &&
"Expect lane to be None or 0 or 1");
6782 assert((!RHSLane || *RHSLane < 2) &&
"Expect lane to be None or 0 or 1");
6788 auto TryVectorizeOperand = [](
SDValue N, std::optional<uint64_t> NLane,
6789 std::optional<uint64_t> OtherLane,
6791 SelectionDAG &DAG) ->
SDValue {
6799 if (OtherLane == 1) {
6809 DAG.
getNode(AArch64ISD::DUPLANE64,
DL, MVT::v2i64,
6814 return DAG.
getNode(AArch64ISD::DUP,
DL, MVT::v1i64,
N);
6819 assert(
N.getValueType() == MVT::i64 &&
6820 "Intrinsic aarch64_neon_pmull64 requires i64 parameters");
6824 LHS = TryVectorizeOperand(
LHS, LHSLane, RHSLane,
DL, DAG);
6825 RHS = TryVectorizeOperand(
RHS, RHSLane, LHSLane,
DL, DAG);
6829 case Intrinsic::aarch64_neon_smax:
6832 case Intrinsic::aarch64_neon_umax:
6835 case Intrinsic::aarch64_neon_smin:
6838 case Intrinsic::aarch64_neon_umin:
6841 case Intrinsic::aarch64_neon_scalar_sqxtn:
6842 case Intrinsic::aarch64_neon_scalar_sqxtun:
6843 case Intrinsic::aarch64_neon_scalar_uqxtn: {
6844 assert(
Op.getValueType() == MVT::i32 ||
Op.getValueType() == MVT::f32);
6845 if (
Op.getValueType() == MVT::i32)
6850 Op.getOperand(1))));
6853 case Intrinsic::aarch64_neon_sqxtn:
6856 case Intrinsic::aarch64_neon_sqxtun:
6859 case Intrinsic::aarch64_neon_uqxtn:
6862 case Intrinsic::aarch64_neon_sqshrn:
6863 if (
Op.getValueType().isVector())
6866 Op.getOperand(1).getValueType(),
6867 Op.getOperand(1),
Op.getOperand(2)));
6870 case Intrinsic::aarch64_neon_sqshrun:
6871 if (
Op.getValueType().isVector())
6874 Op.getOperand(1).getValueType(),
6875 Op.getOperand(1),
Op.getOperand(2)));
6878 case Intrinsic::aarch64_neon_uqshrn:
6879 if (
Op.getValueType().isVector())
6882 Op.getOperand(1).getValueType(),
6883 Op.getOperand(1),
Op.getOperand(2)));
6886 case Intrinsic::aarch64_neon_sqrshrn:
6887 if (
Op.getValueType().isVector())
6890 Op.getOperand(1).getValueType(),
6891 Op.getOperand(1),
Op.getOperand(2)));
6894 case Intrinsic::aarch64_neon_sqrshrun:
6895 if (
Op.getValueType().isVector())
6898 Op.getOperand(1).getValueType(),
6899 Op.getOperand(1),
Op.getOperand(2)));
6902 case Intrinsic::aarch64_neon_uqrshrn:
6903 if (
Op.getValueType().isVector())
6906 Op.getOperand(1).getValueType(),
6907 Op.getOperand(1),
Op.getOperand(2)));
6910 case Intrinsic::aarch64_neon_sqdmulh:
6912 case Intrinsic::aarch64_neon_sqrdmulh:
6914 case Intrinsic::aarch64_neon_sqrdmlah:
6916 case Intrinsic::aarch64_neon_sqrdmlsh:
6918 case Intrinsic::aarch64_neon_sqrshl:
6920 case Intrinsic::aarch64_neon_sqshl:
6922 case Intrinsic::aarch64_neon_uqrshl:
6924 case Intrinsic::aarch64_neon_uqshl:
6926 case Intrinsic::aarch64_neon_sqadd:
6927 if (
Op.getValueType().isVector())
6932 case Intrinsic::aarch64_neon_sqsub:
6933 if (
Op.getValueType().isVector())
6938 case Intrinsic::aarch64_neon_uqadd:
6939 if (
Op.getValueType().isVector())
6943 case Intrinsic::aarch64_neon_suqadd:
6945 case Intrinsic::aarch64_neon_usqadd:
6947 case Intrinsic::aarch64_neon_uqsub:
6948 if (
Op.getValueType().isVector())
6952 case Intrinsic::aarch64_neon_sqdmulls_scalar:
6954 case Intrinsic::aarch64_neon_sqabs:
6956 case Intrinsic::aarch64_neon_sqneg:
6958 case Intrinsic::aarch64_sve_whilelt:
6961 case Intrinsic::aarch64_sve_whilels:
6964 case Intrinsic::aarch64_sve_whilele:
6967 case Intrinsic::aarch64_sve_sunpkhi:
6968 return DAG.
getNode(AArch64ISD::SUNPKHI,
DL,
Op.getValueType(),
6970 case Intrinsic::aarch64_sve_sunpklo:
6971 return DAG.
getNode(AArch64ISD::SUNPKLO,
DL,
Op.getValueType(),
6973 case Intrinsic::aarch64_sve_uunpkhi:
6974 return DAG.
getNode(AArch64ISD::UUNPKHI,
DL,
Op.getValueType(),
6976 case Intrinsic::aarch64_sve_uunpklo:
6977 return DAG.
getNode(AArch64ISD::UUNPKLO,
DL,
Op.getValueType(),
6979 case Intrinsic::aarch64_sve_clasta_n:
6980 return DAG.
getNode(AArch64ISD::CLASTA_N,
DL,
Op.getValueType(),
6981 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
6982 case Intrinsic::aarch64_sve_clastb_n:
6983 return DAG.
getNode(AArch64ISD::CLASTB_N,
DL,
Op.getValueType(),
6984 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
6985 case Intrinsic::aarch64_sve_lasta:
6986 return DAG.
getNode(AArch64ISD::LASTA,
DL,
Op.getValueType(),
6987 Op.getOperand(1),
Op.getOperand(2));
6988 case Intrinsic::aarch64_sve_lastb:
6989 return DAG.
getNode(AArch64ISD::LASTB,
DL,
Op.getValueType(),
6990 Op.getOperand(1),
Op.getOperand(2));
6991 case Intrinsic::aarch64_sve_tbl:
6992 return DAG.
getNode(AArch64ISD::TBL,
DL,
Op.getValueType(),
Op.getOperand(1),
6994 case Intrinsic::aarch64_sve_trn1:
6995 return DAG.
getNode(AArch64ISD::TRN1,
DL,
Op.getValueType(),
6996 Op.getOperand(1),
Op.getOperand(2));
6997 case Intrinsic::aarch64_sve_trn2:
6998 return DAG.
getNode(AArch64ISD::TRN2,
DL,
Op.getValueType(),
6999 Op.getOperand(1),
Op.getOperand(2));
7000 case Intrinsic::aarch64_sve_uzp1:
7001 return DAG.
getNode(AArch64ISD::UZP1,
DL,
Op.getValueType(),
7002 Op.getOperand(1),
Op.getOperand(2));
7003 case Intrinsic::aarch64_sve_uzp2:
7004 return DAG.
getNode(AArch64ISD::UZP2,
DL,
Op.getValueType(),
7005 Op.getOperand(1),
Op.getOperand(2));
7006 case Intrinsic::aarch64_sve_zip1:
7007 return DAG.
getNode(AArch64ISD::ZIP1,
DL,
Op.getValueType(),
7008 Op.getOperand(1),
Op.getOperand(2));
7009 case Intrinsic::aarch64_sve_zip2:
7010 return DAG.
getNode(AArch64ISD::ZIP2,
DL,
Op.getValueType(),
7011 Op.getOperand(1),
Op.getOperand(2));
7012 case Intrinsic::aarch64_sve_splice:
7013 return DAG.
getNode(AArch64ISD::SPLICE,
DL,
Op.getValueType(),
7014 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
7015 case Intrinsic::aarch64_sve_ptrue:
7016 return getPTrue(DAG,
DL,
Op.getValueType(),
Op.getConstantOperandVal(1));
7017 case Intrinsic::aarch64_sve_clz:
7018 return DAG.
getNode(AArch64ISD::CTLZ_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7019 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7020 case Intrinsic::aarch64_sme_cntsd: {
7026 case Intrinsic::aarch64_sve_cnt: {
7029 if (
Data.getValueType().isFloatingPoint())
7031 return DAG.
getNode(AArch64ISD::CTPOP_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7032 Op.getOperand(2),
Data,
Op.getOperand(1));
7034 case Intrinsic::aarch64_sve_dupq_lane:
7035 return LowerDUPQLane(
Op, DAG);
7036 case Intrinsic::aarch64_sve_convert_from_svbool:
7038 case Intrinsic::aarch64_sve_convert_to_svbool:
7040 case Intrinsic::aarch64_sve_convert_from_svcount:
7041 case Intrinsic::aarch64_sve_convert_to_svcount:
7043 case Intrinsic::aarch64_sve_fneg:
7044 return DAG.
getNode(AArch64ISD::FNEG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7045 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7046 case Intrinsic::aarch64_sve_frintp:
7047 return DAG.
getNode(AArch64ISD::FCEIL_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7048 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7049 case Intrinsic::aarch64_sve_frintm:
7050 return DAG.
getNode(AArch64ISD::FFLOOR_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7051 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7052 case Intrinsic::aarch64_sve_frinti:
7053 return DAG.
getNode(AArch64ISD::FNEARBYINT_MERGE_PASSTHRU,
DL,
7054 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7056 case Intrinsic::aarch64_sve_frintx:
7057 return DAG.
getNode(AArch64ISD::FRINT_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7058 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7059 case Intrinsic::aarch64_sve_frint32x:
7060 return DAG.
getNode(AArch64ISD::FRINT32_MERGE_PASSTHRU,
DL,
7061 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7063 case Intrinsic::aarch64_sve_frint64x:
7064 return DAG.
getNode(AArch64ISD::FRINT64_MERGE_PASSTHRU,
DL,
7065 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7067 case Intrinsic::aarch64_sve_frinta:
7068 return DAG.
getNode(AArch64ISD::FROUND_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7069 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7070 case Intrinsic::aarch64_sve_frintn:
7071 return DAG.
getNode(AArch64ISD::FROUNDEVEN_MERGE_PASSTHRU,
DL,
7072 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7074 case Intrinsic::aarch64_sve_frintz:
7075 return DAG.
getNode(AArch64ISD::FTRUNC_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7076 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7077 case Intrinsic::aarch64_sve_frint32z:
7078 return DAG.
getNode(AArch64ISD::FTRUNC32_MERGE_PASSTHRU,
DL,
7079 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7081 case Intrinsic::aarch64_sve_frint64z:
7082 return DAG.
getNode(AArch64ISD::FTRUNC64_MERGE_PASSTHRU,
DL,
7083 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7085 case Intrinsic::aarch64_sve_ucvtf:
7086 return DAG.
getNode(AArch64ISD::UINT_TO_FP_MERGE_PASSTHRU,
DL,
7087 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7089 case Intrinsic::aarch64_sve_scvtf:
7090 return DAG.
getNode(AArch64ISD::SINT_TO_FP_MERGE_PASSTHRU,
DL,
7091 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7093 case Intrinsic::aarch64_sve_fcvtzu:
7094 return DAG.
getNode(AArch64ISD::FCVTZU_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7095 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7096 case Intrinsic::aarch64_sve_fcvtzs:
7097 return DAG.
getNode(AArch64ISD::FCVTZS_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7098 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7099 case Intrinsic::aarch64_sve_fsqrt:
7100 return DAG.
getNode(AArch64ISD::FSQRT_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7101 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7102 case Intrinsic::aarch64_sve_frecpx:
7103 return DAG.
getNode(AArch64ISD::FRECPX_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7104 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7105 case Intrinsic::aarch64_sve_frecpe_x:
7106 return DAG.
getNode(AArch64ISD::FRECPE,
DL,
Op.getValueType(),
7108 case Intrinsic::aarch64_sve_frecps_x:
7109 return DAG.
getNode(AArch64ISD::FRECPS,
DL,
Op.getValueType(),
7110 Op.getOperand(1),
Op.getOperand(2));
7111 case Intrinsic::aarch64_sve_frsqrte_x:
7112 return DAG.
getNode(AArch64ISD::FRSQRTE,
DL,
Op.getValueType(),
7114 case Intrinsic::aarch64_sve_frsqrts_x:
7115 return DAG.
getNode(AArch64ISD::FRSQRTS,
DL,
Op.getValueType(),
7116 Op.getOperand(1),
Op.getOperand(2));
7117 case Intrinsic::aarch64_sve_fabs:
7118 return DAG.
getNode(AArch64ISD::FABS_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7119 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7120 case Intrinsic::aarch64_sve_abs:
7121 return DAG.
getNode(AArch64ISD::ABS_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7122 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7123 case Intrinsic::aarch64_sve_neg:
7124 return DAG.
getNode(AArch64ISD::NEG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7125 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7126 case Intrinsic::aarch64_sve_insr: {
7128 EVT ScalarTy =
Scalar.getValueType();
7129 if ((ScalarTy == MVT::i8) || (ScalarTy == MVT::i16))
7132 return DAG.
getNode(AArch64ISD::INSR,
DL,
Op.getValueType(),
7133 Op.getOperand(1), Scalar);
7135 case Intrinsic::aarch64_sve_rbit:
7136 return DAG.
getNode(AArch64ISD::BITREVERSE_MERGE_PASSTHRU,
DL,
7137 Op.getValueType(),
Op.getOperand(2),
Op.getOperand(3),
7139 case Intrinsic::aarch64_sve_revb:
7140 return DAG.
getNode(AArch64ISD::BSWAP_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7141 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7142 case Intrinsic::aarch64_sve_revh:
7143 return DAG.
getNode(AArch64ISD::REVH_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7144 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7145 case Intrinsic::aarch64_sve_revw:
7146 return DAG.
getNode(AArch64ISD::REVW_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7147 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7148 case Intrinsic::aarch64_sve_revd:
7149 return DAG.
getNode(AArch64ISD::REVD_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7150 Op.getOperand(2),
Op.getOperand(3),
Op.getOperand(1));
7151 case Intrinsic::aarch64_sve_sxtb:
7153 AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7154 Op.getOperand(2),
Op.getOperand(3),
7158 case Intrinsic::aarch64_sve_sxth:
7160 AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7161 Op.getOperand(2),
Op.getOperand(3),
7165 case Intrinsic::aarch64_sve_sxtw:
7167 AArch64ISD::SIGN_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7168 Op.getOperand(2),
Op.getOperand(3),
7172 case Intrinsic::aarch64_sve_uxtb:
7174 AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7175 Op.getOperand(2),
Op.getOperand(3),
7179 case Intrinsic::aarch64_sve_uxth:
7181 AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7182 Op.getOperand(2),
Op.getOperand(3),
7186 case Intrinsic::aarch64_sve_uxtw:
7188 AArch64ISD::ZERO_EXTEND_INREG_MERGE_PASSTHRU,
DL,
Op.getValueType(),
7189 Op.getOperand(2),
Op.getOperand(3),
7193 case Intrinsic::localaddress: {
7195 const auto *RegInfo = Subtarget->getRegisterInfo();
7196 unsigned Reg = RegInfo->getLocalAddressRegister(MF);
7198 Op.getSimpleValueType());
7201 case Intrinsic::eh_recoverfp: {
7206 SDValue IncomingFPOp =
Op.getOperand(2);
7211 "llvm.eh.recoverfp must take a function as the first argument");
7212 return IncomingFPOp;
7214 case Intrinsic::aarch64_neon_vsri:
7215 case Intrinsic::aarch64_neon_vsli:
7216 case Intrinsic::aarch64_sve_sri:
7217 case Intrinsic::aarch64_sve_sli: {
7218 EVT Ty =
Op.getValueType();
7225 bool IsShiftRight = IntNo == Intrinsic::aarch64_neon_vsri ||
7226 IntNo == Intrinsic::aarch64_sve_sri;
7227 unsigned Opcode = IsShiftRight ? AArch64ISD::VSRI : AArch64ISD::VSLI;
7228 return DAG.
getNode(Opcode,
DL, Ty,
Op.getOperand(1),
Op.getOperand(2),
7232 case Intrinsic::aarch64_neon_srhadd:
7233 case Intrinsic::aarch64_neon_urhadd:
7234 case Intrinsic::aarch64_neon_shadd:
7235 case Intrinsic::aarch64_neon_uhadd: {
7236 bool IsSignedAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
7237 IntNo == Intrinsic::aarch64_neon_shadd);
7238 bool IsRoundingAdd = (IntNo == Intrinsic::aarch64_neon_srhadd ||
7239 IntNo == Intrinsic::aarch64_neon_urhadd);
7240 unsigned Opcode = IsSignedAdd
7243 return DAG.
getNode(Opcode,
DL,
Op.getValueType(),
Op.getOperand(1),
7246 case Intrinsic::aarch64_neon_saddlp:
7247 case Intrinsic::aarch64_neon_uaddlp: {
7248 unsigned Opcode = IntNo == Intrinsic::aarch64_neon_uaddlp
7249 ? AArch64ISD::UADDLP
7250 : AArch64ISD::SADDLP;
7251 return DAG.
getNode(Opcode,
DL,
Op.getValueType(),
Op.getOperand(1));
7253 case Intrinsic::aarch64_neon_sdot:
7254 case Intrinsic::aarch64_neon_udot:
7255 case Intrinsic::aarch64_sve_sdot:
7256 case Intrinsic::aarch64_sve_udot: {
7257 unsigned Opcode = (IntNo == Intrinsic::aarch64_neon_udot ||
7258 IntNo == Intrinsic::aarch64_sve_udot)
7261 return DAG.
getNode(Opcode,
DL,
Op.getValueType(),
Op.getOperand(1),
7262 Op.getOperand(2),
Op.getOperand(3));
7264 case Intrinsic::aarch64_neon_usdot:
7265 case Intrinsic::aarch64_sve_usdot: {
7266 return DAG.
getNode(AArch64ISD::USDOT,
DL,
Op.getValueType(),
7267 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
7269 case Intrinsic::aarch64_neon_saddlv:
7270 case Intrinsic::aarch64_neon_uaddlv: {
7271 EVT OpVT =
Op.getOperand(1).getValueType();
7272 EVT ResVT =
Op.getValueType();
7274 ((ResVT == MVT::i32 && (OpVT == MVT::v8i8 || OpVT == MVT::v16i8 ||
7275 OpVT == MVT::v8i16 || OpVT == MVT::v4i16)) ||
7276 (ResVT == MVT::i64 && (OpVT == MVT::v4i32 || OpVT == MVT::v2i32))) &&
7277 "Unexpected aarch64_neon_u/saddlv type");
7281 IntNo == Intrinsic::aarch64_neon_uaddlv ? AArch64ISD::UADDLV
7282 : AArch64ISD::SADDLV,
7283 DL, ResVT == MVT::i32 ? MVT::v4i32 : MVT::v2i64,
Op.getOperand(1));
7287 return EXTRACT_VEC_ELT;
7289 case Intrinsic::aarch64_cls:
7290 case Intrinsic::aarch64_cls64: {
7295 case Intrinsic::aarch64_neon_cls: {
7299 case Intrinsic::aarch64_sve_pmul:
7300 case Intrinsic::aarch64_neon_pmul:
7303 case Intrinsic::aarch64_sve_psel: {
7304 if (
Op.getValueType() != MVT::aarch64svcount)
7315bool AArch64TargetLowering::shouldExtendGSIndex(
EVT VT,
EVT &EltTy)
const {
7324bool AArch64TargetLowering::shouldRemoveExtendFromGSIndex(
SDValue Extend,
7345 if (LD->isVolatile())
7348 EVT MemVT = LD->getMemoryVT();
7349 if (MemVT != MVT::v2i8 && MemVT != MVT::v4i8 && MemVT != MVT::v2i16)
7352 Align Alignment = LD->getAlign();
7354 if (Subtarget.requiresStrictAlign() && Alignment < RequiredAlignment)
7360bool AArch64TargetLowering::isVectorLoadExtDesirable(
SDValue ExtVal)
const {
7368 if (!ExtVT.
isScalableVector() && !Subtarget->useSVEForFixedLengthVectors())