22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
64 void PreprocessISelDAG()
override;
68 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
70 std::vector<SDValue> &OutOps)
override;
72 template <
signed Low,
signed High,
signed Scale>
75 template <
signed Low,
signed High>
83 return SelectShiftedRegister(
N,
false,
Reg, Shift);
86 return SelectShiftedRegister(
N,
true,
Reg, Shift);
89 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
95 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
98 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
101 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
104 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
107 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
116 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
119 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
122 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
131 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
134 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
137 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
139 template <
unsigned Size,
unsigned Max>
143 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
146 int64_t
C = CI->getSExtValue();
154 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
161 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
167 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
172 N =
N->getOperand(0);
176 EVT VT =
N->getValueType(0);
177 EVT LVT =
N->getOperand(0).getValueType();
178 unsigned Index =
N->getConstantOperandVal(1);
182 Res =
N->getOperand(0);
187 if (
N.getOpcode() != AArch64ISD::VLSHR)
190 EVT VT =
Op.getValueType();
191 unsigned ShtAmt =
N->getConstantOperandVal(1);
196 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
198 Op.getOperand(1).getConstantOperandVal(0)
199 <<
Op.getOperand(1).getConstantOperandVal(1));
200 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
203 Op.getOperand(1).getConstantOperandVal(0));
207 if (Imm != 1ULL << (ShtAmt - 1))
210 Res1 =
Op.getOperand(0);
211 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
215 bool SelectDupZeroOrUndef(
SDValue N) {
216 switch(
N->getOpcode()) {
219 case AArch64ISD::DUP:
221 auto Opnd0 =
N->getOperand(0);
235 bool SelectAny(
SDValue) {
return true; }
238 switch(
N->getOpcode()) {
239 case AArch64ISD::DUP:
241 auto Opnd0 =
N->getOperand(0);
253 template <MVT::SimpleValueType VT,
bool Negate>
255 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT>
265 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
268 template <MVT::SimpleValueType VT,
bool Invert = false>
270 return SelectSVELogicalImm(
N, VT, Imm, Invert);
273 template <MVT::SimpleValueType VT>
275 return SelectSVEArithImm(
N, VT, Imm);
278 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
280 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
287 EVT EltVT =
N->getValueType(0).getVectorElementType();
288 return SelectSVEShiftImm(
N->getOperand(0), 1,
294 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
301 MulImm = 1LL << MulImm;
303 if ((MulImm % std::abs(Scale)) != 0)
307 if ((MulImm >= Min) && (MulImm <= Max)) {
308 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
315 template <
signed Max,
signed Scale>
322 if (MulImm >= 0 && MulImm <= Max) {
324 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
331 template <
unsigned BaseReg,
unsigned Max>
339 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
362 const unsigned SubRegs[]);
364 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
366 bool tryIndexedLoad(
SDNode *
N);
368 void SelectPtrauthAuth(
SDNode *
N);
369 void SelectPtrauthResign(
SDNode *
N);
371 bool trySelectStackSlotTagP(
SDNode *
N);
374 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
376 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
380 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
381 unsigned Opc_rr,
unsigned Opc_ri,
382 bool IsIntr =
false);
383 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
384 unsigned Scale,
unsigned Opc_ri,
386 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
387 bool IsZmMulti,
unsigned Opcode,
388 bool HasPred =
false);
390 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
391 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
395 bool IsTupleInput,
unsigned Opc);
396 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 template <
unsigned MaxIdx,
unsigned Scale>
399 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
401 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
402 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
403 unsigned BaseReg = 0);
406 template <
int64_t Min,
int64_t Max>
410 template <
unsigned Scale>
412 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
415 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
420 template <
unsigned MaxIdx,
unsigned Scale>
425 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
430 unsigned Opc_rr,
unsigned Opc_ri);
431 std::tuple<unsigned, SDValue, SDValue>
432 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
436 bool tryBitfieldExtractOp(
SDNode *
N);
437 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
438 bool tryBitfieldInsertOp(
SDNode *
N);
439 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
440 bool tryShiftAmountMod(
SDNode *
N);
442 bool tryReadRegister(
SDNode *
N);
443 bool tryWriteRegister(
SDNode *
N);
445 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
446 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
451#include "AArch64GenDAGISel.inc"
459 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
461 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
474 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
475 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
476 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
479 template<
unsigned RegW
idth>
481 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
483 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
485 template <
unsigned RegW
idth>
487 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
489 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
491 template<
unsigned RegW
idth>
493 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
499 template <
unsigned FloatW
idth>
501 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
507 bool SelectCMP_SWAP(
SDNode *
N);
526 bool AllowSaturation,
SDValue &Imm);
534 bool SelectAllActivePredicate(
SDValue N);
539 template <
bool MatchCBB>
549 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
553char AArch64DAGToDAGISelLegacy::ID = 0;
561 auto getFloatVT = [&](
EVT VT) {
563 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
564 return VT.changeElementType(*(DAG.getContext()),
565 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
570 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
571 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
575 EVT OrigVT =
N.getValueType(0);
577 return DAG.getBitcast(OrigVT, OpNode);
584 Imm =
C->getZExtValue();
601 return N->getOpcode() ==
Opc &&
612 return Imm == ImmExpected;
617 assert(RegWidth == 32 || RegWidth == 64);
619 return APInt(RegWidth,
626 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
627 if (
N->getOpcode() == AArch64ISD::NVCAST)
628 N =
N->getOperand(0);
629 unsigned SplatWidth =
N.getScalarValueSizeInBits();
630 if (
N.getOpcode() == AArch64ISD::FMOV)
632 if (
N->getOpcode() == AArch64ISD::MOVI)
633 return APInt(SplatWidth,
N.getConstantOperandVal(0));
634 if (
N->getOpcode() == AArch64ISD::MOVIshift)
635 return APInt(SplatWidth,
N.getConstantOperandVal(0)
636 <<
N.getConstantOperandVal(1));
637 if (
N->getOpcode() == AArch64ISD::MVNIshift)
638 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
639 <<
N.getConstantOperandVal(1));
640 if (
N->getOpcode() == AArch64ISD::MOVIedit)
642 N.getConstantOperandVal(0)));
643 if (
N->getOpcode() == AArch64ISD::DUP)
645 return Const->getAPIntValue().trunc(SplatWidth);
654 unsigned SplatWidth =
N.getScalarValueSizeInBits();
656 if (SplatVal->getBitWidth() <= SplatWidth)
658 if (SplatVal->isSplat(SplatWidth))
659 return SplatVal->trunc(SplatWidth);
664bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
671 ImmVal->getZExtValue(), Encoding))
674 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
678bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
681 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
682 N.getValueType().getScalarType().getSimpleVT(),
688bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
691 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
695bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
697 std::vector<SDValue> &OutOps) {
698 switch(ConstraintID) {
701 case InlineAsm::ConstraintCode::m:
702 case InlineAsm::ConstraintCode::o:
703 case InlineAsm::ConstraintCode::Q:
707 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
709 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
711 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
712 dl,
Op.getValueType(),
714 OutOps.push_back(NewOp);
733 uint64_t Immed =
N.getNode()->getAsZExtVal();
736 if (Immed >> 12 == 0) {
738 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
746 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
747 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
764 uint64_t Immed =
N.getNode()->getAsZExtVal();
772 if (
N.getValueType() == MVT::i32)
773 Immed = ~((uint32_t)Immed) + 1;
775 Immed = ~Immed + 1ULL;
776 if (Immed & 0xFFFFFFFFFF000000ULL)
779 Immed &= 0xFFFFFFULL;
780 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
787 switch (
N.getOpcode()) {
813 unsigned ShiftVal = CSD->getZExtValue();
831bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
834 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
839 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
863 EVT VT =
N.getValueType();
864 if (VT != MVT::i32 && VT != MVT::i64)
867 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
873 unsigned LHSOpcode =
LHS->getOpcode();
887 unsigned LowZBits, MaskLen;
891 unsigned BitWidth =
N.getValueSizeInBits();
898 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
901 NewShiftC = LowZBits - ShiftAmtC;
902 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
908 NewShiftC = LowZBits + ShiftAmtC;
921 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
923 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
927 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
929 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
930 NewShiftAmt, BitWidthMinus1),
933 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
947 SrcVT =
N.getOperand(0).getValueType();
949 if (!IsLoadStore && SrcVT == MVT::i8)
951 else if (!IsLoadStore && SrcVT == MVT::i16)
953 else if (SrcVT == MVT::i32)
955 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
960 EVT SrcVT =
N.getOperand(0).getValueType();
961 if (!IsLoadStore && SrcVT == MVT::i8)
963 else if (!IsLoadStore && SrcVT == MVT::i16)
965 else if (SrcVT == MVT::i32)
967 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
995bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
998 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1003 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1004 V.getConstantOperandVal(1) <= 4 &&
1017bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
1019 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1029 unsigned BitSize =
N.getValueSizeInBits();
1030 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1033 Reg =
N.getOperand(0);
1034 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1035 return isWorthFoldingALU(
N,
true);
1046 if (
N.getValueType() == MVT::i32)
1054template<
signed Low,
signed High,
signed Scale>
1060 if ((MulImm % std::abs(Scale)) == 0) {
1061 int64_t RDVLImm = MulImm / Scale;
1062 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1063 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1072template <
signed Low,
signed High>
1073bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1078 if (MulImm >=
Low && MulImm <=
High) {
1079 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1090 unsigned ShiftVal = 0;
1105 Reg =
N.getOperand(0).getOperand(0);
1117 Op =
Op->getOperand(0);
1119 Op.getOperand(0).getValueType().isFixedLengthVector())
1123 Reg =
N.getOperand(0);
1128 unsigned Opc =
N.getOpcode();
1146 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1148 return isWorthFoldingALU(
N);
1155 unsigned ShiftVal = 0;
1169 Reg =
N.getOperand(0);
1170 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1172 return isWorthFoldingALU(
N);
1181 for (
auto *
User :
N->users()) {
1208bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1209 unsigned BW,
unsigned Size,
1213 const DataLayout &
DL = CurDAG->getDataLayout();
1214 const TargetLowering *TLI = getTargetLowering();
1218 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1224 if (CurDAG->isBaseWithConstantOffset(
N)) {
1227 int64_t RHSC =
RHS->getSExtValue();
1229 int64_t
Range = 0x1LL << (BW - 1);
1231 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1232 RHSC < (
Range << Scale)) {
1233 Base =
N.getOperand(0);
1238 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1243 uint64_t RHSC =
RHS->getZExtValue();
1245 uint64_t
Range = 0x1ULL << BW;
1247 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1248 Base =
N.getOperand(0);
1253 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1264 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1271bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1274 const DataLayout &
DL = CurDAG->getDataLayout();
1275 const TargetLowering *TLI = getTargetLowering();
1279 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1284 GlobalAddressSDNode *GAN =
1286 Base =
N.getOperand(0);
1296 if (CurDAG->isBaseWithConstantOffset(
N)) {
1298 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1301 Base =
N.getOperand(0);
1306 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1314 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1322 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1331bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1334 if (!CurDAG->isBaseWithConstantOffset(
N))
1337 int64_t RHSC =
RHS->getSExtValue();
1338 if (RHSC >= -256 && RHSC < 256) {
1339 Base =
N.getOperand(0);
1342 const TargetLowering *TLI = getTargetLowering();
1343 Base = CurDAG->getTargetFrameIndex(
1346 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1356 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1363bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1383 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1389 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1392 return isWorthFoldingAddr(
N,
Size);
1395bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1413 const SDNode *
Node =
N.getNode();
1414 for (SDNode *UI :
Node->users()) {
1420 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1423 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1426 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1431 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1434 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1439 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1443 if (IsExtendedRegisterWorthFolding &&
1450 if (isWorthFoldingAddr(
LHS,
Size))
1455 if (IsExtendedRegisterWorthFolding &&
1462 if (isWorthFoldingAddr(
RHS,
Size))
1474 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1477 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1479 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1480 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1484bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1497 const SDNode *
Node =
N.getNode();
1498 for (SDNode *UI :
Node->users()) {
1515 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1525 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1532 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1535 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1538 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1543 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1546 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1553 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1554 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1560 static const unsigned RegClassIDs[] = {
1561 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1562 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1563 AArch64::dsub2, AArch64::dsub3};
1569 static const unsigned RegClassIDs[] = {
1570 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1571 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1572 AArch64::qsub2, AArch64::qsub3};
1578 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1579 AArch64::ZPR3RegClassID,
1580 AArch64::ZPR4RegClassID};
1581 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1582 AArch64::zsub2, AArch64::zsub3};
1592 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1593 AArch64::ZPR4Mul4RegClassID};
1594 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1595 AArch64::zsub2, AArch64::zsub3};
1600 const unsigned RegClassIDs[],
1601 const unsigned SubRegs[]) {
1604 if (Regs.
size() == 1)
1615 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1618 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1619 Ops.push_back(Regs[i]);
1620 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1624 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1628void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1631 EVT VT =
N->getValueType(0);
1633 unsigned ExtOff = isExt;
1636 unsigned Vec0Off = ExtOff + 1;
1642 Ops.push_back(
N->getOperand(1));
1643 Ops.push_back(RegSeq);
1644 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1645 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1648static std::tuple<SDValue, SDValue>
1669 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1674 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1676 return std::make_tuple(
1681void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1686 SDValue AUTDisc =
N->getOperand(3);
1689 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1691 SDValue AUTAddrDisc, AUTConstDisc;
1692 std::tie(AUTConstDisc, AUTAddrDisc) =
1696 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1698 if (
N->getNumOperands() > 4)
1699 Ops.push_back(
N->getOperand(4));
1702 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1703 ReplaceNode(
N, AUT);
1705 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1706 AArch64::X16, Val,
SDValue());
1709 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1710 ReplaceNode(
N, AUT);
1714void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1724 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1729 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1730 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1732 SDValue AUTAddrDisc, AUTConstDisc;
1733 std::tie(AUTConstDisc, AUTAddrDisc) =
1736 SDValue PACAddrDisc, PACConstDisc;
1737 std::tie(PACConstDisc, PACAddrDisc) =
1740 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1741 AArch64::X16, Val,
SDValue());
1744 SDValue Addend =
N->getOperand(OffsetBase + 6);
1745 SDValue IncomingChain =
N->getOperand(0);
1746 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1747 PACKey, PACConstDisc, PACAddrDisc,
1748 Addend, IncomingChain, X16Copy.
getValue(1)};
1750 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1751 MVT::i64, MVT::Other,
Ops);
1752 ReplaceNode(
N, AUTRELLOADPAC);
1754 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1755 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1757 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1758 ReplaceNode(
N, AUTPAC);
1762bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1764 if (
LD->isUnindexed())
1766 EVT VT =
LD->getMemoryVT();
1767 EVT DstVT =
N->getValueType(0);
1771 int OffsetVal = (int)
OffsetOp->getZExtValue();
1776 unsigned Opcode = 0;
1779 bool InsertTo64 =
false;
1781 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1782 else if (VT == MVT::i32) {
1784 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1786 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1788 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1794 }
else if (VT == MVT::i16) {
1796 if (DstVT == MVT::i64)
1797 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1799 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1801 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1802 InsertTo64 = DstVT == MVT::i64;
1807 }
else if (VT == MVT::i8) {
1809 if (DstVT == MVT::i64)
1810 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1812 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1814 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1815 InsertTo64 = DstVT == MVT::i64;
1820 }
else if (VT == MVT::f16) {
1821 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1822 }
else if (VT == MVT::bf16) {
1823 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1824 }
else if (VT == MVT::f32) {
1825 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1826 }
else if (VT == MVT::f64 ||
1828 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1830 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1832 if (IsPre || OffsetVal != 8)
1836 Opcode = AArch64::LD1Onev8b_POST;
1839 Opcode = AArch64::LD1Onev4h_POST;
1842 Opcode = AArch64::LD1Onev2s_POST;
1845 Opcode = AArch64::LD1Onev1d_POST;
1851 if (IsPre || OffsetVal != 16)
1855 Opcode = AArch64::LD1Onev16b_POST;
1858 Opcode = AArch64::LD1Onev8h_POST;
1861 Opcode = AArch64::LD1Onev4s_POST;
1864 Opcode = AArch64::LD1Onev2d_POST;
1876 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1877 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1879 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1889 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1890 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1891 MVT::i64, LoadedVal, SubReg),
1895 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1898 CurDAG->RemoveDeadNode(
N);
1902void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1903 unsigned SubRegIdx) {
1905 EVT VT =
N->getValueType(0);
1911 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1913 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1915 for (
unsigned i = 0; i < NumVecs; ++i)
1917 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1924 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1928 CurDAG->RemoveDeadNode(
N);
1931void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1932 unsigned Opc,
unsigned SubRegIdx) {
1934 EVT VT =
N->getValueType(0);
1941 const EVT ResTys[] = {MVT::i64,
1942 MVT::Untyped, MVT::Other};
1944 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1952 ReplaceUses(
SDValue(
N, 0), SuperReg);
1954 for (
unsigned i = 0; i < NumVecs; ++i)
1956 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1960 CurDAG->RemoveDeadNode(
N);
1966std::tuple<unsigned, SDValue, SDValue>
1967AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1973 SDValue NewOffset = OldOffset;
1975 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1976 N, OldBase, NewBase, NewOffset);
1980 const bool IsRegReg =
1981 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1984 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1997template <SelectTypeKind Kind>
2009 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2014 if (EltVT != MVT::i1)
2018 if (EltVT == MVT::bf16)
2020 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2050void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2053 if (
Imm->getZExtValue() > 1)
2057 EVT VT =
N->getValueType(0);
2059 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2062 for (
unsigned I = 0;
I < 2; ++
I)
2063 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2064 AArch64::psub0 +
I,
DL, VT, SuperReg));
2066 CurDAG->RemoveDeadNode(
N);
2069void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2071 EVT VT =
N->getValueType(0);
2075 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2078 for (
unsigned I = 0;
I < 2; ++
I)
2079 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2080 AArch64::psub0 +
I,
DL, VT, SuperReg));
2082 CurDAG->RemoveDeadNode(
N);
2085void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2087 EVT VT =
N->getValueType(0);
2091 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2093 for (
unsigned i = 0; i < NumVecs; ++i)
2094 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2095 AArch64::zsub0 + i,
DL, VT, SuperReg));
2097 CurDAG->RemoveDeadNode(
N);
2100void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2103 EVT VT =
N->getValueType(0);
2105 Ops.push_back(
N->getOperand(0));
2108 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2111 for (
unsigned i = 0; i < NumVecs; ++i)
2112 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2113 AArch64::zsub0 + i,
DL, VT, SuperReg));
2116 unsigned ChainIdx = NumVecs;
2118 CurDAG->RemoveDeadNode(
N);
2121void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2126 assert(Opcode != 0 &&
"Unexpected opcode");
2129 EVT VT =
N->getValueType(0);
2130 SDUse *OpsIter =
N->op_begin() + 1;
2133 auto GetMultiVecOperand = [&]() {
2136 return createZMulTuple(Regs);
2140 Ops.push_back(*OpsIter++);
2142 Ops.push_back(GetMultiVecOperand());
2144 Ops.push_back(GetMultiVecOperand());
2146 Ops.push_back(*OpsIter++);
2149 Ops.append(OpsIter,
N->op_end());
2151 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2153 for (
unsigned i = 0; i < NumVecs; ++i)
2154 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2155 AArch64::zsub0 + i,
DL, VT, SuperReg));
2157 CurDAG->RemoveDeadNode(
N);
2160void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2161 unsigned Scale,
unsigned Opc_ri,
2162 unsigned Opc_rr,
bool IsIntr) {
2163 assert(Scale < 5 &&
"Invalid scaling value.");
2165 EVT VT =
N->getValueType(0);
2172 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2173 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2179 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2181 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2183 for (
unsigned i = 0; i < NumVecs; ++i)
2184 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2185 AArch64::zsub0 + i,
DL, VT, SuperReg));
2188 unsigned ChainIdx = NumVecs;
2190 CurDAG->RemoveDeadNode(
N);
2193void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2198 assert(Scale < 4 &&
"Invalid scaling value.");
2200 EVT VT =
N->getValueType(0);
2208 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2214 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2216 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2218 for (
unsigned i = 0; i < NumVecs; ++i)
2219 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2220 AArch64::zsub0 + i,
DL, VT, SuperReg));
2223 unsigned ChainIdx = NumVecs;
2225 CurDAG->RemoveDeadNode(
N);
2228void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2230 if (
N->getValueType(0) != MVT::nxv4f32)
2232 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2235void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2236 unsigned NumOutVecs,
2240 if (
Imm->getZExtValue() > MaxImm)
2244 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2250 EVT VT =
Node->getValueType(0);
2253 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2256 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2257 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2258 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2261 unsigned ChainIdx = NumOutVecs;
2263 CurDAG->RemoveDeadNode(Node);
2266void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2267 unsigned NumOutVecs,
2270 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2275 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2279 EVT VT =
Node->getValueType(0);
2282 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2285 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2286 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2287 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2290 unsigned ChainIdx = NumOutVecs;
2292 CurDAG->RemoveDeadNode(Node);
2295void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2298 EVT VT =
N->getValueType(0);
2301 SDValue Zd = createZMulTuple(Regs);
2302 SDValue Zn =
N->getOperand(1 + NumVecs);
2303 SDValue Zm =
N->getOperand(2 + NumVecs);
2309 for (
unsigned i = 0; i < NumVecs; ++i)
2310 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2311 AArch64::zsub0 + i,
DL, VT, SuperReg));
2313 CurDAG->RemoveDeadNode(
N);
2343template <
unsigned MaxIdx,
unsigned Scale>
2344void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2345 unsigned BaseReg,
unsigned Op) {
2346 unsigned TileNum = 0;
2347 if (BaseReg != AArch64::ZA)
2348 TileNum =
N->getConstantOperandVal(2);
2354 if (BaseReg == AArch64::ZA)
2359 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2363 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2365 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2367 EVT VT =
N->getValueType(0);
2368 for (
unsigned I = 0;
I < NumVecs; ++
I)
2370 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2373 unsigned ChainIdx = NumVecs;
2375 CurDAG->RemoveDeadNode(
N);
2378void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2379 unsigned Op,
unsigned MaxIdx,
2380 unsigned Scale,
unsigned BaseReg) {
2385 if (BaseReg != AArch64::ZA)
2389 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2396 if (BaseReg != AArch64::ZA )
2397 Ops.push_back(
N->getOperand(2));
2400 Ops.push_back(
N->getOperand(0));
2401 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2403 EVT VT =
N->getValueType(0);
2404 for (
unsigned I = 0;
I < NumVecs; ++
I)
2406 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2410 unsigned ChainIdx = NumVecs;
2412 CurDAG->RemoveDeadNode(
N);
2415void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2416 unsigned NumOutVecs,
2420 EVT VT =
N->getValueType(0);
2421 unsigned NumInVecs =
N->getNumOperands() - 1;
2425 assert((NumInVecs == 2 || NumInVecs == 4) &&
2426 "Don't know how to handle multi-register input!");
2428 Ops.push_back(createZMulTuple(Regs));
2431 for (
unsigned I = 0;
I < NumInVecs;
I++)
2432 Ops.push_back(
N->getOperand(1 +
I));
2435 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2438 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2439 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2440 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2441 CurDAG->RemoveDeadNode(
N);
2444void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2447 EVT VT =
N->getOperand(2)->getValueType(0);
2455 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2464void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2465 unsigned Scale,
unsigned Opc_rr,
2471 SDValue RegSeq = createZTuple(Regs);
2477 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2478 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2484 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2492 const DataLayout &
DL = CurDAG->getDataLayout();
2493 const TargetLowering *TLI = getTargetLowering();
2497 int FI = FINode->getIndex();
2499 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2506void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2509 EVT VT =
N->getOperand(2)->getValueType(0);
2510 const EVT ResTys[] = {MVT::i64,
2522 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2562void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2565 EVT VT =
N->getValueType(0);
2577 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2579 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2581 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2583 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2587 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2588 AArch64::qsub2, AArch64::qsub3 };
2589 for (
unsigned i = 0; i < NumVecs; ++i) {
2590 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2597 CurDAG->RemoveDeadNode(
N);
2600void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2603 EVT VT =
N->getValueType(0);
2615 const EVT ResTys[] = {MVT::i64,
2618 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2621 CurDAG->getTargetConstant(LaneNo, dl,
2626 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2638 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2639 AArch64::qsub2, AArch64::qsub3 };
2640 for (
unsigned i = 0; i < NumVecs; ++i) {
2641 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2651 CurDAG->RemoveDeadNode(
N);
2654void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2657 EVT VT =
N->getOperand(2)->getValueType(0);
2669 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2671 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2673 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2682void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2685 EVT VT =
N->getOperand(2)->getValueType(0);
2697 const EVT ResTys[] = {MVT::i64,
2700 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2702 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2706 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2717 unsigned &LSB,
unsigned &MSB,
2718 unsigned NumberOfIgnoredLowBits,
2719 bool BiggerPattern) {
2721 "N must be a AND operation to call this function");
2723 EVT VT =
N->getValueType(0);
2728 assert((VT == MVT::i32 || VT == MVT::i64) &&
2729 "Type checking must have been done before calling this function");
2743 const SDNode *Op0 =
N->getOperand(0).getNode();
2750 if (AndImm & (AndImm + 1))
2753 bool ClampMSB =
false;
2773 ClampMSB = (VT == MVT::i32);
2774 }
else if (BiggerPattern) {
2780 Opd0 =
N->getOperand(0);
2786 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2789 <<
": Found large shift immediate, this should not happen\n"));
2803 MSB = MSB > 31 ? 31 : MSB;
2805 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2810 SDValue &Opd0,
unsigned &Immr,
2814 EVT VT =
N->getValueType(0);
2816 assert((VT == MVT::i32 || VT == MVT::i64) &&
2817 "Type checking must have been done before calling this function");
2821 Op =
Op->getOperand(0);
2822 VT =
Op->getValueType(0);
2831 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2835 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2836 Opd0 =
Op.getOperand(0);
2838 Imms = ShiftImm + Width - 1;
2866 Opd0 =
N->getOperand(0).getOperand(0);
2876 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2883 unsigned &Immr,
unsigned &Imms,
2884 bool BiggerPattern) {
2886 "N must be a SHR/SRA operation to call this function");
2888 EVT VT =
N->getValueType(0);
2893 assert((VT == MVT::i32 || VT == MVT::i64) &&
2894 "Type checking must have been done before calling this function");
2904 Opd0 =
N->getOperand(0).getOperand(0);
2905 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2911 Opd0 =
N->getOperand(0).getOperand(0);
2914 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2915 }
else if (BiggerPattern) {
2919 Opd0 =
N->getOperand(0);
2928 <<
": Found large shift immediate, this should not happen\n"));
2937 "bad amount in shift node!");
2938 int immr = SrlImm - ShlImm;
2943 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2945 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2949bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2952 EVT VT =
N->getValueType(0);
2953 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2954 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2965 unsigned Immr = ShiftImm;
2967 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2968 CurDAG->getTargetConstant(Imms, dl, VT)};
2969 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2974 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2975 unsigned NumberOfIgnoredLowBits = 0,
2976 bool BiggerPattern =
false) {
2977 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2980 switch (
N->getOpcode()) {
2982 if (!
N->isMachineOpcode())
2987 NumberOfIgnoredLowBits, BiggerPattern);
2996 unsigned NOpc =
N->getMachineOpcode();
3000 case AArch64::SBFMWri:
3001 case AArch64::UBFMWri:
3002 case AArch64::SBFMXri:
3003 case AArch64::UBFMXri:
3005 Opd0 =
N->getOperand(0);
3006 Immr =
N->getConstantOperandVal(1);
3007 Imms =
N->getConstantOperandVal(2);
3014bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3015 unsigned Opc, Immr, Imms;
3020 EVT VT =
N->getValueType(0);
3025 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3026 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3027 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3029 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3030 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3036 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3037 CurDAG->getTargetConstant(Imms, dl, VT)};
3038 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3047 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3048 assert((VT == MVT::i32 || VT == MVT::i64) &&
3049 "i32 or i64 mask type expected!");
3053 APInt SignificantDstMask =
3057 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3058 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3091 APInt OpUsefulBits(UsefulBits);
3095 OpUsefulBits <<= MSB - Imm + 1;
3100 OpUsefulBits <<= Imm;
3102 OpUsefulBits <<= MSB + 1;
3105 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3111 UsefulBits &= OpUsefulBits;
3128 APInt Mask(UsefulBits);
3129 Mask.clearAllBits();
3137 Mask.lshrInPlace(ShiftAmt);
3143 Mask.lshrInPlace(ShiftAmt);
3159 APInt OpUsefulBits(UsefulBits);
3173 OpUsefulBits <<= Width;
3176 if (
Op.getOperand(1) == Orig) {
3178 Mask = ResultUsefulBits & OpUsefulBits;
3182 if (
Op.getOperand(0) == Orig)
3184 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3190 OpUsefulBits <<= Width;
3192 OpUsefulBits <<= LSB;
3194 if (
Op.getOperand(1) == Orig) {
3196 Mask = ResultUsefulBits & OpUsefulBits;
3197 Mask.lshrInPlace(LSB);
3200 if (
Op.getOperand(0) == Orig)
3201 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3218 case AArch64::ANDSWri:
3219 case AArch64::ANDSXri:
3220 case AArch64::ANDWri:
3221 case AArch64::ANDXri:
3225 case AArch64::UBFMWri:
3226 case AArch64::UBFMXri:
3229 case AArch64::ORRWrs:
3230 case AArch64::ORRXrs:
3235 case AArch64::BFMWri:
3236 case AArch64::BFMXri:
3239 case AArch64::STRBBui:
3240 case AArch64::STURBBi:
3246 case AArch64::STRHHui:
3247 case AArch64::STURHHi:
3260 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3262 UsefulBits =
APInt(Bitwidth, 0);
3271 UsersUsefulBits |= UsefulBitsForUse;
3276 UsefulBits &= UsersUsefulBits;
3286 EVT VT =
Op.getValueType();
3289 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3292 if (ShlAmount > 0) {
3295 UBFMOpc, dl, VT,
Op,
3300 assert(ShlAmount < 0 &&
"expected right shift");
3301 int ShrAmount = -ShlAmount;
3313 const uint64_t NonZeroBits,
3320 const uint64_t NonZeroBits,
3327 bool BiggerPattern,
SDValue &Src,
3328 int &DstLSB,
int &Width) {
3329 EVT VT =
Op.getValueType();
3338 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3342 switch (
Op.getOpcode()) {
3347 NonZeroBits, Src, DstLSB, Width);
3350 NonZeroBits, Src, DstLSB, Width);
3363 EVT VT =
Op.getValueType();
3364 assert((VT == MVT::i32 || VT == MVT::i64) &&
3365 "Caller guarantees VT is one of i32 or i64");
3378 assert((~AndImm & NonZeroBits) == 0 &&
3379 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3408 if (!BiggerPattern && !AndOp0.
hasOneUse())
3427 <<
"Found large Width in bit-field-positioning -- this indicates no "
3428 "proper combining / constant folding was performed\n");
3437 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3452 "Op.getNode() should be a SHL node to call this function");
3454 "Op.getNode() should shift ShlImm to call this function");
3461 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3485 EVT VT =
Op.getValueType();
3486 assert((VT == MVT::i32 || VT == MVT::i64) &&
3487 "Caller guarantees that type is i32 or i64");
3494 if (!BiggerPattern && !
Op.hasOneUse())
3503 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3511 assert(VT == MVT::i32 || VT == MVT::i64);
3522 EVT VT =
N->getValueType(0);
3523 if (VT != MVT::i32 && VT != MVT::i64)
3541 if (!
And.hasOneUse() ||
3551 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3558 if ((OrImm & NotKnownZero) != 0) {
3570 unsigned ImmS = Width - 1;
3576 bool IsBFI = LSB != 0;
3581 unsigned OrChunks = 0, BFIChunks = 0;
3582 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3583 if (((OrImm >> Shift) & 0xFFFF) != 0)
3585 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3588 if (BFIChunks > OrChunks)
3594 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3602 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3611 if (!Dst.hasOneUse())
3614 EVT VT = Dst.getValueType();
3615 assert((VT == MVT::i32 || VT == MVT::i64) &&
3616 "Caller should guarantee that VT is one of i32 or i64");
3644 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3645 unsigned MaskWidth =
3648 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3654 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3655 ShiftedOperand =
SDValue(UBFMNode, 0);
3684 const bool BiggerPattern) {
3685 EVT VT =
N->getValueType(0);
3686 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3687 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3688 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3689 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3690 assert((VT == MVT::i32 || VT == MVT::i64) &&
3691 "Expect result type to be i32 or i64 since N is combinable to BFM");
3698 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3701 if (BiggerPattern) {
3724 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3786 EVT VT =
N->getValueType(0);
3787 if (VT != MVT::i32 && VT != MVT::i64)
3795 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3796 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3816 for (
int I = 0;
I < 4; ++
I) {
3819 unsigned ImmR, ImmS;
3820 bool BiggerPattern =
I / 2;
3821 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3823 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3829 NumberOfIgnoredLowBits, BiggerPattern)) {
3832 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3833 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3838 Width = ImmS - ImmR + 1;
3849 Src, DstLSB, Width)) {
3857 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3867 APInt BitsToBeInserted =
3870 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3894 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3927 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3929 if (Src->hasOneUse() &&
3932 Src = Src->getOperand(0);
3942 unsigned ImmS = Width - 1;
3948 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3956bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3965 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3978bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3982 EVT VT =
N->getValueType(0);
3983 if (VT != MVT::i32 && VT != MVT::i64)
3989 Op0, DstLSB, Width))
3995 unsigned ImmS = Width - 1;
3998 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3999 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4000 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4001 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4007bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4008 EVT VT =
N->getValueType(0);
4011 switch (
N->getOpcode()) {
4013 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4016 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4019 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4022 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4030 if (VT == MVT::i32) {
4033 }
else if (VT == MVT::i64) {
4039 SDValue ShiftAmt =
N->getOperand(1);
4059 (Add0Imm %
Size == 0)) {
4065 if (SubVT == MVT::i32) {
4066 NegOpc = AArch64::SUBWrr;
4067 ZeroReg = AArch64::WZR;
4069 assert(SubVT == MVT::i64);
4070 NegOpc = AArch64::SUBXrr;
4071 ZeroReg = AArch64::XZR;
4074 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4075 MachineSDNode *Neg =
4076 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4077 NewShiftAmt =
SDValue(Neg, 0);
4085 if (SubVT == MVT::i32) {
4086 NotOpc = AArch64::ORNWrr;
4087 ZeroReg = AArch64::WZR;
4089 assert(SubVT == MVT::i64);
4090 NotOpc = AArch64::ORNXrr;
4091 ZeroReg = AArch64::XZR;
4094 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4095 MachineSDNode *
Not =
4096 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4097 NewShiftAmt =
SDValue(Not, 0);
4118 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4119 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4120 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4121 NewShiftAmt, SubReg);
4122 NewShiftAmt =
SDValue(Ext, 0);
4126 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4133 bool isReciprocal) {
4136 FVal = CN->getValueAPF();
4139 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4149 if (
unsigned FBits =
4162 bool isReciprocal) {
4163 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4164 N.getValueType().getScalarSizeInBits() ==
4165 N.getOperand(0).getValueType().getScalarSizeInBits())
4166 N =
N.getOperand(0);
4168 auto ImmToFloat = [RegWidth](
APInt Imm) {
4182 switch (
N->getOpcode()) {
4183 case AArch64ISD::MOVIshift:
4184 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4185 <<
N.getConstantOperandVal(1)));
4187 case AArch64ISD::FMOV:
4188 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4190 case AArch64ISD::DUP:
4192 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4200 if (
unsigned FBits =
4209bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4210 unsigned RegWidth) {
4215bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4216 unsigned RegWidth) {
4218 CurDAG,
N, FixedPos, RegWidth,
false);
4221bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(
SDValue N,
4223 unsigned RegWidth) {
4225 CurDAG,
N, FixedPos, RegWidth,
true);
4228bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4230 unsigned RegWidth) {
4240 RegString.
split(Fields,
':');
4242 if (Fields.
size() == 1)
4246 &&
"Invalid number of fields in read register string");
4249 bool AllIntFields =
true;
4253 AllIntFields &= !
Field.getAsInteger(10, IntField);
4254 Ops.push_back(IntField);
4258 "Unexpected non-integer value in special register string.");
4263 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4264 (
Ops[3] << 3) | (
Ops[4]);
4271bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4273 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4276 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4278 unsigned Opcode64Bit = AArch64::MRS;
4283 const auto *TheReg =
4284 AArch64SysReg::lookupSysRegByName(RegString->getString());
4285 if (TheReg && TheReg->Readable &&
4286 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4287 Imm = TheReg->Encoding;
4293 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4294 Opcode64Bit = AArch64::ADR;
4302 SDValue InChain =
N->getOperand(0);
4303 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4304 if (!ReadIs128Bit) {
4305 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4306 {SysRegImm, InChain});
4308 SDNode *MRRS = CurDAG->getMachineNode(
4310 {MVT::Untyped , MVT::Other },
4311 {SysRegImm, InChain});
4315 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4317 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4323 ReplaceUses(
SDValue(
N, 2), OutChain);
4332bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4334 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4337 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4339 if (!WriteIs128Bit) {
4345 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4348 "Expected a constant integer expression.");
4349 unsigned Reg = PMapper->Encoding;
4350 uint64_t Immed =
N->getConstantOperandVal(2);
4351 CurDAG->SelectNodeTo(
4352 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4353 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4359 if (trySelectPState(
4360 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4361 AArch64::MSRpstateImm4))
4363 if (trySelectPState(
4364 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4365 AArch64::MSRpstateImm1))
4374 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4375 if (TheReg && TheReg->Writeable &&
4376 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4377 Imm = TheReg->Encoding;
4386 if (!WriteIs128Bit) {
4387 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4388 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4389 N->getOperand(2), InChain);
4393 SDNode *Pair = CurDAG->getMachineNode(
4394 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4395 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4398 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4400 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4402 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4403 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4411bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4416 if (Subtarget->hasLSE())
return false;
4418 if (MemTy == MVT::i8)
4419 Opcode = AArch64::CMP_SWAP_8;
4420 else if (MemTy == MVT::i16)
4421 Opcode = AArch64::CMP_SWAP_16;
4422 else if (MemTy == MVT::i32)
4423 Opcode = AArch64::CMP_SWAP_32;
4424 else if (MemTy == MVT::i64)
4425 Opcode = AArch64::CMP_SWAP_64;
4429 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4430 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4432 SDNode *CmpSwap = CurDAG->getMachineNode(
4434 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4441 CurDAG->RemoveDeadNode(
N);
4446bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4447 SDValue &Shift,
bool Negate) {
4454 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4457bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4466 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4473 if ((Val & ~0xff) == 0) {
4474 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4479 if ((Val & ~0xff00) == 0) {
4480 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4492bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4516 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4517 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4524 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4525 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4529 if (Val <= 65280 && Val % 256 == 0) {
4530 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4531 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4542bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4552 int32_t ImmVal, ShiftVal;
4557 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4558 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4562bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4564 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4568bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4571 if (ImmVal >= -128 && ImmVal < 128) {
4572 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4578bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4580 uint64_t ImmVal = CNode->getZExtValue();
4590 ImmVal &= 0xFFFFFFFF;
4599 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4606bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4610 ImmVal = CI->getZExtValue();
4612 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4623 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4632bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4633 uint64_t
High,
bool AllowSaturation,
4636 uint64_t ImmVal = CN->getZExtValue();
4643 if (ImmVal >
High) {
4644 if (!AllowSaturation)
4649 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4656bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4670 const TargetLowering *TLI = getTargetLowering();
4673 SDValue FiOp = CurDAG->getTargetFrameIndex(
4675 int TagOffset =
N->getConstantOperandVal(3);
4677 SDNode *Out = CurDAG->getMachineNode(
4678 AArch64::TAGPstack,
DL, MVT::i64,
4679 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4680 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4681 ReplaceNode(
N, Out);
4685void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4687 "llvm.aarch64.tagp third argument must be an immediate");
4688 if (trySelectStackSlotTagP(
N))
4695 int TagOffset =
N->getConstantOperandVal(3);
4696 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4697 {
N->getOperand(1),
N->getOperand(2)});
4698 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4699 {
SDValue(N1, 0),
N->getOperand(2)});
4700 SDNode *N3 = CurDAG->getMachineNode(
4701 AArch64::ADDG,
DL, MVT::i64,
4702 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4703 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4707bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4711 if (
N->getConstantOperandVal(2) != 0)
4713 if (!
N->getOperand(0).isUndef())
4717 EVT VT =
N->getValueType(0);
4718 EVT InVT =
N->getOperand(1).getValueType();
4729 "Expected to insert into a packed scalable vector!");
4732 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4733 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4734 N->getOperand(1), RC));
4738bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4742 if (
N->getConstantOperandVal(1) != 0)
4746 EVT VT =
N->getValueType(0);
4747 EVT InVT =
N->getOperand(0).getValueType();
4758 "Expected to extract from a packed scalable vector!");
4761 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4762 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4763 N->getOperand(0), RC));
4767bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4773 EVT VT =
N->getValueType(0);
4786 (Subtarget->hasSVE2() ||
4787 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4788 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4791 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4795 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4796 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4797 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4804 bool IsXOROperand =
true;
4806 IsXOROperand =
false;
4812 APInt ShlAmt, ShrAmt;
4820 if (!IsXOROperand) {
4822 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4825 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4826 SDNode *SubRegToReg =
4827 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4838 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4839 AArch64::XAR_ZZZI_D})) {
4840 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4865 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4875 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4883 bool IsXOROperand =
true;
4885 IsXOROperand =
false;
4888 R1 =
XOR.getOperand(0);
4889 R2 =
XOR.getOperand(1);
4899 if (ShAmt + HsAmt != VTSizeInBits)
4902 if (!IsXOROperand) {
4905 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4914 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4920 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4921 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4923 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4926 if (
R2.getValueType() == VT)
4927 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4932 SDValue SubReg = CurDAG->getTargetConstant(
4935 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4940 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4946 SDNode *XAR =
nullptr;
4950 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4951 AArch64::XAR_ZZZI_D}))
4952 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4954 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4957 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4963 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4964 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4967 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4968 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4971 SDValue SubReg = CurDAG->getTargetConstant(
4974 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4978 ReplaceNode(
N, XAR);
4982void AArch64DAGToDAGISel::Select(SDNode *Node) {
4984 if (
Node->isMachineOpcode()) {
4986 Node->setNodeId(-1);
4991 EVT VT =
Node->getValueType(0);
4993 switch (
Node->getOpcode()) {
4998 if (SelectCMP_SWAP(Node))
5003 case AArch64ISD::MRRS:
5004 if (tryReadRegister(Node))
5009 case AArch64ISD::MSRR:
5010 if (tryWriteRegister(Node))
5017 if (tryIndexedLoad(Node))
5026 if (tryBitfieldExtractOp(Node))
5028 if (tryBitfieldInsertInZeroOp(Node))
5033 if (tryShiftAmountMod(Node))
5038 if (tryBitfieldExtractOpFromSExt(Node))
5043 if (tryBitfieldInsertOp(Node))
5045 if (trySelectXAR(Node))
5050 if (trySelectCastScalableToFixedLengthVector(Node))
5056 if (trySelectCastFixedLengthToScalableVector(Node))
5065 if (ConstNode->
isZero()) {
5066 if (VT == MVT::i32) {
5068 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5069 ReplaceNode(Node,
New.getNode());
5071 }
else if (VT == MVT::i64) {
5073 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5074 ReplaceNode(Node,
New.getNode());
5085 const TargetLowering *TLI = getTargetLowering();
5086 SDValue TFI = CurDAG->getTargetFrameIndex(
5089 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5090 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5091 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5095 unsigned IntNo =
Node->getConstantOperandVal(1);
5099 case Intrinsic::aarch64_gcsss: {
5103 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5105 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5106 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5107 MVT::Other, Zero,
SDValue(SS1, 0));
5108 ReplaceNode(Node, SS2);
5111 case Intrinsic::aarch64_ldaxp:
5112 case Intrinsic::aarch64_ldxp: {
5114 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5119 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5120 MVT::Other, MemAddr, Chain);
5123 MachineMemOperand *MemOp =
5126 ReplaceNode(Node, Ld);
5129 case Intrinsic::aarch64_stlxp:
5130 case Intrinsic::aarch64_stxp: {
5132 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5140 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5142 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5144 MachineMemOperand *MemOp =
5148 ReplaceNode(Node, St);
5151 case Intrinsic::aarch64_neon_ld1x2:
5152 if (VT == MVT::v8i8) {
5153 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5155 }
else if (VT == MVT::v16i8) {
5156 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5158 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5159 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5161 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5162 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5164 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5165 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5167 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5168 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5170 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5171 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5173 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5174 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5178 case Intrinsic::aarch64_neon_ld1x3:
5179 if (VT == MVT::v8i8) {
5180 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5182 }
else if (VT == MVT::v16i8) {
5183 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5185 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5186 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5188 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5189 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5191 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5192 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5194 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5195 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5197 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5198 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5200 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5201 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5205 case Intrinsic::aarch64_neon_ld1x4:
5206 if (VT == MVT::v8i8) {
5207 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5209 }
else if (VT == MVT::v16i8) {
5210 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5212 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5213 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5215 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5216 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5218 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5219 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5221 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5222 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5224 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5225 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5227 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5228 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5232 case Intrinsic::aarch64_neon_ld2:
5233 if (VT == MVT::v8i8) {
5234 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5236 }
else if (VT == MVT::v16i8) {
5237 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5239 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5240 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5242 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5243 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5245 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5246 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5248 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5249 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5251 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5252 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5254 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5255 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5259 case Intrinsic::aarch64_neon_ld3:
5260 if (VT == MVT::v8i8) {
5261 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5263 }
else if (VT == MVT::v16i8) {
5264 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5266 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5267 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5269 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5270 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5272 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5273 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5275 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5276 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5278 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5279 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5281 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5282 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5286 case Intrinsic::aarch64_neon_ld4:
5287 if (VT == MVT::v8i8) {
5288 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5290 }
else if (VT == MVT::v16i8) {
5291 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5293 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5294 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5296 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5297 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5299 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5300 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5302 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5303 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5305 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5306 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5308 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5309 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5313 case Intrinsic::aarch64_neon_ld2r:
5314 if (VT == MVT::v8i8) {
5315 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5317 }
else if (VT == MVT::v16i8) {
5318 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5320 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5321 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5323 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5324 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5326 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5327 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5329 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5330 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5332 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5333 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5335 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5336 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5340 case Intrinsic::aarch64_neon_ld3r:
5341 if (VT == MVT::v8i8) {
5342 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5344 }
else if (VT == MVT::v16i8) {
5345 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5347 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5348 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5350 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5351 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5353 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5354 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5356 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5357 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5359 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5360 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5362 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5363 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5367 case Intrinsic::aarch64_neon_ld4r:
5368 if (VT == MVT::v8i8) {
5369 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5371 }
else if (VT == MVT::v16i8) {
5372 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5374 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5375 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5377 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5378 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5380 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5381 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5383 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5384 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5386 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5387 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5389 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5390 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5394 case Intrinsic::aarch64_neon_ld2lane:
5395 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5396 SelectLoadLane(Node, 2, AArch64::LD2i8);
5398 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5399 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5400 SelectLoadLane(Node, 2, AArch64::LD2i16);
5402 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5404 SelectLoadLane(Node, 2, AArch64::LD2i32);
5406 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5408 SelectLoadLane(Node, 2, AArch64::LD2i64);
5412 case Intrinsic::aarch64_neon_ld3lane:
5413 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5414 SelectLoadLane(Node, 3, AArch64::LD3i8);
5416 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5417 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5418 SelectLoadLane(Node, 3, AArch64::LD3i16);
5420 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5422 SelectLoadLane(Node, 3, AArch64::LD3i32);
5424 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5426 SelectLoadLane(Node, 3, AArch64::LD3i64);
5430 case Intrinsic::aarch64_neon_ld4lane:
5431 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5432 SelectLoadLane(Node, 4, AArch64::LD4i8);
5434 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5435 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5436 SelectLoadLane(Node, 4, AArch64::LD4i16);
5438 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5440 SelectLoadLane(Node, 4, AArch64::LD4i32);
5442 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5444 SelectLoadLane(Node, 4, AArch64::LD4i64);
5448 case Intrinsic::aarch64_ld64b:
5449 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5451 case Intrinsic::aarch64_sve_ld2q_sret: {
5452 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5455 case Intrinsic::aarch64_sve_ld3q_sret: {
5456 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5459 case Intrinsic::aarch64_sve_ld4q_sret: {
5460 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5463 case Intrinsic::aarch64_sve_ld2_sret: {
5464 if (VT == MVT::nxv16i8) {
5465 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5468 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5469 VT == MVT::nxv8bf16) {
5470 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5473 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5474 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5477 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5478 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5484 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5485 if (VT == MVT::nxv16i8) {
5486 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5487 SelectContiguousMultiVectorLoad(
5488 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5489 else if (Subtarget->hasSVE2p1())
5490 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5495 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5496 VT == MVT::nxv8bf16) {
5497 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5498 SelectContiguousMultiVectorLoad(
5499 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5500 else if (Subtarget->hasSVE2p1())
5501 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5506 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5507 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5508 SelectContiguousMultiVectorLoad(
5509 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5510 else if (Subtarget->hasSVE2p1())
5511 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5516 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5517 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5518 SelectContiguousMultiVectorLoad(
5519 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5520 else if (Subtarget->hasSVE2p1())
5521 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5529 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5530 if (VT == MVT::nxv16i8) {
5531 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5532 SelectContiguousMultiVectorLoad(
5533 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5534 else if (Subtarget->hasSVE2p1())
5535 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5540 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5541 VT == MVT::nxv8bf16) {
5542 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5543 SelectContiguousMultiVectorLoad(
5544 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5545 else if (Subtarget->hasSVE2p1())
5546 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5551 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5552 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5553 SelectContiguousMultiVectorLoad(
5554 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5555 else if (Subtarget->hasSVE2p1())
5556 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5561 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5562 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5563 SelectContiguousMultiVectorLoad(
5564 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5565 else if (Subtarget->hasSVE2p1())
5566 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5574 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5575 if (VT == MVT::nxv16i8) {
5576 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5577 SelectContiguousMultiVectorLoad(Node, 2, 0,
5578 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5579 AArch64::LDNT1B_2Z_PSEUDO);
5580 else if (Subtarget->hasSVE2p1())
5581 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5582 AArch64::LDNT1B_2Z);
5586 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5587 VT == MVT::nxv8bf16) {
5588 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5589 SelectContiguousMultiVectorLoad(Node, 2, 1,
5590 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5591 AArch64::LDNT1H_2Z_PSEUDO);
5592 else if (Subtarget->hasSVE2p1())
5593 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5594 AArch64::LDNT1H_2Z);
5598 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5599 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5600 SelectContiguousMultiVectorLoad(Node, 2, 2,
5601 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5602 AArch64::LDNT1W_2Z_PSEUDO);
5603 else if (Subtarget->hasSVE2p1())
5604 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5605 AArch64::LDNT1W_2Z);
5609 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5610 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5611 SelectContiguousMultiVectorLoad(Node, 2, 3,
5612 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5613 AArch64::LDNT1D_2Z_PSEUDO);
5614 else if (Subtarget->hasSVE2p1())
5615 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5616 AArch64::LDNT1D_2Z);
5623 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5624 if (VT == MVT::nxv16i8) {
5625 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5626 SelectContiguousMultiVectorLoad(Node, 4, 0,
5627 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5628 AArch64::LDNT1B_4Z_PSEUDO);
5629 else if (Subtarget->hasSVE2p1())
5630 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5631 AArch64::LDNT1B_4Z);
5635 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5636 VT == MVT::nxv8bf16) {
5637 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5638 SelectContiguousMultiVectorLoad(Node, 4, 1,
5639 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5640 AArch64::LDNT1H_4Z_PSEUDO);
5641 else if (Subtarget->hasSVE2p1())
5642 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5643 AArch64::LDNT1H_4Z);
5647 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5648 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5649 SelectContiguousMultiVectorLoad(Node, 4, 2,
5650 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5651 AArch64::LDNT1W_4Z_PSEUDO);
5652 else if (Subtarget->hasSVE2p1())
5653 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5654 AArch64::LDNT1W_4Z);
5658 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5659 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5660 SelectContiguousMultiVectorLoad(Node, 4, 3,
5661 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5662 AArch64::LDNT1D_4Z_PSEUDO);
5663 else if (Subtarget->hasSVE2p1())
5664 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5665 AArch64::LDNT1D_4Z);
5672 case Intrinsic::aarch64_sve_ld3_sret: {
5673 if (VT == MVT::nxv16i8) {
5674 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5677 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5678 VT == MVT::nxv8bf16) {
5679 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5682 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5683 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5686 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5687 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5693 case Intrinsic::aarch64_sve_ld4_sret: {
5694 if (VT == MVT::nxv16i8) {
5695 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5698 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5699 VT == MVT::nxv8bf16) {
5700 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5703 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5704 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5707 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5708 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5714 case Intrinsic::aarch64_sme_read_hor_vg2: {
5715 if (VT == MVT::nxv16i8) {
5716 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5717 AArch64::MOVA_2ZMXI_H_B);
5719 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5720 VT == MVT::nxv8bf16) {
5721 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5722 AArch64::MOVA_2ZMXI_H_H);
5724 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5725 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5726 AArch64::MOVA_2ZMXI_H_S);
5728 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5729 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5730 AArch64::MOVA_2ZMXI_H_D);
5735 case Intrinsic::aarch64_sme_read_ver_vg2: {
5736 if (VT == MVT::nxv16i8) {
5737 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5738 AArch64::MOVA_2ZMXI_V_B);
5740 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5741 VT == MVT::nxv8bf16) {
5742 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5743 AArch64::MOVA_2ZMXI_V_H);
5745 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5746 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5747 AArch64::MOVA_2ZMXI_V_S);
5749 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5750 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5751 AArch64::MOVA_2ZMXI_V_D);
5756 case Intrinsic::aarch64_sme_read_hor_vg4: {
5757 if (VT == MVT::nxv16i8) {
5758 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5759 AArch64::MOVA_4ZMXI_H_B);
5761 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5762 VT == MVT::nxv8bf16) {
5763 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5764 AArch64::MOVA_4ZMXI_H_H);
5766 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5767 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5768 AArch64::MOVA_4ZMXI_H_S);
5770 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5771 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5772 AArch64::MOVA_4ZMXI_H_D);
5777 case Intrinsic::aarch64_sme_read_ver_vg4: {
5778 if (VT == MVT::nxv16i8) {
5779 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5780 AArch64::MOVA_4ZMXI_V_B);
5782 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5783 VT == MVT::nxv8bf16) {
5784 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5785 AArch64::MOVA_4ZMXI_V_H);
5787 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5788 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5789 AArch64::MOVA_4ZMXI_V_S);
5791 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5792 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5793 AArch64::MOVA_4ZMXI_V_D);
5798 case Intrinsic::aarch64_sme_read_vg1x2: {
5799 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5800 AArch64::MOVA_VG2_2ZMXI);
5803 case Intrinsic::aarch64_sme_read_vg1x4: {
5804 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5805 AArch64::MOVA_VG4_4ZMXI);
5808 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5809 if (VT == MVT::nxv16i8) {
5810 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5812 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5813 VT == MVT::nxv8bf16) {
5814 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5816 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5817 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5819 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5820 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5825 case Intrinsic::aarch64_sme_readz_vert_x2: {
5826 if (VT == MVT::nxv16i8) {
5827 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5829 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5830 VT == MVT::nxv8bf16) {
5831 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5833 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5834 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5836 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5837 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5842 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5843 if (VT == MVT::nxv16i8) {
5844 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5846 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5847 VT == MVT::nxv8bf16) {
5848 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5850 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5851 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5853 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5854 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5859 case Intrinsic::aarch64_sme_readz_vert_x4: {
5860 if (VT == MVT::nxv16i8) {
5861 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5863 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5864 VT == MVT::nxv8bf16) {
5865 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5867 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5868 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5870 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5871 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5876 case Intrinsic::aarch64_sme_readz_x2: {
5877 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5881 case Intrinsic::aarch64_sme_readz_x4: {
5882 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5886 case Intrinsic::swift_async_context_addr: {
5889 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5891 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5892 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5893 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5895 ReplaceUses(
SDValue(Node, 0), Res);
5897 CurDAG->RemoveDeadNode(Node);
5899 auto &MF = CurDAG->getMachineFunction();
5900 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5901 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5904 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5906 Node->getValueType(0),
5907 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5908 AArch64::LUTI2_4ZTZI_S}))
5910 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5913 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5915 Node->getValueType(0),
5916 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5918 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5921 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5923 Node->getValueType(0),
5924 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5925 AArch64::LUTI2_2ZTZI_S}))
5927 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5930 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5932 Node->getValueType(0),
5933 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5934 AArch64::LUTI4_2ZTZI_S}))
5936 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5939 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5940 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5943 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5945 Node->getValueType(0),
5946 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5947 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5949 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5951 Node->getValueType(0),
5952 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5953 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5955 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5957 Node->getValueType(0),
5958 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5959 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5961 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5963 Node->getValueType(0),
5964 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5965 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5967 case Intrinsic::ptrauth_resign_load_relative:
5968 SelectPtrauthResign(Node);
5973 unsigned IntNo =
Node->getConstantOperandVal(0);
5977 case Intrinsic::aarch64_tagp:
5981 case Intrinsic::ptrauth_auth:
5982 SelectPtrauthAuth(Node);
5985 case Intrinsic::ptrauth_resign:
5986 SelectPtrauthResign(Node);
5989 case Intrinsic::aarch64_neon_tbl2:
5990 SelectTable(Node, 2,
5991 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5994 case Intrinsic::aarch64_neon_tbl3:
5995 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5996 : AArch64::TBLv16i8Three,
5999 case Intrinsic::aarch64_neon_tbl4:
6000 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6001 : AArch64::TBLv16i8Four,
6004 case Intrinsic::aarch64_neon_tbx2:
6005 SelectTable(Node, 2,
6006 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6009 case Intrinsic::aarch64_neon_tbx3:
6010 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6011 : AArch64::TBXv16i8Three,
6014 case Intrinsic::aarch64_neon_tbx4:
6015 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6016 : AArch64::TBXv16i8Four,
6019 case Intrinsic::aarch64_sve_srshl_single_x2:
6021 Node->getValueType(0),
6022 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6023 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6024 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6026 case Intrinsic::aarch64_sve_srshl_single_x4:
6028 Node->getValueType(0),
6029 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6030 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6031 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6033 case Intrinsic::aarch64_sve_urshl_single_x2:
6035 Node->getValueType(0),
6036 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6037 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6038 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6040 case Intrinsic::aarch64_sve_urshl_single_x4:
6042 Node->getValueType(0),
6043 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6044 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6045 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6047 case Intrinsic::aarch64_sve_srshl_x2:
6049 Node->getValueType(0),
6050 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6051 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6052 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6054 case Intrinsic::aarch64_sve_srshl_x4:
6056 Node->getValueType(0),
6057 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6058 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6059 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6061 case Intrinsic::aarch64_sve_urshl_x2:
6063 Node->getValueType(0),
6064 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6065 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6066 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6068 case Intrinsic::aarch64_sve_urshl_x4:
6070 Node->getValueType(0),
6071 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6072 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6073 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6075 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6077 Node->getValueType(0),
6078 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6079 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6080 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6082 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6084 Node->getValueType(0),
6085 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6086 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6087 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6089 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6091 Node->getValueType(0),
6092 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6093 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6094 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6096 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6098 Node->getValueType(0),
6099 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6100 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6101 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6103 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6105 Node->getValueType(0),
6106 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6107 AArch64::FSCALE_2ZZ_D}))
6108 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6110 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6112 Node->getValueType(0),
6113 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6114 AArch64::FSCALE_4ZZ_D}))
6115 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6117 case Intrinsic::aarch64_sme_fp8_scale_x2:
6119 Node->getValueType(0),
6120 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6121 AArch64::FSCALE_2Z2Z_D}))
6122 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6124 case Intrinsic::aarch64_sme_fp8_scale_x4:
6126 Node->getValueType(0),
6127 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6128 AArch64::FSCALE_4Z4Z_D}))
6129 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6131 case Intrinsic::aarch64_sve_whilege_x2:
6133 Node->getValueType(0),
6134 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6135 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6136 SelectWhilePair(Node,
Op);
6138 case Intrinsic::aarch64_sve_whilegt_x2:
6140 Node->getValueType(0),
6141 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6142 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6143 SelectWhilePair(Node,
Op);
6145 case Intrinsic::aarch64_sve_whilehi_x2:
6147 Node->getValueType(0),
6148 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6149 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6150 SelectWhilePair(Node,
Op);
6152 case Intrinsic::aarch64_sve_whilehs_x2:
6154 Node->getValueType(0),
6155 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6156 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6157 SelectWhilePair(Node,
Op);
6159 case Intrinsic::aarch64_sve_whilele_x2:
6161 Node->getValueType(0),
6162 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6163 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6164 SelectWhilePair(Node,
Op);
6166 case Intrinsic::aarch64_sve_whilelo_x2:
6168 Node->getValueType(0),
6169 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6170 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6171 SelectWhilePair(Node,
Op);
6173 case Intrinsic::aarch64_sve_whilels_x2:
6175 Node->getValueType(0),
6176 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6177 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6178 SelectWhilePair(Node,
Op);
6180 case Intrinsic::aarch64_sve_whilelt_x2:
6182 Node->getValueType(0),
6183 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6184 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6185 SelectWhilePair(Node,
Op);
6187 case Intrinsic::aarch64_sve_smax_single_x2:
6189 Node->getValueType(0),
6190 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6191 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6192 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6194 case Intrinsic::aarch64_sve_umax_single_x2:
6196 Node->getValueType(0),
6197 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6198 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6199 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6201 case Intrinsic::aarch64_sve_fmax_single_x2:
6203 Node->getValueType(0),
6204 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6205 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6206 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6208 case Intrinsic::aarch64_sve_smax_single_x4:
6210 Node->getValueType(0),
6211 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6212 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6213 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6215 case Intrinsic::aarch64_sve_umax_single_x4:
6217 Node->getValueType(0),
6218 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6219 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6220 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6222 case Intrinsic::aarch64_sve_fmax_single_x4:
6224 Node->getValueType(0),
6225 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6226 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6227 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6229 case Intrinsic::aarch64_sve_smin_single_x2:
6231 Node->getValueType(0),
6232 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6233 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6234 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6236 case Intrinsic::aarch64_sve_umin_single_x2:
6238 Node->getValueType(0),
6239 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6240 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6241 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6243 case Intrinsic::aarch64_sve_fmin_single_x2:
6245 Node->getValueType(0),
6246 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6247 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6248 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6250 case Intrinsic::aarch64_sve_smin_single_x4:
6252 Node->getValueType(0),
6253 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6254 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6255 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6257 case Intrinsic::aarch64_sve_umin_single_x4:
6259 Node->getValueType(0),
6260 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6261 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6262 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6264 case Intrinsic::aarch64_sve_fmin_single_x4:
6266 Node->getValueType(0),
6267 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6268 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6269 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6271 case Intrinsic::aarch64_sve_smax_x2:
6273 Node->getValueType(0),
6274 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6275 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6276 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6278 case Intrinsic::aarch64_sve_umax_x2:
6280 Node->getValueType(0),
6281 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6282 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6283 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6285 case Intrinsic::aarch64_sve_fmax_x2:
6287 Node->getValueType(0),
6288 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6289 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6290 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6292 case Intrinsic::aarch64_sve_smax_x4:
6294 Node->getValueType(0),
6295 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6296 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6297 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6299 case Intrinsic::aarch64_sve_umax_x4:
6301 Node->getValueType(0),
6302 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6303 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6304 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6306 case Intrinsic::aarch64_sve_fmax_x4:
6308 Node->getValueType(0),
6309 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6310 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6311 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6313 case Intrinsic::aarch64_sme_famax_x2:
6315 Node->getValueType(0),
6316 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6317 AArch64::FAMAX_2Z2Z_D}))
6318 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6320 case Intrinsic::aarch64_sme_famax_x4:
6322 Node->getValueType(0),
6323 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6324 AArch64::FAMAX_4Z4Z_D}))
6325 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6327 case Intrinsic::aarch64_sme_famin_x2:
6329 Node->getValueType(0),
6330 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6331 AArch64::FAMIN_2Z2Z_D}))
6332 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6334 case Intrinsic::aarch64_sme_famin_x4:
6336 Node->getValueType(0),
6337 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6338 AArch64::FAMIN_4Z4Z_D}))
6339 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6341 case Intrinsic::aarch64_sve_smin_x2:
6343 Node->getValueType(0),
6344 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6345 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6346 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6348 case Intrinsic::aarch64_sve_umin_x2:
6350 Node->getValueType(0),
6351 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6352 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6353 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6355 case Intrinsic::aarch64_sve_fmin_x2:
6357 Node->getValueType(0),
6358 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6359 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6360 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6362 case Intrinsic::aarch64_sve_smin_x4:
6364 Node->getValueType(0),
6365 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6366 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6367 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6369 case Intrinsic::aarch64_sve_umin_x4:
6371 Node->getValueType(0),
6372 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6373 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6374 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6376 case Intrinsic::aarch64_sve_fmin_x4:
6378 Node->getValueType(0),
6379 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6380 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6381 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6383 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6385 Node->getValueType(0),
6386 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6387 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6388 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6390 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6392 Node->getValueType(0),
6393 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6394 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6395 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6397 case Intrinsic::aarch64_sve_fminnm_single_x2:
6399 Node->getValueType(0),
6400 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6401 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6402 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6404 case Intrinsic::aarch64_sve_fminnm_single_x4:
6406 Node->getValueType(0),
6407 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6408 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6409 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6411 case Intrinsic::aarch64_sve_fscale_single_x4:
6412 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6414 case Intrinsic::aarch64_sve_fscale_single_x2:
6415 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6417 case Intrinsic::aarch64_sve_fmul_single_x4:
6419 Node->getValueType(0),
6420 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6421 AArch64::FMUL_4ZZ_D}))
6422 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6424 case Intrinsic::aarch64_sve_fmul_single_x2:
6426 Node->getValueType(0),
6427 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6428 AArch64::FMUL_2ZZ_D}))
6429 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6431 case Intrinsic::aarch64_sve_fmaxnm_x2:
6433 Node->getValueType(0),
6434 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6435 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6436 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6438 case Intrinsic::aarch64_sve_fmaxnm_x4:
6440 Node->getValueType(0),
6441 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6442 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6443 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6445 case Intrinsic::aarch64_sve_fminnm_x2:
6447 Node->getValueType(0),
6448 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6449 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6450 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6452 case Intrinsic::aarch64_sve_fminnm_x4:
6454 Node->getValueType(0),
6455 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6456 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6457 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6459 case Intrinsic::aarch64_sve_aese_lane_x2:
6460 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6462 case Intrinsic::aarch64_sve_aesd_lane_x2:
6463 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6465 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6466 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6468 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6469 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6471 case Intrinsic::aarch64_sve_aese_lane_x4:
6472 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6474 case Intrinsic::aarch64_sve_aesd_lane_x4:
6475 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6477 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6478 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6480 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6481 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6483 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6484 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6486 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6490 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6492 for (
unsigned I = 0;
I < 2;
I++)
6494 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6496 CurDAG->RemoveDeadNode(Node);
6499 case Intrinsic::aarch64_sve_fscale_x4:
6500 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6502 case Intrinsic::aarch64_sve_fscale_x2:
6503 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6505 case Intrinsic::aarch64_sve_fmul_x4:
6507 Node->getValueType(0),
6508 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6509 AArch64::FMUL_4Z4Z_D}))
6510 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6512 case Intrinsic::aarch64_sve_fmul_x2:
6514 Node->getValueType(0),
6515 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6516 AArch64::FMUL_2Z2Z_D}))
6517 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6519 case Intrinsic::aarch64_sve_fcvtzs_x2:
6520 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6522 case Intrinsic::aarch64_sve_scvtf_x2:
6523 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6525 case Intrinsic::aarch64_sve_fcvtzu_x2:
6526 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6528 case Intrinsic::aarch64_sve_ucvtf_x2:
6529 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6531 case Intrinsic::aarch64_sve_fcvtzs_x4:
6532 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6534 case Intrinsic::aarch64_sve_scvtf_x4:
6535 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6537 case Intrinsic::aarch64_sve_fcvtzu_x4:
6538 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6540 case Intrinsic::aarch64_sve_ucvtf_x4:
6541 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6543 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6544 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6546 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6547 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6549 case Intrinsic::aarch64_sve_sclamp_single_x2:
6551 Node->getValueType(0),
6552 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6553 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6554 SelectClamp(Node, 2,
Op);
6556 case Intrinsic::aarch64_sve_uclamp_single_x2:
6558 Node->getValueType(0),
6559 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6560 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6561 SelectClamp(Node, 2,
Op);
6563 case Intrinsic::aarch64_sve_fclamp_single_x2:
6565 Node->getValueType(0),
6566 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6567 AArch64::FCLAMP_VG2_2Z2Z_D}))
6568 SelectClamp(Node, 2,
Op);
6570 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6571 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6573 case Intrinsic::aarch64_sve_sclamp_single_x4:
6575 Node->getValueType(0),
6576 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6577 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6578 SelectClamp(Node, 4,
Op);
6580 case Intrinsic::aarch64_sve_uclamp_single_x4:
6582 Node->getValueType(0),
6583 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6584 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6585 SelectClamp(Node, 4,
Op);
6587 case Intrinsic::aarch64_sve_fclamp_single_x4:
6589 Node->getValueType(0),
6590 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6591 AArch64::FCLAMP_VG4_4Z4Z_D}))
6592 SelectClamp(Node, 4,
Op);
6594 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6595 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6597 case Intrinsic::aarch64_sve_add_single_x2:
6599 Node->getValueType(0),
6600 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6601 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6602 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6604 case Intrinsic::aarch64_sve_add_single_x4:
6606 Node->getValueType(0),
6607 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6608 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6609 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6611 case Intrinsic::aarch64_sve_zip_x2:
6613 Node->getValueType(0),
6614 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6615 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6616 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6618 case Intrinsic::aarch64_sve_zipq_x2:
6619 SelectUnaryMultiIntrinsic(Node, 2,
false,
6620 AArch64::ZIP_VG2_2ZZZ_Q);
6622 case Intrinsic::aarch64_sve_zip_x4:
6624 Node->getValueType(0),
6625 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6626 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6627 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6629 case Intrinsic::aarch64_sve_zipq_x4:
6630 SelectUnaryMultiIntrinsic(Node, 4,
true,
6631 AArch64::ZIP_VG4_4Z4Z_Q);
6633 case Intrinsic::aarch64_sve_uzp_x2:
6635 Node->getValueType(0),
6636 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6637 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6638 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6640 case Intrinsic::aarch64_sve_uzpq_x2:
6641 SelectUnaryMultiIntrinsic(Node, 2,
false,
6642 AArch64::UZP_VG2_2ZZZ_Q);
6644 case Intrinsic::aarch64_sve_uzp_x4:
6646 Node->getValueType(0),
6647 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6648 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6649 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6651 case Intrinsic::aarch64_sve_uzpq_x4:
6652 SelectUnaryMultiIntrinsic(Node, 4,
true,
6653 AArch64::UZP_VG4_4Z4Z_Q);
6655 case Intrinsic::aarch64_sve_sel_x2:
6657 Node->getValueType(0),
6658 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6659 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6660 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6662 case Intrinsic::aarch64_sve_sel_x4:
6664 Node->getValueType(0),
6665 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6666 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6667 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6669 case Intrinsic::aarch64_sve_frinta_x2:
6670 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6672 case Intrinsic::aarch64_sve_frinta_x4:
6673 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6675 case Intrinsic::aarch64_sve_frintm_x2:
6676 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6678 case Intrinsic::aarch64_sve_frintm_x4:
6679 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6681 case Intrinsic::aarch64_sve_frintn_x2:
6682 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6684 case Intrinsic::aarch64_sve_frintn_x4:
6685 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6687 case Intrinsic::aarch64_sve_frintp_x2:
6688 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6690 case Intrinsic::aarch64_sve_frintp_x4:
6691 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6693 case Intrinsic::aarch64_sve_sunpk_x2:
6695 Node->getValueType(0),
6696 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6697 AArch64::SUNPK_VG2_2ZZ_D}))
6698 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6700 case Intrinsic::aarch64_sve_uunpk_x2:
6702 Node->getValueType(0),
6703 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6704 AArch64::UUNPK_VG2_2ZZ_D}))
6705 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6707 case Intrinsic::aarch64_sve_sunpk_x4:
6709 Node->getValueType(0),
6710 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6711 AArch64::SUNPK_VG4_4Z2Z_D}))
6712 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6714 case Intrinsic::aarch64_sve_uunpk_x4:
6716 Node->getValueType(0),
6717 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6718 AArch64::UUNPK_VG4_4Z2Z_D}))
6719 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6721 case Intrinsic::aarch64_sve_pext_x2: {
6723 Node->getValueType(0),
6724 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6725 AArch64::PEXT_2PCI_D}))
6726 SelectPExtPair(Node,
Op);
6733 unsigned IntNo =
Node->getConstantOperandVal(1);
6734 if (
Node->getNumOperands() >= 3)
6735 VT =
Node->getOperand(2)->getValueType(0);
6739 case Intrinsic::aarch64_neon_st1x2: {
6740 if (VT == MVT::v8i8) {
6741 SelectStore(Node, 2, AArch64::ST1Twov8b);
6743 }
else if (VT == MVT::v16i8) {
6744 SelectStore(Node, 2, AArch64::ST1Twov16b);
6746 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6747 VT == MVT::v4bf16) {
6748 SelectStore(Node, 2, AArch64::ST1Twov4h);
6750 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6751 VT == MVT::v8bf16) {
6752 SelectStore(Node, 2, AArch64::ST1Twov8h);
6754 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6755 SelectStore(Node, 2, AArch64::ST1Twov2s);
6757 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6758 SelectStore(Node, 2, AArch64::ST1Twov4s);
6760 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6761 SelectStore(Node, 2, AArch64::ST1Twov2d);
6763 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6764 SelectStore(Node, 2, AArch64::ST1Twov1d);
6769 case Intrinsic::aarch64_neon_st1x3: {
6770 if (VT == MVT::v8i8) {
6771 SelectStore(Node, 3, AArch64::ST1Threev8b);
6773 }
else if (VT == MVT::v16i8) {
6774 SelectStore(Node, 3, AArch64::ST1Threev16b);
6776 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6777 VT == MVT::v4bf16) {
6778 SelectStore(Node, 3, AArch64::ST1Threev4h);
6780 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6781 VT == MVT::v8bf16) {
6782 SelectStore(Node, 3, AArch64::ST1Threev8h);
6784 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6785 SelectStore(Node, 3, AArch64::ST1Threev2s);
6787 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6788 SelectStore(Node, 3, AArch64::ST1Threev4s);
6790 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6791 SelectStore(Node, 3, AArch64::ST1Threev2d);
6793 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6794 SelectStore(Node, 3, AArch64::ST1Threev1d);
6799 case Intrinsic::aarch64_neon_st1x4: {
6800 if (VT == MVT::v8i8) {
6801 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6803 }
else if (VT == MVT::v16i8) {
6804 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6806 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6807 VT == MVT::v4bf16) {
6808 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6810 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6811 VT == MVT::v8bf16) {
6812 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6814 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6815 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6817 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6818 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6820 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6821 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6823 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6824 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6829 case Intrinsic::aarch64_neon_st2: {
6830 if (VT == MVT::v8i8) {
6831 SelectStore(Node, 2, AArch64::ST2Twov8b);
6833 }
else if (VT == MVT::v16i8) {
6834 SelectStore(Node, 2, AArch64::ST2Twov16b);
6836 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6837 VT == MVT::v4bf16) {
6838 SelectStore(Node, 2, AArch64::ST2Twov4h);
6840 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6841 VT == MVT::v8bf16) {
6842 SelectStore(Node, 2, AArch64::ST2Twov8h);
6844 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6845 SelectStore(Node, 2, AArch64::ST2Twov2s);
6847 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6848 SelectStore(Node, 2, AArch64::ST2Twov4s);
6850 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6851 SelectStore(Node, 2, AArch64::ST2Twov2d);
6853 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6854 SelectStore(Node, 2, AArch64::ST1Twov1d);
6859 case Intrinsic::aarch64_neon_st3: {
6860 if (VT == MVT::v8i8) {
6861 SelectStore(Node, 3, AArch64::ST3Threev8b);
6863 }
else if (VT == MVT::v16i8) {
6864 SelectStore(Node, 3, AArch64::ST3Threev16b);
6866 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6867 VT == MVT::v4bf16) {
6868 SelectStore(Node, 3, AArch64::ST3Threev4h);
6870 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6871 VT == MVT::v8bf16) {
6872 SelectStore(Node, 3, AArch64::ST3Threev8h);
6874 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6875 SelectStore(Node, 3, AArch64::ST3Threev2s);
6877 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6878 SelectStore(Node, 3, AArch64::ST3Threev4s);
6880 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6881 SelectStore(Node, 3, AArch64::ST3Threev2d);
6883 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6884 SelectStore(Node, 3, AArch64::ST1Threev1d);
6889 case Intrinsic::aarch64_neon_st4: {
6890 if (VT == MVT::v8i8) {
6891 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6893 }
else if (VT == MVT::v16i8) {
6894 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6896 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6897 VT == MVT::v4bf16) {
6898 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6900 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6901 VT == MVT::v8bf16) {
6902 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6904 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6905 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6907 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6908 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6910 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6911 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6913 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6914 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6919 case Intrinsic::aarch64_neon_st2lane: {
6920 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6921 SelectStoreLane(Node, 2, AArch64::ST2i8);
6923 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6924 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6925 SelectStoreLane(Node, 2, AArch64::ST2i16);
6927 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6929 SelectStoreLane(Node, 2, AArch64::ST2i32);
6931 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6933 SelectStoreLane(Node, 2, AArch64::ST2i64);
6938 case Intrinsic::aarch64_neon_st3lane: {
6939 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6940 SelectStoreLane(Node, 3, AArch64::ST3i8);
6942 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6943 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6944 SelectStoreLane(Node, 3, AArch64::ST3i16);
6946 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6948 SelectStoreLane(Node, 3, AArch64::ST3i32);
6950 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6952 SelectStoreLane(Node, 3, AArch64::ST3i64);
6957 case Intrinsic::aarch64_neon_st4lane: {
6958 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6959 SelectStoreLane(Node, 4, AArch64::ST4i8);
6961 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6962 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6963 SelectStoreLane(Node, 4, AArch64::ST4i16);
6965 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6967 SelectStoreLane(Node, 4, AArch64::ST4i32);
6969 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6971 SelectStoreLane(Node, 4, AArch64::ST4i64);
6976 case Intrinsic::aarch64_sve_st2q: {
6977 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6980 case Intrinsic::aarch64_sve_st3q: {
6981 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6984 case Intrinsic::aarch64_sve_st4q: {
6985 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6988 case Intrinsic::aarch64_sve_st2: {
6989 if (VT == MVT::nxv16i8) {
6990 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6992 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6993 VT == MVT::nxv8bf16) {
6994 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6996 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6997 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6999 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7000 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7005 case Intrinsic::aarch64_sve_st3: {
7006 if (VT == MVT::nxv16i8) {
7007 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7009 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7010 VT == MVT::nxv8bf16) {
7011 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7013 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7014 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7016 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7017 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7022 case Intrinsic::aarch64_sve_st4: {
7023 if (VT == MVT::nxv16i8) {
7024 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7026 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7027 VT == MVT::nxv8bf16) {
7028 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7030 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7031 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7033 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7034 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7042 case AArch64ISD::LD2post: {
7043 if (VT == MVT::v8i8) {
7044 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7046 }
else if (VT == MVT::v16i8) {
7047 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7049 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7050 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7052 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7053 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7055 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7056 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7058 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7059 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7061 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7062 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7064 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7065 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7070 case AArch64ISD::LD3post: {
7071 if (VT == MVT::v8i8) {
7072 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7074 }
else if (VT == MVT::v16i8) {
7075 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7077 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7078 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7080 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7081 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7083 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7084 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7086 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7087 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7089 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7090 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7092 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7093 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7098 case AArch64ISD::LD4post: {
7099 if (VT == MVT::v8i8) {
7100 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7102 }
else if (VT == MVT::v16i8) {
7103 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7105 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7106 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7108 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7109 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7111 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7112 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7114 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7115 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7117 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7118 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7120 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7121 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7126 case AArch64ISD::LD1x2post: {
7127 if (VT == MVT::v8i8) {
7128 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7130 }
else if (VT == MVT::v16i8) {
7131 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7133 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7134 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7136 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7137 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7139 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7140 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7142 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7143 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7145 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7146 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7148 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7149 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7154 case AArch64ISD::LD1x3post: {
7155 if (VT == MVT::v8i8) {
7156 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7158 }
else if (VT == MVT::v16i8) {
7159 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7161 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7162 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7164 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7165 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7167 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7168 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7170 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7171 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7173 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7174 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7176 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7177 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7182 case AArch64ISD::LD1x4post: {
7183 if (VT == MVT::v8i8) {
7184 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7186 }
else if (VT == MVT::v16i8) {
7187 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7189 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7190 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7192 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7193 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7195 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7196 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7198 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7199 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7201 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7202 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7204 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7205 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7210 case AArch64ISD::LD1DUPpost: {
7211 if (VT == MVT::v8i8) {
7212 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7214 }
else if (VT == MVT::v16i8) {
7215 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7217 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7218 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7220 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7221 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7223 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7224 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7226 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7227 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7229 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7230 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7232 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7233 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7238 case AArch64ISD::LD2DUPpost: {
7239 if (VT == MVT::v8i8) {
7240 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7242 }
else if (VT == MVT::v16i8) {
7243 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7245 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7246 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7248 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7249 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7251 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7252 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7254 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7255 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7257 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7258 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7260 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7261 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7266 case AArch64ISD::LD3DUPpost: {
7267 if (VT == MVT::v8i8) {
7268 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7270 }
else if (VT == MVT::v16i8) {
7271 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7273 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7274 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7276 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7277 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7279 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7280 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7282 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7283 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7285 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7286 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7288 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7289 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7294 case AArch64ISD::LD4DUPpost: {
7295 if (VT == MVT::v8i8) {
7296 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7298 }
else if (VT == MVT::v16i8) {
7299 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7301 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7302 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7304 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7305 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7307 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7308 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7310 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7311 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7313 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7314 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7316 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7317 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7322 case AArch64ISD::LD1LANEpost: {
7323 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7324 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7326 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7327 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7328 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7330 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7332 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7334 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7336 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7341 case AArch64ISD::LD2LANEpost: {
7342 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7343 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7345 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7346 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7347 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7349 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7351 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7353 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7355 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7360 case AArch64ISD::LD3LANEpost: {
7361 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7362 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7364 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7365 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7366 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7368 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7370 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7372 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7374 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7379 case AArch64ISD::LD4LANEpost: {
7380 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7381 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7383 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7384 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7385 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7387 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7389 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7391 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7393 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7398 case AArch64ISD::ST2post: {
7399 VT =
Node->getOperand(1).getValueType();
7400 if (VT == MVT::v8i8) {
7401 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7403 }
else if (VT == MVT::v16i8) {
7404 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7406 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7407 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7409 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7410 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7412 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7413 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7415 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7416 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7418 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7419 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7421 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7422 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7427 case AArch64ISD::ST3post: {
7428 VT =
Node->getOperand(1).getValueType();
7429 if (VT == MVT::v8i8) {
7430 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7432 }
else if (VT == MVT::v16i8) {
7433 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7435 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7436 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7438 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7439 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7441 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7442 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7444 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7445 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7447 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7448 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7450 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7451 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7456 case AArch64ISD::ST4post: {
7457 VT =
Node->getOperand(1).getValueType();
7458 if (VT == MVT::v8i8) {
7459 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7461 }
else if (VT == MVT::v16i8) {
7462 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7464 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7465 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7467 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7468 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7470 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7471 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7473 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7474 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7476 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7477 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7479 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7480 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7485 case AArch64ISD::ST1x2post: {
7486 VT =
Node->getOperand(1).getValueType();
7487 if (VT == MVT::v8i8) {
7488 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7490 }
else if (VT == MVT::v16i8) {
7491 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7493 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7494 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7496 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7497 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7499 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7500 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7502 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7503 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7505 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7506 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7508 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7509 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7514 case AArch64ISD::ST1x3post: {
7515 VT =
Node->getOperand(1).getValueType();
7516 if (VT == MVT::v8i8) {
7517 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7519 }
else if (VT == MVT::v16i8) {
7520 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7522 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7523 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7525 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7526 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7528 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7529 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7531 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7532 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7534 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7535 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7537 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7538 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7543 case AArch64ISD::ST1x4post: {
7544 VT =
Node->getOperand(1).getValueType();
7545 if (VT == MVT::v8i8) {
7546 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7548 }
else if (VT == MVT::v16i8) {
7549 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7551 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7552 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7554 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7555 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7557 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7558 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7560 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7561 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7563 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7564 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7566 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7567 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7572 case AArch64ISD::ST2LANEpost: {
7573 VT =
Node->getOperand(1).getValueType();
7574 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7575 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7577 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7578 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7579 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7581 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7583 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7585 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7587 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7592 case AArch64ISD::ST3LANEpost: {
7593 VT =
Node->getOperand(1).getValueType();
7594 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7595 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7597 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7598 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7599 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7601 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7603 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7605 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7607 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7612 case AArch64ISD::ST4LANEpost: {
7613 VT =
Node->getOperand(1).getValueType();
7614 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7615 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7617 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7618 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7619 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7621 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7623 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7625 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7627 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7642 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7654 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7658 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7659 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7674 return MemIntr->getMemoryVT();
7681 DataVT = Load->getValueType(0);
7683 DataVT = Load->getValueType(0);
7685 DataVT = Store->getValue().getValueType();
7687 DataVT = Store->getValue().getValueType();
7694 const unsigned Opcode = Root->
getOpcode();
7698 case AArch64ISD::LD1_MERGE_ZERO:
7699 case AArch64ISD::LD1S_MERGE_ZERO:
7700 case AArch64ISD::LDNF1_MERGE_ZERO:
7701 case AArch64ISD::LDNF1S_MERGE_ZERO:
7703 case AArch64ISD::ST1_PRED:
7715 case Intrinsic::aarch64_sme_ldr:
7716 case Intrinsic::aarch64_sme_str:
7717 return MVT::nxv16i8;
7718 case Intrinsic::aarch64_sve_prf:
7723 case Intrinsic::aarch64_sve_ld2_sret:
7724 case Intrinsic::aarch64_sve_ld2q_sret:
7727 case Intrinsic::aarch64_sve_st2q:
7730 case Intrinsic::aarch64_sve_ld3_sret:
7731 case Intrinsic::aarch64_sve_ld3q_sret:
7734 case Intrinsic::aarch64_sve_st3q:
7737 case Intrinsic::aarch64_sve_ld4_sret:
7738 case Intrinsic::aarch64_sve_ld4q_sret:
7741 case Intrinsic::aarch64_sve_st4q:
7744 case Intrinsic::aarch64_sve_ld1udq:
7745 case Intrinsic::aarch64_sve_st1dq:
7746 return EVT(MVT::nxv1i64);
7747 case Intrinsic::aarch64_sve_ld1uwq:
7748 case Intrinsic::aarch64_sve_st1wq:
7749 return EVT(MVT::nxv1i32);
7756template <
int64_t Min,
int64_t Max>
7757bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7761 const DataLayout &
DL = CurDAG->getDataLayout();
7762 const MachineFrameInfo &MFI = MF->getFrameInfo();
7770 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7784 int64_t MulImm = std::numeric_limits<int64_t>::max();
7788 int64_t ByteOffset =
C->getSExtValue();
7789 const auto KnownVScale =
7792 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7795 MulImm = ByteOffset / KnownVScale;
7802 if ((MulImm % MemWidthBytes) != 0)
7805 int64_t
Offset = MulImm / MemWidthBytes;
7809 Base =
N.getOperand(0);
7818 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7824bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7843 int64_t ImmOff =
C->getSExtValue();
7844 unsigned Size = 1 << Scale;
7853 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7855 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7866 if (
C->getZExtValue() == Scale) {
7875bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7876 const AArch64TargetLowering *TLI =
7877 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7882bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7883 EVT VT =
N.getValueType();
7887bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7892 int64_t ImmOff =
C->getSExtValue();
7893 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7894 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7899 if (
SDValue C = MatchConstantOffset(
N)) {
7900 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7906 if (CurDAG->isBaseWithConstantOffset(
N)) {
7907 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7908 Base =
N.getOperand(0);
7916 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7920bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7940 uint64_t LowerBound = 0, UpperBound = 64;
7958 if (CN->getAPIntValue().uge(LowerBound) &&
7959 CN->getAPIntValue().ult(UpperBound)) {
7961 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7969template <
bool MatchCBB>
7976 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7978 Reg =
N.getOperand(0);
7980 SDLoc(
N), MVT::i32);
7988 Reg =
N.getOperand(0);
7997void AArch64DAGToDAGISel::PreprocessISelDAG() {
7998 bool MadeChange =
false;
8004 switch (
N.getOpcode()) {
8006 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8007 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8008 ScalarTy ==
N.getOperand(0).getValueType())
8018 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8024 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8030 CurDAG->RemoveDeadNodes();
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static std::optional< APInt > GetNEONSplatValue(SDValue N)
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static SDValue addBitcastHints(SelectionDAG &DAG, SDNode &N)
addBitcastHints - This method adds bitcast hints to the operands of a node to help instruction select...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static std::optional< APInt > DecodeNEONSplat(SDValue N)
static bool checkCVTFixedPointOperandWithFBitsForVectors(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static APInt DecodeFMOVImm(uint64_t Imm, unsigned RegWidth)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const AArch64RegisterInfo * getRegisterInfo() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static const fltSemantics & IEEEhalf()
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
static constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.