22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
47 AArch64DAGToDAGISel() =
delete;
64 std::vector<SDValue> &OutOps)
override;
66 template <
signed Low,
signed High,
signed Scale>
74 return SelectShiftedRegister(
N,
false, Reg, Shift);
77 return SelectShiftedRegister(
N,
true, Reg, Shift);
80 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
83 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
86 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
89 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
95 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
98 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
101 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
104 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
107 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
116 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
119 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
122 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
130 template <
unsigned Size,
unsigned Max>
134 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
136 if (
auto *CI = dyn_cast<ConstantSDNode>(OffImm)) {
137 int64_t
C = CI->getSExtValue();
145 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
152 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
158 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
163 N =
N->getOperand(0);
165 !isa<ConstantSDNode>(
N->getOperand(1)))
167 EVT VT =
N->getValueType(0);
168 EVT LVT =
N->getOperand(0).getValueType();
169 unsigned Index =
N->getConstantOperandVal(1);
173 Res =
N->getOperand(0);
181 EVT VT =
Op.getValueType();
182 unsigned ShtAmt =
N->getConstantOperandVal(1);
189 Op.getOperand(1).getConstantOperandVal(0)
190 <<
Op.getOperand(1).getConstantOperandVal(1));
192 isa<ConstantSDNode>(
Op.getOperand(1).getOperand(0)))
194 Op.getOperand(1).getConstantOperandVal(0));
198 if (Imm != 1ULL << (ShtAmt - 1))
201 Res1 =
Op.getOperand(0);
202 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
206 bool SelectDupZeroOrUndef(
SDValue N) {
207 switch(
N->getOpcode()) {
212 auto Opnd0 =
N->getOperand(0);
227 switch(
N->getOpcode()) {
230 auto Opnd0 =
N->getOperand(0);
242 template<MVT::SimpleValueType VT>
244 return SelectSVEAddSubImm(
N, VT, Imm, Shift);
247 template <MVT::SimpleValueType VT,
bool Negate>
249 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
252 template <MVT::SimpleValueType VT>
254 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
257 template <MVT::SimpleValueType VT,
bool Invert = false>
259 return SelectSVELogicalImm(
N, VT, Imm, Invert);
262 template <MVT::SimpleValueType VT>
264 return SelectSVEArithImm(
N, VT, Imm);
267 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
269 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
276 EVT EltVT =
N->getValueType(0).getVectorElementType();
277 return SelectSVEShiftImm(
N->getOperand(0), 1,
283 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
285 if (!isa<ConstantSDNode>(
N))
288 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
290 MulImm = 1LL << MulImm;
292 if ((MulImm % std::abs(Scale)) != 0)
296 if ((MulImm >= Min) && (MulImm <= Max)) {
297 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
304 template <
signed Max,
signed Scale>
306 if (!isa<ConstantSDNode>(
N))
309 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
311 if (MulImm >= 0 && MulImm <= Max) {
313 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
320 template <
unsigned BaseReg,
unsigned Max>
322 if (
auto *CI = dyn_cast<ConstantSDNode>(
N)) {
328 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
351 const unsigned SubRegs[]);
353 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
355 bool tryIndexedLoad(
SDNode *
N);
357 void SelectPtrauthAuth(
SDNode *
N);
358 void SelectPtrauthResign(
SDNode *
N);
360 bool trySelectStackSlotTagP(
SDNode *
N);
363 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
365 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
367 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
368 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
369 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
370 unsigned Opc_rr,
unsigned Opc_ri,
371 bool IsIntr =
false);
372 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
373 unsigned Scale,
unsigned Opc_ri,
375 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
376 bool IsZmMulti,
unsigned Opcode,
377 bool HasPred =
false);
378 void SelectPExtPair(
SDNode *
N,
unsigned Opc);
379 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
380 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
381 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
382 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
383 bool IsTupleInput,
unsigned Opc);
384 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
386 template <
unsigned MaxIdx,
unsigned Scale>
387 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
389 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
390 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
391 unsigned BaseReg = 0);
394 template <
int64_t Min,
int64_t Max>
398 template <
unsigned Scale>
400 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
403 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc,
406 template <
unsigned MaxIdx,
unsigned Scale>
411 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
412 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
413 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
414 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
415 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
416 unsigned Opc_rr,
unsigned Opc_ri);
417 std::tuple<unsigned, SDValue, SDValue>
418 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
422 bool tryBitfieldExtractOp(
SDNode *
N);
423 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
424 bool tryBitfieldInsertOp(
SDNode *
N);
425 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
426 bool tryShiftAmountMod(
SDNode *
N);
428 bool tryReadRegister(
SDNode *
N);
429 bool tryWriteRegister(
SDNode *
N);
431 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
432 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
437#include "AArch64GenDAGISel.inc"
445 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
447 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
460 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
461 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
462 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
465 template<
unsigned RegW
idth>
467 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
470 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
472 template<
unsigned RegW
idth>
474 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
480 bool SelectCMP_SWAP(
SDNode *
N);
490 bool AllowSaturation,
SDValue &Imm);
498 bool SelectAllActivePredicate(
SDValue N);
508 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
512char AArch64DAGToDAGISelLegacy::ID = 0;
520 Imm =
C->getZExtValue();
537 return N->getOpcode() == Opc &&
548 return Imm == ImmExpected;
552bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
554 std::vector<SDValue> &OutOps) {
555 switch(ConstraintID) {
558 case InlineAsm::ConstraintCode::m:
559 case InlineAsm::ConstraintCode::o:
560 case InlineAsm::ConstraintCode::Q:
566 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
568 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
569 dl,
Op.getValueType(),
571 OutOps.push_back(NewOp);
587 if (!isa<ConstantSDNode>(
N.getNode()))
590 uint64_t Immed =
N.getNode()->getAsZExtVal();
593 if (Immed >> 12 == 0) {
595 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
603 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
604 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
617 if (!isa<ConstantSDNode>(
N.getNode()))
621 uint64_t Immed =
N.getNode()->getAsZExtVal();
629 if (
N.getValueType() == MVT::i32)
632 Immed = ~Immed + 1ULL;
633 if (Immed & 0xFFFFFFFFFF000000ULL)
636 Immed &= 0xFFFFFFULL;
637 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(
N), MVT::i32), Val,
644 switch (
N.getOpcode()) {
663 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
666 unsigned ShiftVal = CSD->getZExtValue();
675 if (!isa<MemSDNode>(*UI))
677 if (!isa<MemSDNode>(*UII))
684bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
687 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
692 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
714bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(
SDValue N,
SDValue &Reg,
716 EVT VT =
N.getValueType();
717 if (VT != MVT::i32 && VT != MVT::i64)
720 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
726 unsigned LHSOpcode =
LHS->getOpcode();
740 unsigned LowZBits, MaskLen;
744 unsigned BitWidth =
N.getValueSizeInBits();
751 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
754 NewShiftC = LowZBits - ShiftAmtC;
755 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
761 NewShiftC = LowZBits + ShiftAmtC;
774 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
776 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
780 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
782 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
783 NewShiftAmt, BitWidthMinus1),
786 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
798 SrcVT = cast<VTSDNode>(
N.getOperand(1))->getVT();
800 SrcVT =
N.getOperand(0).getValueType();
802 if (!IsLoadStore && SrcVT == MVT::i8)
804 else if (!IsLoadStore && SrcVT == MVT::i16)
806 else if (SrcVT == MVT::i32)
808 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
813 EVT SrcVT =
N.getOperand(0).getValueType();
814 if (!IsLoadStore && SrcVT == MVT::i8)
816 else if (!IsLoadStore && SrcVT == MVT::i16)
818 else if (SrcVT == MVT::i32)
820 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
848bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
851 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
856 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
857 V.getConstantOperandVal(1) <= 4 &&
870bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
872 if (SelectShiftedRegisterFromAnd(
N, Reg, Shift))
882 unsigned BitSize =
N.getValueSizeInBits();
883 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
886 Reg =
N.getOperand(0);
887 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(
N), MVT::i32);
888 return isWorthFoldingALU(
N,
true);
899 if (
N.getValueType() == MVT::i32)
907template<
signed Low,
signed High,
signed Scale>
909 if (!isa<ConstantSDNode>(
N))
912 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
913 if ((MulImm % std::abs(Scale)) == 0) {
914 int64_t RDVLImm = MulImm / Scale;
915 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
916 Imm = CurDAG->getSignedConstant(RDVLImm,
SDLoc(
N), MVT::i32,
927bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
929 unsigned ShiftVal = 0;
944 Reg =
N.getOperand(0).getOperand(0);
950 Reg =
N.getOperand(0);
955 unsigned Opc =
N.getOpcode();
956 return Opc !=
ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG &&
973 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
975 return isWorthFoldingALU(
N);
980bool AArch64DAGToDAGISel::SelectArithUXTXRegister(
SDValue N,
SDValue &Reg,
982 unsigned ShiftVal = 0;
996 Reg =
N.getOperand(0);
997 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
999 return isWorthFoldingALU(
N);
1008 for (
auto *
Use :
N->uses()) {
1035bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1036 unsigned BW,
unsigned Size,
1043 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1045 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1051 if (CurDAG->isBaseWithConstantOffset(
N)) {
1052 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1054 int64_t RHSC =
RHS->getSExtValue();
1056 int64_t
Range = 0x1LL << (BW - 1);
1058 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1059 RHSC < (
Range << Scale)) {
1060 Base =
N.getOperand(0);
1062 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1065 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1074 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1075 Base =
N.getOperand(0);
1077 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1080 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1091 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1098bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1104 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1106 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1112 dyn_cast<GlobalAddressSDNode>(
N.getOperand(1).getNode());
1113 Base =
N.getOperand(0);
1114 OffImm =
N.getOperand(1);
1123 if (CurDAG->isBaseWithConstantOffset(
N)) {
1124 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1125 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1128 Base =
N.getOperand(0);
1130 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1133 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1141 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1149 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1158bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1161 if (!CurDAG->isBaseWithConstantOffset(
N))
1163 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1164 int64_t RHSC =
RHS->getSExtValue();
1165 if (RHSC >= -256 && RHSC < 256) {
1166 Base =
N.getOperand(0);
1168 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1170 Base = CurDAG->getTargetFrameIndex(
1173 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(
N), MVT::i64);
1183 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1190bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1210 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1216 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1219 return isWorthFoldingAddr(
N,
Size);
1222bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1234 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1242 if (!isa<MemSDNode>(*UI))
1247 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1250 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1251 SelectExtendedSHL(RHS,
Size,
true,
Offset, SignExtend)) {
1253 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1258 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1259 SelectExtendedSHL(LHS,
Size,
true,
Offset, SignExtend)) {
1261 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1266 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1270 if (IsExtendedRegisterWorthFolding &&
1277 if (isWorthFoldingAddr(LHS,
Size))
1282 if (IsExtendedRegisterWorthFolding &&
1289 if (isWorthFoldingAddr(RHS,
Size))
1301 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1304 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1306 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1307 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1311bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1326 if (!isa<MemSDNode>(*UI))
1341 if (isa<ConstantSDNode>(RHS)) {
1342 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1352 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
1355 N = CurDAG->getNode(
ISD::ADD,
DL, MVT::i64, LHS, MOVIV);
1359 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1362 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1363 SelectExtendedSHL(RHS,
Size,
false,
Offset, SignExtend)) {
1365 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1370 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1371 SelectExtendedSHL(LHS,
Size,
false,
Offset, SignExtend)) {
1373 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1380 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1381 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1387 static const unsigned RegClassIDs[] = {
1388 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1389 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1390 AArch64::dsub2, AArch64::dsub3};
1396 static const unsigned RegClassIDs[] = {
1397 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1398 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1399 AArch64::qsub2, AArch64::qsub3};
1405 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1406 AArch64::ZPR3RegClassID,
1407 AArch64::ZPR4RegClassID};
1408 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1409 AArch64::zsub2, AArch64::zsub3};
1419 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1420 AArch64::ZPR4Mul4RegClassID};
1421 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1422 AArch64::zsub2, AArch64::zsub3};
1427 const unsigned RegClassIDs[],
1428 const unsigned SubRegs[]) {
1431 if (Regs.
size() == 1)
1442 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1445 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1447 Ops.
push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1451 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped, Ops);
1455void AArch64DAGToDAGISel::SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1458 EVT VT =
N->getValueType(0);
1460 unsigned ExtOff = isExt;
1463 unsigned Vec0Off = ExtOff + 1;
1465 N->op_begin() + Vec0Off + NumVecs);
1472 Ops.
push_back(
N->getOperand(NumVecs + ExtOff + 1));
1473 ReplaceNode(
N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
1476static std::tuple<SDValue, SDValue>
1496 auto *ConstDiscN = dyn_cast<ConstantSDNode>(ConstDisc);
1497 if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue()))
1502 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1504 return std::make_tuple(
1509void AArch64DAGToDAGISel::SelectPtrauthAuth(
SDNode *
N) {
1514 SDValue AUTDisc =
N->getOperand(3);
1516 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1517 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1519 SDValue AUTAddrDisc, AUTConstDisc;
1520 std::tie(AUTConstDisc, AUTAddrDisc) =
1523 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1524 AArch64::X16, Val,
SDValue());
1525 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1527 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUT,
DL, MVT::i64, Ops);
1528 ReplaceNode(
N, AUT);
1532void AArch64DAGToDAGISel::SelectPtrauthResign(
SDNode *
N) {
1537 SDValue AUTDisc =
N->getOperand(3);
1539 SDValue PACDisc =
N->getOperand(5);
1541 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1542 unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
1544 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1545 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1547 SDValue AUTAddrDisc, AUTConstDisc;
1548 std::tie(AUTConstDisc, AUTAddrDisc) =
1551 SDValue PACAddrDisc, PACConstDisc;
1552 std::tie(PACConstDisc, PACAddrDisc) =
1555 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1556 AArch64::X16, Val,
SDValue());
1558 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1559 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1561 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64, Ops);
1562 ReplaceNode(
N, AUTPAC);
1566bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
1568 if (
LD->isUnindexed())
1570 EVT VT =
LD->getMemoryVT();
1571 EVT DstVT =
N->getValueType(0);
1578 unsigned Opcode = 0;
1581 bool InsertTo64 =
false;
1583 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1584 else if (VT == MVT::i32) {
1586 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1588 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1590 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1596 }
else if (VT == MVT::i16) {
1598 if (DstVT == MVT::i64)
1599 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1601 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1603 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1604 InsertTo64 = DstVT == MVT::i64;
1609 }
else if (VT == MVT::i8) {
1611 if (DstVT == MVT::i64)
1612 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1614 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1616 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1617 InsertTo64 = DstVT == MVT::i64;
1622 }
else if (VT == MVT::f16) {
1623 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1624 }
else if (VT == MVT::bf16) {
1625 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1626 }
else if (VT == MVT::f32) {
1627 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1629 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1631 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1639 SDValue Offset = CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1641 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1646 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {
MemOp});
1651 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1653 SDValue(CurDAG->getMachineNode(
1654 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1655 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1660 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1663 CurDAG->RemoveDeadNode(
N);
1667void AArch64DAGToDAGISel::SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1668 unsigned SubRegIdx) {
1670 EVT VT =
N->getValueType(0);
1676 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1678 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1680 for (
unsigned i = 0; i < NumVecs; ++i)
1682 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1688 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(
N)) {
1690 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
1693 CurDAG->RemoveDeadNode(
N);
1696void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
1697 unsigned Opc,
unsigned SubRegIdx) {
1699 EVT VT =
N->getValueType(0);
1706 const EVT ResTys[] = {MVT::i64,
1707 MVT::Untyped, MVT::Other};
1709 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1717 ReplaceUses(
SDValue(
N, 0), SuperReg);
1719 for (
unsigned i = 0; i < NumVecs; ++i)
1721 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1725 CurDAG->RemoveDeadNode(
N);
1731std::tuple<unsigned, SDValue, SDValue>
1732AArch64DAGToDAGISel::findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
1738 SDValue NewOffset = OldOffset;
1740 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1741 N, OldBase, NewBase, NewOffset);
1745 const bool IsRegReg =
1746 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1749 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1762template <SelectTypeKind Kind>
1774 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1779 if (EltVT != MVT::i1)
1783 if (EltVT == MVT::bf16)
1785 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1815void AArch64DAGToDAGISel::SelectPExtPair(
SDNode *
N,
unsigned Opc) {
1818 if (
Imm->getZExtValue() > 1)
1822 EVT VT =
N->getValueType(0);
1823 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1824 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1827 for (
unsigned I = 0;
I < 2; ++
I)
1828 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1829 AArch64::psub0 +
I,
DL, VT, SuperReg));
1831 CurDAG->RemoveDeadNode(
N);
1834void AArch64DAGToDAGISel::SelectWhilePair(
SDNode *
N,
unsigned Opc) {
1836 EVT VT =
N->getValueType(0);
1838 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1840 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1843 for (
unsigned I = 0;
I < 2; ++
I)
1844 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1845 AArch64::psub0 +
I,
DL, VT, SuperReg));
1847 CurDAG->RemoveDeadNode(
N);
1850void AArch64DAGToDAGISel::SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
1852 EVT VT =
N->getValueType(0);
1854 SDValue Ops = createZTuple(Regs);
1858 for (
unsigned i = 0; i < NumVecs; ++i)
1859 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1860 AArch64::zsub0 + i,
DL, VT, SuperReg));
1862 CurDAG->RemoveDeadNode(
N);
1865void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(
SDNode *
N,
1870 assert(Opcode != 0 &&
"Unexpected opcode");
1873 EVT VT =
N->getValueType(0);
1874 unsigned FirstVecIdx = HasPred ? 2 : 1;
1876 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1878 return createZMulTuple(Regs);
1881 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1885 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1887 Zm =
N->getOperand(NumVecs + FirstVecIdx);
1891 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1892 N->getOperand(1), Zdn, Zm);
1894 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
1896 for (
unsigned i = 0; i < NumVecs; ++i)
1897 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1898 AArch64::zsub0 + i,
DL, VT, SuperReg));
1900 CurDAG->RemoveDeadNode(
N);
1903void AArch64DAGToDAGISel::SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
1904 unsigned Scale,
unsigned Opc_ri,
1905 unsigned Opc_rr,
bool IsIntr) {
1906 assert(Scale < 5 &&
"Invalid scaling value.");
1908 EVT VT =
N->getValueType(0);
1914 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
1915 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
1916 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
1918 SDValue Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
1922 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1924 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1926 for (
unsigned i = 0; i < NumVecs; ++i)
1927 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1928 AArch64::zsub0 + i,
DL, VT, SuperReg));
1931 unsigned ChainIdx = NumVecs;
1933 CurDAG->RemoveDeadNode(
N);
1936void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(
SDNode *
N,
1941 assert(Scale < 4 &&
"Invalid scaling value.");
1943 EVT VT =
N->getValueType(0);
1951 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
1957 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1959 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1961 for (
unsigned i = 0; i < NumVecs; ++i)
1962 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1963 AArch64::zsub0 + i,
DL, VT, SuperReg));
1966 unsigned ChainIdx = NumVecs;
1968 CurDAG->RemoveDeadNode(
N);
1971void AArch64DAGToDAGISel::SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
1973 if (
N->getValueType(0) != MVT::nxv4f32)
1975 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
1978void AArch64DAGToDAGISel::SelectMultiVectorLuti(
SDNode *
Node,
1979 unsigned NumOutVecs,
1982 if (
Imm->getZExtValue() > MaxImm)
1986 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
1990 EVT VT =
Node->getValueType(0);
1993 CurDAG->getMachineNode(Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
1996 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
1997 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
1998 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2001 unsigned ChainIdx = NumOutVecs;
2003 CurDAG->RemoveDeadNode(
Node);
2006void AArch64DAGToDAGISel::SelectClamp(
SDNode *
N,
unsigned NumVecs,
2009 EVT VT =
N->getValueType(0);
2012 SDValue Zd = createZMulTuple(Regs);
2013 SDValue Zn =
N->getOperand(1 + NumVecs);
2014 SDValue Zm =
N->getOperand(2 + NumVecs);
2020 for (
unsigned i = 0; i < NumVecs; ++i)
2021 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2022 AArch64::zsub0 + i,
DL, VT, SuperReg));
2024 CurDAG->RemoveDeadNode(
N);
2054template <
unsigned MaxIdx,
unsigned Scale>
2055void AArch64DAGToDAGISel::SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
2056 unsigned BaseReg,
unsigned Op) {
2057 unsigned TileNum = 0;
2058 if (BaseReg != AArch64::ZA)
2059 TileNum =
N->getConstantOperandVal(2);
2065 if (BaseReg == AArch64::ZA)
2066 SliceBase =
N->getOperand(2);
2068 SliceBase =
N->getOperand(3);
2070 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2076 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2078 EVT VT =
N->getValueType(0);
2079 for (
unsigned I = 0;
I < NumVecs; ++
I)
2081 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2084 unsigned ChainIdx = NumVecs;
2086 CurDAG->RemoveDeadNode(
N);
2089void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
2090 unsigned Op,
unsigned MaxIdx,
2091 unsigned Scale,
unsigned BaseReg) {
2095 SDValue SliceBase =
N->getOperand(2);
2096 if (BaseReg != AArch64::ZA)
2097 SliceBase =
N->getOperand(3);
2100 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2107 if (BaseReg != AArch64::ZA )
2112 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2114 EVT VT =
N->getValueType(0);
2115 for (
unsigned I = 0;
I < NumVecs; ++
I)
2117 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2121 unsigned ChainIdx = NumVecs;
2123 CurDAG->RemoveDeadNode(
N);
2126void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(
SDNode *
N,
2127 unsigned NumOutVecs,
2131 EVT VT =
N->getValueType(0);
2132 unsigned NumInVecs =
N->getNumOperands() - 1;
2136 assert((NumInVecs == 2 || NumInVecs == 4) &&
2137 "Don't know how to handle multi-register input!");
2142 for (
unsigned I = 0;
I < NumInVecs;
I++)
2146 SDNode *Res = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
2149 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2150 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2151 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2152 CurDAG->RemoveDeadNode(
N);
2155void AArch64DAGToDAGISel::SelectStore(
SDNode *
N,
unsigned NumVecs,
2158 EVT VT =
N->getOperand(2)->getValueType(0);
2165 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
N->getOperand(0)};
2166 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2170 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2175void AArch64DAGToDAGISel::SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
2176 unsigned Scale,
unsigned Opc_rr,
2182 SDValue RegSeq = createZTuple(Regs);
2187 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
2188 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2189 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2191 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
2195 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2207 if (
auto FINode = dyn_cast<FrameIndexSDNode>(
N)) {
2208 int FI = FINode->getIndex();
2210 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2217void AArch64DAGToDAGISel::SelectPostStore(
SDNode *
N,
unsigned NumVecs,
2220 EVT VT =
N->getOperand(2)->getValueType(0);
2221 const EVT ResTys[] = {MVT::i64,
2230 N->getOperand(NumVecs + 1),
2231 N->getOperand(NumVecs + 2),
2233 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2273void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
2276 EVT VT =
N->getValueType(0);
2284 WidenVector(*CurDAG));
2288 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2290 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2292 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2293 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2294 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2298 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2299 AArch64::qsub2, AArch64::qsub3 };
2300 for (
unsigned i = 0; i < NumVecs; ++i) {
2301 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2308 CurDAG->RemoveDeadNode(
N);
2311void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
2314 EVT VT =
N->getValueType(0);
2322 WidenVector(*CurDAG));
2326 const EVT ResTys[] = {MVT::i64,
2329 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2332 CurDAG->getTargetConstant(LaneNo, dl,
2334 N->getOperand(NumVecs + 2),
2335 N->getOperand(NumVecs + 3),
2337 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2349 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2350 AArch64::qsub2, AArch64::qsub3 };
2351 for (
unsigned i = 0; i < NumVecs; ++i) {
2352 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2362 CurDAG->RemoveDeadNode(
N);
2365void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
2368 EVT VT =
N->getOperand(2)->getValueType(0);
2376 WidenVector(*CurDAG));
2380 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2382 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2383 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2384 SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
2388 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2393void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
2396 EVT VT =
N->getOperand(2)->getValueType(0);
2404 WidenVector(*CurDAG));
2408 const EVT ResTys[] = {MVT::i64,
2411 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2413 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2414 N->getOperand(NumVecs + 2),
2415 N->getOperand(NumVecs + 3),
2417 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2421 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2428 unsigned &LSB,
unsigned &MSB,
2429 unsigned NumberOfIgnoredLowBits,
2430 bool BiggerPattern) {
2432 "N must be a AND operation to call this function");
2434 EVT VT =
N->getValueType(0);
2439 assert((VT == MVT::i32 || VT == MVT::i64) &&
2440 "Type checking must have been done before calling this function");
2454 const SDNode *Op0 =
N->getOperand(0).getNode();
2458 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
2461 if (AndImm & (AndImm + 1))
2464 bool ClampMSB =
false;
2484 ClampMSB = (VT == MVT::i32);
2485 }
else if (BiggerPattern) {
2491 Opd0 =
N->getOperand(0);
2497 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2500 <<
": Found large shift immediate, this should not happen\n"));
2506 (VT == MVT::i32 ? llvm::countr_one<uint32_t>(AndImm)
2507 : llvm::countr_one<uint64_t>(AndImm)) -
2514 MSB = MSB > 31 ? 31 : MSB;
2516 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2521 SDValue &Opd0,
unsigned &Immr,
2525 EVT VT =
N->getValueType(0);
2527 assert((VT == MVT::i32 || VT == MVT::i64) &&
2528 "Type checking must have been done before calling this function");
2532 Op =
Op->getOperand(0);
2533 VT =
Op->getValueType(0);
2542 unsigned Width = cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2546 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2547 Opd0 =
Op.getOperand(0);
2549 Imms = ShiftImm + Width - 1;
2577 Opd0 =
N->getOperand(0).getOperand(0);
2587 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2594 unsigned &Immr,
unsigned &Imms,
2595 bool BiggerPattern) {
2597 "N must be a SHR/SRA operation to call this function");
2599 EVT VT =
N->getValueType(0);
2604 assert((VT == MVT::i32 || VT == MVT::i64) &&
2605 "Type checking must have been done before calling this function");
2615 Opd0 =
N->getOperand(0).getOperand(0);
2616 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2622 Opd0 =
N->getOperand(0).getOperand(0);
2625 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2626 }
else if (BiggerPattern) {
2630 Opd0 =
N->getOperand(0);
2639 <<
": Found large shift immediate, this should not happen\n"));
2648 "bad amount in shift node!");
2649 int immr = SrlImm - ShlImm;
2654 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2656 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2660bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *
N) {
2663 EVT VT =
N->getValueType(0);
2664 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2665 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2676 unsigned Immr = ShiftImm;
2678 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2679 CurDAG->getTargetConstant(Imms, dl, VT)};
2680 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT, Ops);
2685 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2686 unsigned NumberOfIgnoredLowBits = 0,
2687 bool BiggerPattern =
false) {
2688 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2691 switch (
N->getOpcode()) {
2693 if (!
N->isMachineOpcode())
2698 NumberOfIgnoredLowBits, BiggerPattern);
2707 unsigned NOpc =
N->getMachineOpcode();
2711 case AArch64::SBFMWri:
2712 case AArch64::UBFMWri:
2713 case AArch64::SBFMXri:
2714 case AArch64::UBFMXri:
2716 Opd0 =
N->getOperand(0);
2717 Immr =
N->getConstantOperandVal(1);
2718 Imms =
N->getConstantOperandVal(2);
2725bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *
N) {
2726 unsigned Opc, Immr, Imms;
2731 EVT VT =
N->getValueType(0);
2736 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2737 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2738 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2740 SDNode *
BFM = CurDAG->getMachineNode(Opc, dl, MVT::i64, Ops64);
2741 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2747 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2748 CurDAG->getTargetConstant(Imms, dl, VT)};
2749 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
2758 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2759 assert((VT == MVT::i32 || VT == MVT::i64) &&
2760 "i32 or i64 mask type expected!");
2766 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2767 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2790 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2800 APInt OpUsefulBits(UsefulBits);
2804 OpUsefulBits <<= MSB - Imm + 1;
2809 OpUsefulBits <<= Imm;
2811 OpUsefulBits <<= MSB + 1;
2814 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2820 UsefulBits &= OpUsefulBits;
2826 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2828 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2836 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2837 APInt Mask(UsefulBits);
2838 Mask.clearAllBits();
2846 Mask.lshrInPlace(ShiftAmt);
2852 Mask.lshrInPlace(ShiftAmt);
2864 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2866 cast<const ConstantSDNode>(
Op.getOperand(3).getNode())->getZExtValue();
2868 APInt OpUsefulBits(UsefulBits);
2882 OpUsefulBits <<= Width;
2885 if (
Op.getOperand(1) == Orig) {
2887 Mask = ResultUsefulBits & OpUsefulBits;
2891 if (
Op.getOperand(0) == Orig)
2893 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2899 OpUsefulBits <<= Width;
2901 OpUsefulBits <<= LSB;
2903 if (
Op.getOperand(1) == Orig) {
2905 Mask = ResultUsefulBits & OpUsefulBits;
2906 Mask.lshrInPlace(LSB);
2909 if (
Op.getOperand(0) == Orig)
2910 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2927 case AArch64::ANDSWri:
2928 case AArch64::ANDSXri:
2929 case AArch64::ANDWri:
2930 case AArch64::ANDXri:
2934 case AArch64::UBFMWri:
2935 case AArch64::UBFMXri:
2938 case AArch64::ORRWrs:
2939 case AArch64::ORRXrs:
2944 case AArch64::BFMWri:
2945 case AArch64::BFMXri:
2948 case AArch64::STRBBui:
2949 case AArch64::STURBBi:
2955 case AArch64::STRHHui:
2956 case AArch64::STURHHi:
2969 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
2971 UsefulBits =
APInt(Bitwidth, 0);
2980 UsersUsefulBits |= UsefulBitsForUse;
2985 UsefulBits &= UsersUsefulBits;
2995 EVT VT =
Op.getValueType();
2998 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3001 if (ShlAmount > 0) {
3004 UBFMOpc, dl, VT,
Op,
3009 assert(ShlAmount < 0 &&
"expected right shift");
3010 int ShrAmount = -ShlAmount;
3036 bool BiggerPattern,
SDValue &Src,
3037 int &DstLSB,
int &Width) {
3038 EVT VT =
Op.getValueType();
3047 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3051 switch (
Op.getOpcode()) {
3056 NonZeroBits, Src, DstLSB, Width);
3059 NonZeroBits, Src, DstLSB, Width);
3072 EVT VT =
Op.getValueType();
3073 assert((VT == MVT::i32 || VT == MVT::i64) &&
3074 "Caller guarantees VT is one of i32 or i64");
3087 assert((~AndImm & NonZeroBits) == 0 &&
3088 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3117 if (!BiggerPattern && !AndOp0.
hasOneUse())
3136 <<
"Found large Width in bit-field-positioning -- this indicates no "
3137 "proper combining / constant folding was performed\n");
3146 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3161 "Op.getNode() should be a SHL node to call this function");
3163 "Op.getNode() should shift ShlImm to call this function");
3170 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3194 EVT VT =
Op.getValueType();
3195 assert((VT == MVT::i32 || VT == MVT::i64) &&
3196 "Caller guarantees that type is i32 or i64");
3203 if (!BiggerPattern && !
Op.hasOneUse())
3212 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3220 assert(VT == MVT::i32 || VT == MVT::i64);
3231 EVT VT =
N->getValueType(0);
3232 if (VT != MVT::i32 && VT != MVT::i64)
3250 if (!
And.hasOneUse() ||
3260 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3267 if ((OrImm & NotKnownZero) != 0) {
3279 unsigned ImmS = Width - 1;
3285 bool IsBFI = LSB != 0;
3290 unsigned OrChunks = 0, BFIChunks = 0;
3291 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3292 if (((OrImm >> Shift) & 0xFFFF) != 0)
3294 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3297 if (BFIChunks > OrChunks)
3303 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3311 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3320 if (!Dst.hasOneUse())
3323 EVT VT = Dst.getValueType();
3324 assert((VT == MVT::i32 || VT == MVT::i64) &&
3325 "Caller should guarantee that VT is one of i32 or i64");
3333 SDValue DstOp0 = Dst.getOperand(0);
3353 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3354 unsigned MaskWidth =
3357 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3363 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3364 ShiftedOperand =
SDValue(UBFMNode, 0);
3374 ShiftedOperand = Dst.getOperand(0);
3381 ShiftedOperand = Dst.getOperand(0);
3393 const bool BiggerPattern) {
3394 EVT VT =
N->getValueType(0);
3395 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3396 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3397 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3398 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3399 assert((VT == MVT::i32 || VT == MVT::i64) &&
3400 "Expect result type to be i32 or i64 since N is combinable to BFM");
3407 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3410 if (BiggerPattern) {
3424 SDValue Ops[] = {OrOpd0, ShiftedOperand,
3433 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3495 EVT VT =
N->getValueType(0);
3496 if (VT != MVT::i32 && VT != MVT::i64)
3504 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3505 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3525 for (
int I = 0;
I < 4; ++
I) {
3528 unsigned ImmR, ImmS;
3529 bool BiggerPattern =
I / 2;
3530 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3532 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3538 NumberOfIgnoredLowBits, BiggerPattern)) {
3541 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3542 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3547 Width = ImmS - ImmR + 1;
3558 Src, DstLSB, Width)) {
3566 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3576 APInt BitsToBeInserted =
3579 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3603 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3636 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3638 if (Src->hasOneUse() &&
3641 Src = Src->getOperand(0);
3651 unsigned ImmS = Width - 1;
3657 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3665bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *
N) {
3674 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3687bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *
N) {
3691 EVT VT =
N->getValueType(0);
3692 if (VT != MVT::i32 && VT != MVT::i64)
3698 Op0, DstLSB, Width))
3704 unsigned ImmS = Width - 1;
3707 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3708 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3709 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3710 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3716bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
3717 EVT VT =
N->getValueType(0);
3720 switch (
N->getOpcode()) {
3722 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3725 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3728 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3731 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3739 if (VT == MVT::i32) {
3742 }
else if (VT == MVT::i64) {
3748 SDValue ShiftAmt =
N->getOperand(1);
3768 (Add0Imm %
Size == 0)) {
3774 if (SubVT == MVT::i32) {
3775 NegOpc = AArch64::SUBWrr;
3776 ZeroReg = AArch64::WZR;
3778 assert(SubVT == MVT::i64);
3779 NegOpc = AArch64::SUBXrr;
3780 ZeroReg = AArch64::XZR;
3783 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3785 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3786 NewShiftAmt =
SDValue(Neg, 0);
3794 if (SubVT == MVT::i32) {
3795 NotOpc = AArch64::ORNWrr;
3796 ZeroReg = AArch64::WZR;
3798 assert(SubVT == MVT::i64);
3799 NotOpc = AArch64::ORNXrr;
3800 ZeroReg = AArch64::XZR;
3803 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3805 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3806 NewShiftAmt =
SDValue(Not, 0);
3827 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3828 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3830 AArch64::SUBREG_TO_REG,
DL, VT,
3831 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3832 NewShiftAmt =
SDValue(Ext, 0);
3835 SDValue Ops[] = {
N->getOperand(0), NewShiftAmt};
3836 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3843 bool isReciprocal) {
3846 FVal = CN->getValueAPF();
3847 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(
N)) {
3850 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
3854 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
3855 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
3878 if (!IsExact || !IntVal.isPowerOf2())
3880 unsigned FBits = IntVal.logBase2();
3884 if (FBits == 0 || FBits > RegWidth)
return false;
3890bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
3891 unsigned RegWidth) {
3896bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
3898 unsigned RegWidth) {
3908 RegString.
split(Fields,
':');
3910 if (Fields.
size() == 1)
3914 &&
"Invalid number of fields in read register string");
3917 bool AllIntFields =
true;
3921 AllIntFields &= !
Field.getAsInteger(10, IntField);
3926 "Unexpected non-integer value in special register string.");
3931 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
3932 (Ops[3] << 3) | (Ops[4]);
3939bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *
N) {
3940 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
3941 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
3946 unsigned Opcode64Bit = AArch64::MRS;
3951 const auto *TheReg =
3953 if (TheReg && TheReg->Readable &&
3954 TheReg->haveFeatures(Subtarget->getFeatureBits()))
3955 Imm = TheReg->Encoding;
3961 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
3962 Opcode64Bit = AArch64::ADR;
3970 SDValue InChain =
N->getOperand(0);
3971 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
3972 if (!ReadIs128Bit) {
3973 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
3974 {SysRegImm, InChain});
3978 {MVT::Untyped , MVT::Other },
3979 {SysRegImm, InChain});
3983 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
3985 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
3991 ReplaceUses(
SDValue(
N, 2), OutChain);
4000bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *
N) {
4001 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4002 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4007 if (!WriteIs128Bit) {
4013 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4015 assert(isa<ConstantSDNode>(
N->getOperand(2)) &&
4016 "Expected a constant integer expression.");
4017 unsigned Reg = PMapper->Encoding;
4018 uint64_t Immed =
N->getConstantOperandVal(2);
4019 CurDAG->SelectNodeTo(
4020 N, State, MVT::Other, CurDAG->getTargetConstant(Reg,
DL, MVT::i32),
4021 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4027 if (trySelectPState(
4028 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4029 AArch64::MSRpstateImm4))
4031 if (trySelectPState(
4032 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4033 AArch64::MSRpstateImm1))
4043 if (TheReg && TheReg->Writeable &&
4044 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4045 Imm = TheReg->Encoding;
4053 SDValue InChain =
N->getOperand(0);
4054 if (!WriteIs128Bit) {
4055 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4056 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4057 N->getOperand(2), InChain);
4061 SDNode *Pair = CurDAG->getMachineNode(
4062 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4063 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4066 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4068 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4070 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4071 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4079bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *
N) {
4081 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
4084 if (Subtarget->hasLSE())
return false;
4086 if (MemTy == MVT::i8)
4087 Opcode = AArch64::CMP_SWAP_8;
4088 else if (MemTy == MVT::i16)
4089 Opcode = AArch64::CMP_SWAP_16;
4090 else if (MemTy == MVT::i32)
4091 Opcode = AArch64::CMP_SWAP_32;
4092 else if (MemTy == MVT::i64)
4093 Opcode = AArch64::CMP_SWAP_64;
4097 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4098 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4100 SDNode *CmpSwap = CurDAG->getMachineNode(
4102 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
4105 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {
MemOp});
4109 CurDAG->RemoveDeadNode(
N);
4116 if (!isa<ConstantSDNode>(
N))
4128 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4129 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4136 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4137 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4141 if (Val <= 65280 && Val % 256 == 0) {
4142 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4143 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4154bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N,
MVT VT,
4157 if (!isa<ConstantSDNode>(
N))
4161 int64_t Val = cast<ConstantSDNode>(
N)
4178 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4179 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4186 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4187 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4191 if (Val <= 65280 && Val % 256 == 0) {
4192 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4193 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4206 if (!isa<ConstantSDNode>(
N))
4210 int64_t Val = cast<ConstantSDNode>(
N)
4218 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4219 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4225 if (Val >= -128 && Val <= 127) {
4226 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4227 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4231 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) {
4232 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4233 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF,
DL, MVT::i32);
4244bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4245 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4246 int64_t ImmVal = CNode->getSExtValue();
4248 if (ImmVal >= -128 && ImmVal < 128) {
4249 Imm = CurDAG->getSignedConstant(ImmVal,
DL, MVT::i32,
true);
4257 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4258 uint64_t ImmVal = CNode->getZExtValue();
4268 ImmVal &= 0xFFFFFFFF;
4277 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4286 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4287 uint64_t ImmVal = CNode->getZExtValue();
4297 ImmVal |= ImmVal << 8;
4298 ImmVal |= ImmVal << 16;
4299 ImmVal |= ImmVal << 32;
4303 ImmVal |= ImmVal << 16;
4304 ImmVal |= ImmVal << 32;
4307 ImmVal &= 0xFFFFFFFF;
4308 ImmVal |= ImmVal << 32;
4318 Imm = CurDAG->getTargetConstant(encoding,
DL, MVT::i64);
4333 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
4334 uint64_t ImmVal = CN->getZExtValue();
4341 if (ImmVal >
High) {
4342 if (!AllowSaturation)
4347 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4354bool AArch64DAGToDAGISel::trySelectStackSlotTagP(
SDNode *
N) {
4358 if (!(isa<FrameIndexSDNode>(
N->getOperand(1)))) {
4370 int FI = cast<FrameIndexSDNode>(
N->getOperand(1))->getIndex();
4371 SDValue FiOp = CurDAG->getTargetFrameIndex(
4373 int TagOffset =
N->getConstantOperandVal(3);
4375 SDNode *Out = CurDAG->getMachineNode(
4376 AArch64::TAGPstack,
DL, MVT::i64,
4377 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->getOperand(2),
4378 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4379 ReplaceNode(
N, Out);
4383void AArch64DAGToDAGISel::SelectTagP(
SDNode *
N) {
4384 assert(isa<ConstantSDNode>(
N->getOperand(3)) &&
4385 "llvm.aarch64.tagp third argument must be an immediate");
4386 if (trySelectStackSlotTagP(
N))
4393 int TagOffset =
N->getConstantOperandVal(3);
4394 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4395 {
N->getOperand(1),
N->getOperand(2)});
4396 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4397 {
SDValue(N1, 0),
N->getOperand(2)});
4398 SDNode *N3 = CurDAG->getMachineNode(
4399 AArch64::ADDG,
DL, MVT::i64,
4400 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4401 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4405bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(
SDNode *
N) {
4409 if (
N->getConstantOperandVal(2) != 0)
4411 if (!
N->getOperand(0).isUndef())
4415 EVT VT =
N->getValueType(0);
4416 EVT InVT =
N->getOperand(1).getValueType();
4427 "Expected to insert into a packed scalable vector!");
4430 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4431 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4432 N->getOperand(1), RC));
4436bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(
SDNode *
N) {
4440 if (
N->getConstantOperandVal(1) != 0)
4444 EVT VT =
N->getValueType(0);
4445 EVT InVT =
N->getOperand(0).getValueType();
4456 "Expected to extract from a packed scalable vector!");
4459 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4460 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4461 N->getOperand(0), RC));
4465bool AArch64DAGToDAGISel::trySelectXAR(
SDNode *
N) {
4470 EVT VT =
N->getValueType(0);
4482 (Subtarget->hasSVE2() ||
4483 (Subtarget->hasSME() && Subtarget->isStreaming()))) {
4492 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4493 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4500 APInt ShlAmt, ShrAmt;
4513 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4514 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4515 AArch64::XAR_ZZZI_D})) {
4516 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
4522 if (!Subtarget->hasSHA3())
4544 if (ShAmt + HsAmt != 64)
4548 CurDAG->SelectNodeTo(
N, AArch64::XAR, N0.
getValueType(), Ops);
4553void AArch64DAGToDAGISel::Select(
SDNode *
Node) {
4555 if (
Node->isMachineOpcode()) {
4557 Node->setNodeId(-1);
4562 EVT VT =
Node->getValueType(0);
4564 switch (
Node->getOpcode()) {
4569 if (SelectCMP_SWAP(
Node))
4575 if (tryReadRegister(
Node))
4581 if (tryWriteRegister(
Node))
4588 if (tryIndexedLoad(
Node))
4597 if (tryBitfieldExtractOp(
Node))
4599 if (tryBitfieldInsertInZeroOp(
Node))
4604 if (tryShiftAmountMod(
Node))
4609 if (tryBitfieldExtractOpFromSExt(
Node))
4614 if (tryBitfieldInsertOp(
Node))
4616 if (trySelectXAR(
Node))
4621 if (trySelectCastScalableToFixedLengthVector(
Node))
4627 if (trySelectCastFixedLengthToScalableVector(
Node))
4636 if (ConstNode->
isZero()) {
4637 if (VT == MVT::i32) {
4639 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::WZR, MVT::i32);
4640 ReplaceNode(
Node,
New.getNode());
4642 }
else if (VT == MVT::i64) {
4644 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::XZR, MVT::i64);
4645 ReplaceNode(
Node,
New.getNode());
4654 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
4657 SDValue TFI = CurDAG->getTargetFrameIndex(
4660 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4661 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4662 CurDAG->SelectNodeTo(
Node, AArch64::ADDXri, MVT::i64, Ops);
4666 unsigned IntNo =
Node->getConstantOperandVal(1);
4670 case Intrinsic::aarch64_gcsss: {
4674 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4676 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4677 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4678 MVT::Other, Zero,
SDValue(SS1, 0));
4679 ReplaceNode(
Node, SS2);
4682 case Intrinsic::aarch64_ldaxp:
4683 case Intrinsic::aarch64_ldxp: {
4685 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4690 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4691 MVT::Other, MemAddr, Chain);
4695 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4696 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
4697 ReplaceNode(
Node, Ld);
4700 case Intrinsic::aarch64_stlxp:
4701 case Intrinsic::aarch64_stxp: {
4703 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4711 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4713 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other, Ops);
4716 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4717 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
4719 ReplaceNode(
Node, St);
4722 case Intrinsic::aarch64_neon_ld1x2:
4723 if (VT == MVT::v8i8) {
4724 SelectLoad(
Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4726 }
else if (VT == MVT::v16i8) {
4727 SelectLoad(
Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4729 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4730 SelectLoad(
Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4732 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4733 SelectLoad(
Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4735 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4736 SelectLoad(
Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4738 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4739 SelectLoad(
Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4741 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4742 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4744 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4745 SelectLoad(
Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4749 case Intrinsic::aarch64_neon_ld1x3:
4750 if (VT == MVT::v8i8) {
4751 SelectLoad(
Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
4753 }
else if (VT == MVT::v16i8) {
4754 SelectLoad(
Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
4756 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4757 SelectLoad(
Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
4759 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4760 SelectLoad(
Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
4762 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4763 SelectLoad(
Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
4765 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4766 SelectLoad(
Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
4768 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4769 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4771 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4772 SelectLoad(
Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
4776 case Intrinsic::aarch64_neon_ld1x4:
4777 if (VT == MVT::v8i8) {
4778 SelectLoad(
Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
4780 }
else if (VT == MVT::v16i8) {
4781 SelectLoad(
Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
4783 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4784 SelectLoad(
Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
4786 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4787 SelectLoad(
Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
4789 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4790 SelectLoad(
Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
4792 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4793 SelectLoad(
Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
4795 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4796 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4798 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4799 SelectLoad(
Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
4803 case Intrinsic::aarch64_neon_ld2:
4804 if (VT == MVT::v8i8) {
4805 SelectLoad(
Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
4807 }
else if (VT == MVT::v16i8) {
4808 SelectLoad(
Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
4810 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4811 SelectLoad(
Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
4813 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4814 SelectLoad(
Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
4816 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4817 SelectLoad(
Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
4819 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4820 SelectLoad(
Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
4822 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4823 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4825 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4826 SelectLoad(
Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
4830 case Intrinsic::aarch64_neon_ld3:
4831 if (VT == MVT::v8i8) {
4832 SelectLoad(
Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
4834 }
else if (VT == MVT::v16i8) {
4835 SelectLoad(
Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
4837 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4838 SelectLoad(
Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
4840 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4841 SelectLoad(
Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
4843 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4844 SelectLoad(
Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
4846 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4847 SelectLoad(
Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
4849 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4850 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4852 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4853 SelectLoad(
Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
4857 case Intrinsic::aarch64_neon_ld4:
4858 if (VT == MVT::v8i8) {
4859 SelectLoad(
Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
4861 }
else if (VT == MVT::v16i8) {
4862 SelectLoad(
Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
4864 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4865 SelectLoad(
Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
4867 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4868 SelectLoad(
Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
4870 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4871 SelectLoad(
Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
4873 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4874 SelectLoad(
Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
4876 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4877 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4879 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4880 SelectLoad(
Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
4884 case Intrinsic::aarch64_neon_ld2r:
4885 if (VT == MVT::v8i8) {
4886 SelectLoad(
Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
4888 }
else if (VT == MVT::v16i8) {
4889 SelectLoad(
Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
4891 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4892 SelectLoad(
Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
4894 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4895 SelectLoad(
Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
4897 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4898 SelectLoad(
Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
4900 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4901 SelectLoad(
Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
4903 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4904 SelectLoad(
Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
4906 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4907 SelectLoad(
Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
4911 case Intrinsic::aarch64_neon_ld3r:
4912 if (VT == MVT::v8i8) {
4913 SelectLoad(
Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
4915 }
else if (VT == MVT::v16i8) {
4916 SelectLoad(
Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
4918 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4919 SelectLoad(
Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
4921 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4922 SelectLoad(
Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
4924 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4925 SelectLoad(
Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
4927 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4928 SelectLoad(
Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
4930 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4931 SelectLoad(
Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
4933 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4934 SelectLoad(
Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
4938 case Intrinsic::aarch64_neon_ld4r:
4939 if (VT == MVT::v8i8) {
4940 SelectLoad(
Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
4942 }
else if (VT == MVT::v16i8) {
4943 SelectLoad(
Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
4945 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4946 SelectLoad(
Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
4948 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4949 SelectLoad(
Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
4951 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4952 SelectLoad(
Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
4954 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4955 SelectLoad(
Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
4957 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4958 SelectLoad(
Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
4960 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4961 SelectLoad(
Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
4965 case Intrinsic::aarch64_neon_ld2lane:
4966 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4967 SelectLoadLane(
Node, 2, AArch64::LD2i8);
4969 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4970 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4971 SelectLoadLane(
Node, 2, AArch64::LD2i16);
4973 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4975 SelectLoadLane(
Node, 2, AArch64::LD2i32);
4977 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4979 SelectLoadLane(
Node, 2, AArch64::LD2i64);
4983 case Intrinsic::aarch64_neon_ld3lane:
4984 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
4985 SelectLoadLane(
Node, 3, AArch64::LD3i8);
4987 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
4988 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
4989 SelectLoadLane(
Node, 3, AArch64::LD3i16);
4991 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
4993 SelectLoadLane(
Node, 3, AArch64::LD3i32);
4995 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
4997 SelectLoadLane(
Node, 3, AArch64::LD3i64);
5001 case Intrinsic::aarch64_neon_ld4lane:
5002 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5003 SelectLoadLane(
Node, 4, AArch64::LD4i8);
5005 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5006 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5007 SelectLoadLane(
Node, 4, AArch64::LD4i16);
5009 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5011 SelectLoadLane(
Node, 4, AArch64::LD4i32);
5013 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5015 SelectLoadLane(
Node, 4, AArch64::LD4i64);
5019 case Intrinsic::aarch64_ld64b:
5020 SelectLoad(
Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5022 case Intrinsic::aarch64_sve_ld2q_sret: {
5023 SelectPredicatedLoad(
Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5026 case Intrinsic::aarch64_sve_ld3q_sret: {
5027 SelectPredicatedLoad(
Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5030 case Intrinsic::aarch64_sve_ld4q_sret: {
5031 SelectPredicatedLoad(
Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5034 case Intrinsic::aarch64_sve_ld2_sret: {
5035 if (VT == MVT::nxv16i8) {
5036 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5039 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5040 VT == MVT::nxv8bf16) {
5041 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5044 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5045 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5048 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5049 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5055 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5056 if (VT == MVT::nxv16i8) {
5057 if (Subtarget->hasSME2())
5058 SelectContiguousMultiVectorLoad(
5059 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5060 else if (Subtarget->hasSVE2p1())
5061 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LD1B_2Z_IMM,
5066 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5067 VT == MVT::nxv8bf16) {
5068 if (Subtarget->hasSME2())
5069 SelectContiguousMultiVectorLoad(
5070 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5071 else if (Subtarget->hasSVE2p1())
5072 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LD1H_2Z_IMM,
5077 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5078 if (Subtarget->hasSME2())
5079 SelectContiguousMultiVectorLoad(
5080 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5081 else if (Subtarget->hasSVE2p1())
5082 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LD1W_2Z_IMM,
5087 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5088 if (Subtarget->hasSME2())
5089 SelectContiguousMultiVectorLoad(
5090 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5091 else if (Subtarget->hasSVE2p1())
5092 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LD1D_2Z_IMM,
5100 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5101 if (VT == MVT::nxv16i8) {
5102 if (Subtarget->hasSME2())
5103 SelectContiguousMultiVectorLoad(
5104 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5105 else if (Subtarget->hasSVE2p1())
5106 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LD1B_4Z_IMM,
5111 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5112 VT == MVT::nxv8bf16) {
5113 if (Subtarget->hasSME2())
5114 SelectContiguousMultiVectorLoad(
5115 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5116 else if (Subtarget->hasSVE2p1())
5117 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LD1H_4Z_IMM,
5122 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5123 if (Subtarget->hasSME2())
5124 SelectContiguousMultiVectorLoad(
5125 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5126 else if (Subtarget->hasSVE2p1())
5127 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LD1W_4Z_IMM,
5132 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5133 if (Subtarget->hasSME2())
5134 SelectContiguousMultiVectorLoad(
5135 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5136 else if (Subtarget->hasSVE2p1())
5137 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LD1D_4Z_IMM,
5145 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5146 if (VT == MVT::nxv16i8) {
5147 if (Subtarget->hasSME2())
5148 SelectContiguousMultiVectorLoad(
Node, 2, 0,
5149 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5150 AArch64::LDNT1B_2Z_PSEUDO);
5151 else if (Subtarget->hasSVE2p1())
5152 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5153 AArch64::LDNT1B_2Z);
5157 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5158 VT == MVT::nxv8bf16) {
5159 if (Subtarget->hasSME2())
5160 SelectContiguousMultiVectorLoad(
Node, 2, 1,
5161 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5162 AArch64::LDNT1H_2Z_PSEUDO);
5163 else if (Subtarget->hasSVE2p1())
5164 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5165 AArch64::LDNT1H_2Z);
5169 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5170 if (Subtarget->hasSME2())
5171 SelectContiguousMultiVectorLoad(
Node, 2, 2,
5172 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5173 AArch64::LDNT1W_2Z_PSEUDO);
5174 else if (Subtarget->hasSVE2p1())
5175 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5176 AArch64::LDNT1W_2Z);
5180 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5181 if (Subtarget->hasSME2())
5182 SelectContiguousMultiVectorLoad(
Node, 2, 3,
5183 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5184 AArch64::LDNT1D_2Z_PSEUDO);
5185 else if (Subtarget->hasSVE2p1())
5186 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5187 AArch64::LDNT1D_2Z);
5194 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5195 if (VT == MVT::nxv16i8) {
5196 if (Subtarget->hasSME2())
5197 SelectContiguousMultiVectorLoad(
Node, 4, 0,
5198 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5199 AArch64::LDNT1B_4Z_PSEUDO);
5200 else if (Subtarget->hasSVE2p1())
5201 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5202 AArch64::LDNT1B_4Z);
5206 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5207 VT == MVT::nxv8bf16) {
5208 if (Subtarget->hasSME2())
5209 SelectContiguousMultiVectorLoad(
Node, 4, 1,
5210 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5211 AArch64::LDNT1H_4Z_PSEUDO);
5212 else if (Subtarget->hasSVE2p1())
5213 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5214 AArch64::LDNT1H_4Z);
5218 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5219 if (Subtarget->hasSME2())
5220 SelectContiguousMultiVectorLoad(
Node, 4, 2,
5221 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5222 AArch64::LDNT1W_4Z_PSEUDO);
5223 else if (Subtarget->hasSVE2p1())
5224 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5225 AArch64::LDNT1W_4Z);
5229 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5230 if (Subtarget->hasSME2())
5231 SelectContiguousMultiVectorLoad(
Node, 4, 3,
5232 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5233 AArch64::LDNT1D_4Z_PSEUDO);
5234 else if (Subtarget->hasSVE2p1())
5235 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5236 AArch64::LDNT1D_4Z);
5243 case Intrinsic::aarch64_sve_ld3_sret: {
5244 if (VT == MVT::nxv16i8) {
5245 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5248 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5249 VT == MVT::nxv8bf16) {
5250 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5253 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5254 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5257 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5258 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5264 case Intrinsic::aarch64_sve_ld4_sret: {
5265 if (VT == MVT::nxv16i8) {
5266 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5269 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5270 VT == MVT::nxv8bf16) {
5271 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5274 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5275 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5278 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5279 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5285 case Intrinsic::aarch64_sme_read_hor_vg2: {
5286 if (VT == MVT::nxv16i8) {
5287 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5288 AArch64::MOVA_2ZMXI_H_B);
5290 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5291 VT == MVT::nxv8bf16) {
5292 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5293 AArch64::MOVA_2ZMXI_H_H);
5295 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5296 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5297 AArch64::MOVA_2ZMXI_H_S);
5299 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5300 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5301 AArch64::MOVA_2ZMXI_H_D);
5306 case Intrinsic::aarch64_sme_read_ver_vg2: {
5307 if (VT == MVT::nxv16i8) {
5308 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5309 AArch64::MOVA_2ZMXI_V_B);
5311 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5312 VT == MVT::nxv8bf16) {
5313 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5314 AArch64::MOVA_2ZMXI_V_H);
5316 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5317 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5318 AArch64::MOVA_2ZMXI_V_S);
5320 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5321 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5322 AArch64::MOVA_2ZMXI_V_D);
5327 case Intrinsic::aarch64_sme_read_hor_vg4: {
5328 if (VT == MVT::nxv16i8) {
5329 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5330 AArch64::MOVA_4ZMXI_H_B);
5332 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5333 VT == MVT::nxv8bf16) {
5334 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5335 AArch64::MOVA_4ZMXI_H_H);
5337 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5338 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAS0,
5339 AArch64::MOVA_4ZMXI_H_S);
5341 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5342 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAD0,
5343 AArch64::MOVA_4ZMXI_H_D);
5348 case Intrinsic::aarch64_sme_read_ver_vg4: {
5349 if (VT == MVT::nxv16i8) {
5350 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5351 AArch64::MOVA_4ZMXI_V_B);
5353 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5354 VT == MVT::nxv8bf16) {
5355 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5356 AArch64::MOVA_4ZMXI_V_H);
5358 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5359 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAS0,
5360 AArch64::MOVA_4ZMXI_V_S);
5362 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5363 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAD0,
5364 AArch64::MOVA_4ZMXI_V_D);
5369 case Intrinsic::aarch64_sme_read_vg1x2: {
5370 SelectMultiVectorMove<7, 1>(
Node, 2, AArch64::ZA,
5371 AArch64::MOVA_VG2_2ZMXI);
5374 case Intrinsic::aarch64_sme_read_vg1x4: {
5375 SelectMultiVectorMove<7, 1>(
Node, 4, AArch64::ZA,
5376 AArch64::MOVA_VG4_4ZMXI);
5379 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5380 if (VT == MVT::nxv16i8) {
5381 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5383 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5384 VT == MVT::nxv8bf16) {
5385 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5387 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5388 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5390 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5391 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5396 case Intrinsic::aarch64_sme_readz_vert_x2: {
5397 if (VT == MVT::nxv16i8) {
5398 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5400 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5401 VT == MVT::nxv8bf16) {
5402 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5404 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5405 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5407 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5408 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5413 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5414 if (VT == MVT::nxv16i8) {
5415 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5417 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5418 VT == MVT::nxv8bf16) {
5419 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5421 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5422 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5424 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5425 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5430 case Intrinsic::aarch64_sme_readz_vert_x4: {
5431 if (VT == MVT::nxv16i8) {
5432 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5434 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5435 VT == MVT::nxv8bf16) {
5436 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5438 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5439 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5441 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5442 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5447 case Intrinsic::aarch64_sme_readz_x2: {
5448 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5452 case Intrinsic::aarch64_sme_readz_x4: {
5453 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5457 case Intrinsic::swift_async_context_addr: {
5460 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5462 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5463 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5464 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5468 CurDAG->RemoveDeadNode(
Node);
5470 auto &MF = CurDAG->getMachineFunction();
5471 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5475 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5476 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5477 Node->getValueType(0),
5478 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5479 AArch64::LUTI2_4ZTZI_S}))
5481 SelectMultiVectorLuti(
Node, 4, Opc, 3);
5484 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5485 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5486 Node->getValueType(0),
5487 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5489 SelectMultiVectorLuti(
Node, 4, Opc, 1);
5492 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5493 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5494 Node->getValueType(0),
5495 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5496 AArch64::LUTI2_2ZTZI_S}))
5498 SelectMultiVectorLuti(
Node, 2, Opc, 7);
5501 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5502 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5503 Node->getValueType(0),
5504 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5505 AArch64::LUTI4_2ZTZI_S}))
5507 SelectMultiVectorLuti(
Node, 2, Opc, 3);
5513 unsigned IntNo =
Node->getConstantOperandVal(0);
5517 case Intrinsic::aarch64_tagp:
5521 case Intrinsic::ptrauth_auth:
5522 SelectPtrauthAuth(
Node);
5525 case Intrinsic::ptrauth_resign:
5526 SelectPtrauthResign(
Node);
5529 case Intrinsic::aarch64_neon_tbl2:
5530 SelectTable(
Node, 2,
5531 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5534 case Intrinsic::aarch64_neon_tbl3:
5535 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5536 : AArch64::TBLv16i8Three,
5539 case Intrinsic::aarch64_neon_tbl4:
5540 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5541 : AArch64::TBLv16i8Four,
5544 case Intrinsic::aarch64_neon_tbx2:
5545 SelectTable(
Node, 2,
5546 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5549 case Intrinsic::aarch64_neon_tbx3:
5550 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5551 : AArch64::TBXv16i8Three,
5554 case Intrinsic::aarch64_neon_tbx4:
5555 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5556 : AArch64::TBXv16i8Four,
5559 case Intrinsic::aarch64_sve_srshl_single_x2:
5560 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5561 Node->getValueType(0),
5562 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5563 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5564 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5566 case Intrinsic::aarch64_sve_srshl_single_x4:
5567 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5568 Node->getValueType(0),
5569 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5570 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5571 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5573 case Intrinsic::aarch64_sve_urshl_single_x2:
5574 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5575 Node->getValueType(0),
5576 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5577 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5578 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5580 case Intrinsic::aarch64_sve_urshl_single_x4:
5581 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5582 Node->getValueType(0),
5583 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5584 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5585 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5587 case Intrinsic::aarch64_sve_srshl_x2:
5588 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5589 Node->getValueType(0),
5590 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5591 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5592 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5594 case Intrinsic::aarch64_sve_srshl_x4:
5595 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5596 Node->getValueType(0),
5597 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5598 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5599 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5601 case Intrinsic::aarch64_sve_urshl_x2:
5602 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5603 Node->getValueType(0),
5604 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5605 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5606 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5608 case Intrinsic::aarch64_sve_urshl_x4:
5609 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5610 Node->getValueType(0),
5611 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5612 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5613 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5615 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5616 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5617 Node->getValueType(0),
5618 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5619 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5620 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5622 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5623 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5624 Node->getValueType(0),
5625 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5626 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5627 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5629 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5630 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5631 Node->getValueType(0),
5632 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5633 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5634 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5636 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5637 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5638 Node->getValueType(0),
5639 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5640 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5641 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5643 case Intrinsic::aarch64_sve_whilege_x2:
5644 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5645 Node->getValueType(0),
5646 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5647 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5648 SelectWhilePair(
Node,
Op);
5650 case Intrinsic::aarch64_sve_whilegt_x2:
5651 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5652 Node->getValueType(0),
5653 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5654 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5655 SelectWhilePair(
Node,
Op);
5657 case Intrinsic::aarch64_sve_whilehi_x2:
5658 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5659 Node->getValueType(0),
5660 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5661 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5662 SelectWhilePair(
Node,
Op);
5664 case Intrinsic::aarch64_sve_whilehs_x2:
5665 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5666 Node->getValueType(0),
5667 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5668 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5669 SelectWhilePair(
Node,
Op);
5671 case Intrinsic::aarch64_sve_whilele_x2:
5672 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5673 Node->getValueType(0),
5674 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5675 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5676 SelectWhilePair(
Node,
Op);
5678 case Intrinsic::aarch64_sve_whilelo_x2:
5679 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5680 Node->getValueType(0),
5681 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5682 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5683 SelectWhilePair(
Node,
Op);
5685 case Intrinsic::aarch64_sve_whilels_x2:
5686 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5687 Node->getValueType(0),
5688 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5689 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5690 SelectWhilePair(
Node,
Op);
5692 case Intrinsic::aarch64_sve_whilelt_x2:
5693 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5694 Node->getValueType(0),
5695 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
5696 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
5697 SelectWhilePair(
Node,
Op);
5699 case Intrinsic::aarch64_sve_smax_single_x2:
5700 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5701 Node->getValueType(0),
5702 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
5703 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
5704 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5706 case Intrinsic::aarch64_sve_umax_single_x2:
5707 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5708 Node->getValueType(0),
5709 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
5710 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
5711 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5713 case Intrinsic::aarch64_sve_fmax_single_x2:
5714 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5715 Node->getValueType(0),
5716 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
5717 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
5718 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5720 case Intrinsic::aarch64_sve_smax_single_x4:
5721 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5722 Node->getValueType(0),
5723 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
5724 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
5725 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5727 case Intrinsic::aarch64_sve_umax_single_x4:
5728 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5729 Node->getValueType(0),
5730 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
5731 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
5732 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5734 case Intrinsic::aarch64_sve_fmax_single_x4:
5735 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5736 Node->getValueType(0),
5737 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
5738 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
5739 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5741 case Intrinsic::aarch64_sve_smin_single_x2:
5742 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5743 Node->getValueType(0),
5744 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
5745 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
5746 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5748 case Intrinsic::aarch64_sve_umin_single_x2:
5749 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5750 Node->getValueType(0),
5751 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
5752 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
5753 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5755 case Intrinsic::aarch64_sve_fmin_single_x2:
5756 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5757 Node->getValueType(0),
5758 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
5759 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
5760 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5762 case Intrinsic::aarch64_sve_smin_single_x4:
5763 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5764 Node->getValueType(0),
5765 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
5766 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
5767 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5769 case Intrinsic::aarch64_sve_umin_single_x4:
5770 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5771 Node->getValueType(0),
5772 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
5773 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
5774 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5776 case Intrinsic::aarch64_sve_fmin_single_x4:
5777 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5778 Node->getValueType(0),
5779 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
5780 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
5781 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5783 case Intrinsic::aarch64_sve_smax_x2:
5784 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5785 Node->getValueType(0),
5786 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
5787 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
5788 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5790 case Intrinsic::aarch64_sve_umax_x2:
5791 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5792 Node->getValueType(0),
5793 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
5794 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
5795 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5797 case Intrinsic::aarch64_sve_fmax_x2:
5798 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5799 Node->getValueType(0),
5800 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
5801 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
5802 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5804 case Intrinsic::aarch64_sve_smax_x4:
5805 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5806 Node->getValueType(0),
5807 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
5808 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
5809 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5811 case Intrinsic::aarch64_sve_umax_x4:
5812 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5813 Node->getValueType(0),
5814 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
5815 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
5816 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5818 case Intrinsic::aarch64_sve_fmax_x4:
5819 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5820 Node->getValueType(0),
5821 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
5822 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
5823 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5825 case Intrinsic::aarch64_sve_smin_x2:
5826 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5827 Node->getValueType(0),
5828 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
5829 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
5830 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5832 case Intrinsic::aarch64_sve_umin_x2:
5833 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5834 Node->getValueType(0),
5835 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
5836 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
5837 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5839 case Intrinsic::aarch64_sve_fmin_x2:
5840 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5841 Node->getValueType(0),
5842 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
5843 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
5844 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5846 case Intrinsic::aarch64_sve_smin_x4:
5847 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5848 Node->getValueType(0),
5849 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
5850 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
5851 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5853 case Intrinsic::aarch64_sve_umin_x4:
5854 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5855 Node->getValueType(0),
5856 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
5857 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
5858 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5860 case Intrinsic::aarch64_sve_fmin_x4:
5861 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5862 Node->getValueType(0),
5863 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
5864 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
5865 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5867 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
5868 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5869 Node->getValueType(0),
5870 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
5871 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
5872 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5874 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
5875 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5876 Node->getValueType(0),
5877 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
5878 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
5879 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5881 case Intrinsic::aarch64_sve_fminnm_single_x2:
5882 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5883 Node->getValueType(0),
5884 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
5885 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
5886 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5888 case Intrinsic::aarch64_sve_fminnm_single_x4:
5889 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5890 Node->getValueType(0),
5891 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
5892 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
5893 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5895 case Intrinsic::aarch64_sve_fmaxnm_x2:
5896 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5897 Node->getValueType(0),
5898 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
5899 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
5900 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5902 case Intrinsic::aarch64_sve_fmaxnm_x4:
5903 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5904 Node->getValueType(0),
5905 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
5906 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
5907 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5909 case Intrinsic::aarch64_sve_fminnm_x2:
5910 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5911 Node->getValueType(0),
5912 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
5913 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
5914 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5916 case Intrinsic::aarch64_sve_fminnm_x4:
5917 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5918 Node->getValueType(0),
5919 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
5920 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
5921 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5923 case Intrinsic::aarch64_sve_fcvtzs_x2:
5924 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
5926 case Intrinsic::aarch64_sve_scvtf_x2:
5927 SelectCVTIntrinsic(
Node, 2, AArch64::SCVTF_2Z2Z_StoS);
5929 case Intrinsic::aarch64_sve_fcvtzu_x2:
5930 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
5932 case Intrinsic::aarch64_sve_ucvtf_x2:
5933 SelectCVTIntrinsic(
Node, 2, AArch64::UCVTF_2Z2Z_StoS);
5935 case Intrinsic::aarch64_sve_fcvtzs_x4:
5936 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
5938 case Intrinsic::aarch64_sve_scvtf_x4:
5939 SelectCVTIntrinsic(
Node, 4, AArch64::SCVTF_4Z4Z_StoS);
5941 case Intrinsic::aarch64_sve_fcvtzu_x4:
5942 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
5944 case Intrinsic::aarch64_sve_ucvtf_x4:
5945 SelectCVTIntrinsic(
Node, 4, AArch64::UCVTF_4Z4Z_StoS);
5947 case Intrinsic::aarch64_sve_fcvt_widen_x2:
5948 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
5950 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
5951 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
5953 case Intrinsic::aarch64_sve_sclamp_single_x2:
5954 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5955 Node->getValueType(0),
5956 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
5957 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
5958 SelectClamp(
Node, 2,
Op);
5960 case Intrinsic::aarch64_sve_uclamp_single_x2:
5961 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5962 Node->getValueType(0),
5963 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
5964 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
5965 SelectClamp(
Node, 2,
Op);
5967 case Intrinsic::aarch64_sve_fclamp_single_x2:
5968 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5969 Node->getValueType(0),
5970 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
5971 AArch64::FCLAMP_VG2_2Z2Z_D}))
5972 SelectClamp(
Node, 2,
Op);
5974 case Intrinsic::aarch64_sve_bfclamp_single_x2:
5975 SelectClamp(
Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
5977 case Intrinsic::aarch64_sve_sclamp_single_x4:
5978 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5979 Node->getValueType(0),
5980 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
5981 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
5982 SelectClamp(
Node, 4,
Op);
5984 case Intrinsic::aarch64_sve_uclamp_single_x4:
5985 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5986 Node->getValueType(0),
5987 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
5988 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
5989 SelectClamp(
Node, 4,
Op);
5991 case Intrinsic::aarch64_sve_fclamp_single_x4:
5992 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5993 Node->getValueType(0),
5994 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
5995 AArch64::FCLAMP_VG4_4Z4Z_D}))
5996 SelectClamp(
Node, 4,
Op);
5998 case Intrinsic::aarch64_sve_bfclamp_single_x4:
5999 SelectClamp(
Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6001 case Intrinsic::aarch64_sve_add_single_x2:
6002 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6003 Node->getValueType(0),
6004 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6005 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6006 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6008 case Intrinsic::aarch64_sve_add_single_x4:
6009 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6010 Node->getValueType(0),
6011 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6012 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6013 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6015 case Intrinsic::aarch64_sve_zip_x2:
6016 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6017 Node->getValueType(0),
6018 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6019 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6020 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6022 case Intrinsic::aarch64_sve_zipq_x2:
6023 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6024 AArch64::ZIP_VG2_2ZZZ_Q);
6026 case Intrinsic::aarch64_sve_zip_x4:
6027 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6028 Node->getValueType(0),
6029 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6030 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6031 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6033 case Intrinsic::aarch64_sve_zipq_x4:
6034 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6035 AArch64::ZIP_VG4_4Z4Z_Q);
6037 case Intrinsic::aarch64_sve_uzp_x2:
6038 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6039 Node->getValueType(0),
6040 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6041 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6042 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6044 case Intrinsic::aarch64_sve_uzpq_x2:
6045 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6046 AArch64::UZP_VG2_2ZZZ_Q);
6048 case Intrinsic::aarch64_sve_uzp_x4:
6049 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6050 Node->getValueType(0),
6051 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6052 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6053 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6055 case Intrinsic::aarch64_sve_uzpq_x4:
6056 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6057 AArch64::UZP_VG4_4Z4Z_Q);
6059 case Intrinsic::aarch64_sve_sel_x2:
6060 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6061 Node->getValueType(0),
6062 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6063 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6064 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op,
true);
6066 case Intrinsic::aarch64_sve_sel_x4:
6067 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6068 Node->getValueType(0),
6069 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6070 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6071 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op,
true);
6073 case Intrinsic::aarch64_sve_frinta_x2:
6074 SelectFrintFromVT(
Node, 2, AArch64::FRINTA_2Z2Z_S);
6076 case Intrinsic::aarch64_sve_frinta_x4:
6077 SelectFrintFromVT(
Node, 4, AArch64::FRINTA_4Z4Z_S);
6079 case Intrinsic::aarch64_sve_frintm_x2:
6080 SelectFrintFromVT(
Node, 2, AArch64::FRINTM_2Z2Z_S);
6082 case Intrinsic::aarch64_sve_frintm_x4:
6083 SelectFrintFromVT(
Node, 4, AArch64::FRINTM_4Z4Z_S);
6085 case Intrinsic::aarch64_sve_frintn_x2:
6086 SelectFrintFromVT(
Node, 2, AArch64::FRINTN_2Z2Z_S);
6088 case Intrinsic::aarch64_sve_frintn_x4:
6089 SelectFrintFromVT(
Node, 4, AArch64::FRINTN_4Z4Z_S);
6091 case Intrinsic::aarch64_sve_frintp_x2:
6092 SelectFrintFromVT(
Node, 2, AArch64::FRINTP_2Z2Z_S);
6094 case Intrinsic::aarch64_sve_frintp_x4:
6095 SelectFrintFromVT(
Node, 4, AArch64::FRINTP_4Z4Z_S);
6097 case Intrinsic::aarch64_sve_sunpk_x2:
6098 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6099 Node->getValueType(0),
6100 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6101 AArch64::SUNPK_VG2_2ZZ_D}))
6102 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6104 case Intrinsic::aarch64_sve_uunpk_x2:
6105 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6106 Node->getValueType(0),
6107 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6108 AArch64::UUNPK_VG2_2ZZ_D}))
6109 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6111 case Intrinsic::aarch64_sve_sunpk_x4:
6112 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6113 Node->getValueType(0),
6114 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6115 AArch64::SUNPK_VG4_4Z2Z_D}))
6116 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6118 case Intrinsic::aarch64_sve_uunpk_x4:
6119 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6120 Node->getValueType(0),
6121 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6122 AArch64::UUNPK_VG4_4Z2Z_D}))
6123 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6125 case Intrinsic::aarch64_sve_pext_x2: {
6126 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6127 Node->getValueType(0),
6128 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6129 AArch64::PEXT_2PCI_D}))
6130 SelectPExtPair(
Node,
Op);
6137 unsigned IntNo =
Node->getConstantOperandVal(1);
6138 if (
Node->getNumOperands() >= 3)
6139 VT =
Node->getOperand(2)->getValueType(0);
6143 case Intrinsic::aarch64_neon_st1x2: {
6144 if (VT == MVT::v8i8) {
6145 SelectStore(
Node, 2, AArch64::ST1Twov8b);
6147 }
else if (VT == MVT::v16i8) {
6148 SelectStore(
Node, 2, AArch64::ST1Twov16b);
6150 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6151 VT == MVT::v4bf16) {
6152 SelectStore(
Node, 2, AArch64::ST1Twov4h);
6154 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6155 VT == MVT::v8bf16) {
6156 SelectStore(
Node, 2, AArch64::ST1Twov8h);
6158 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6159 SelectStore(
Node, 2, AArch64::ST1Twov2s);
6161 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6162 SelectStore(
Node, 2, AArch64::ST1Twov4s);
6164 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6165 SelectStore(
Node, 2, AArch64::ST1Twov2d);
6167 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6168 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6173 case Intrinsic::aarch64_neon_st1x3: {
6174 if (VT == MVT::v8i8) {
6175 SelectStore(
Node, 3, AArch64::ST1Threev8b);
6177 }
else if (VT == MVT::v16i8) {
6178 SelectStore(
Node, 3, AArch64::ST1Threev16b);
6180 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6181 VT == MVT::v4bf16) {
6182 SelectStore(
Node, 3, AArch64::ST1Threev4h);
6184 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6185 VT == MVT::v8bf16) {
6186 SelectStore(
Node, 3, AArch64::ST1Threev8h);
6188 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6189 SelectStore(
Node, 3, AArch64::ST1Threev2s);
6191 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6192 SelectStore(
Node, 3, AArch64::ST1Threev4s);
6194 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6195 SelectStore(
Node, 3, AArch64::ST1Threev2d);
6197 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6198 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6203 case Intrinsic::aarch64_neon_st1x4: {
6204 if (VT == MVT::v8i8) {
6205 SelectStore(
Node, 4, AArch64::ST1Fourv8b);
6207 }
else if (VT == MVT::v16i8) {
6208 SelectStore(
Node, 4, AArch64::ST1Fourv16b);
6210 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6211 VT == MVT::v4bf16) {
6212 SelectStore(
Node, 4, AArch64::ST1Fourv4h);
6214 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6215 VT == MVT::v8bf16) {
6216 SelectStore(
Node, 4, AArch64::ST1Fourv8h);
6218 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6219 SelectStore(
Node, 4, AArch64::ST1Fourv2s);
6221 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6222 SelectStore(
Node, 4, AArch64::ST1Fourv4s);
6224 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6225 SelectStore(
Node, 4, AArch64::ST1Fourv2d);
6227 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6228 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6233 case Intrinsic::aarch64_neon_st2: {
6234 if (VT == MVT::v8i8) {
6235 SelectStore(
Node, 2, AArch64::ST2Twov8b);
6237 }
else if (VT == MVT::v16i8) {
6238 SelectStore(
Node, 2, AArch64::ST2Twov16b);
6240 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6241 VT == MVT::v4bf16) {
6242 SelectStore(
Node, 2, AArch64::ST2Twov4h);
6244 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6245 VT == MVT::v8bf16) {
6246 SelectStore(
Node, 2, AArch64::ST2Twov8h);
6248 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6249 SelectStore(
Node, 2, AArch64::ST2Twov2s);
6251 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6252 SelectStore(
Node, 2, AArch64::ST2Twov4s);
6254 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6255 SelectStore(
Node, 2, AArch64::ST2Twov2d);
6257 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6258 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6263 case Intrinsic::aarch64_neon_st3: {
6264 if (VT == MVT::v8i8) {
6265 SelectStore(
Node, 3, AArch64::ST3Threev8b);
6267 }
else if (VT == MVT::v16i8) {
6268 SelectStore(
Node, 3, AArch64::ST3Threev16b);
6270 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6271 VT == MVT::v4bf16) {
6272 SelectStore(
Node, 3, AArch64::ST3Threev4h);
6274 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6275 VT == MVT::v8bf16) {
6276 SelectStore(
Node, 3, AArch64::ST3Threev8h);
6278 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6279 SelectStore(
Node, 3, AArch64::ST3Threev2s);
6281 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6282 SelectStore(
Node, 3, AArch64::ST3Threev4s);
6284 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6285 SelectStore(
Node, 3, AArch64::ST3Threev2d);
6287 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6288 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6293 case Intrinsic::aarch64_neon_st4: {
6294 if (VT == MVT::v8i8) {
6295 SelectStore(
Node, 4, AArch64::ST4Fourv8b);
6297 }
else if (VT == MVT::v16i8) {
6298 SelectStore(
Node, 4, AArch64::ST4Fourv16b);
6300 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6301 VT == MVT::v4bf16) {
6302 SelectStore(
Node, 4, AArch64::ST4Fourv4h);
6304 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6305 VT == MVT::v8bf16) {
6306 SelectStore(
Node, 4, AArch64::ST4Fourv8h);
6308 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6309 SelectStore(
Node, 4, AArch64::ST4Fourv2s);
6311 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6312 SelectStore(
Node, 4, AArch64::ST4Fourv4s);
6314 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6315 SelectStore(
Node, 4, AArch64::ST4Fourv2d);
6317 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6318 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6323 case Intrinsic::aarch64_neon_st2lane: {
6324 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6325 SelectStoreLane(
Node, 2, AArch64::ST2i8);
6327 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6328 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6329 SelectStoreLane(
Node, 2, AArch64::ST2i16);
6331 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6333 SelectStoreLane(
Node, 2, AArch64::ST2i32);
6335 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6337 SelectStoreLane(
Node, 2, AArch64::ST2i64);
6342 case Intrinsic::aarch64_neon_st3lane: {
6343 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6344 SelectStoreLane(
Node, 3, AArch64::ST3i8);
6346 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6347 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6348 SelectStoreLane(
Node, 3, AArch64::ST3i16);
6350 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6352 SelectStoreLane(
Node, 3, AArch64::ST3i32);
6354 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6356 SelectStoreLane(
Node, 3, AArch64::ST3i64);
6361 case Intrinsic::aarch64_neon_st4lane: {
6362 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6363 SelectStoreLane(
Node, 4, AArch64::ST4i8);
6365 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6366 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6367 SelectStoreLane(
Node, 4, AArch64::ST4i16);
6369 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6371 SelectStoreLane(
Node, 4, AArch64::ST4i32);
6373 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6375 SelectStoreLane(
Node, 4, AArch64::ST4i64);
6380 case Intrinsic::aarch64_sve_st2q: {
6381 SelectPredicatedStore(
Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6384 case Intrinsic::aarch64_sve_st3q: {
6385 SelectPredicatedStore(
Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6388 case Intrinsic::aarch64_sve_st4q: {
6389 SelectPredicatedStore(
Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6392 case Intrinsic::aarch64_sve_st2: {
6393 if (VT == MVT::nxv16i8) {
6394 SelectPredicatedStore(
Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6396 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6397 VT == MVT::nxv8bf16) {
6398 SelectPredicatedStore(
Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6400 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6401 SelectPredicatedStore(
Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6403 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6404 SelectPredicatedStore(
Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6409 case Intrinsic::aarch64_sve_st3: {
6410 if (VT == MVT::nxv16i8) {
6411 SelectPredicatedStore(
Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6413 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6414 VT == MVT::nxv8bf16) {
6415 SelectPredicatedStore(
Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6417 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6418 SelectPredicatedStore(
Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6420 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6421 SelectPredicatedStore(
Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6426 case Intrinsic::aarch64_sve_st4: {
6427 if (VT == MVT::nxv16i8) {
6428 SelectPredicatedStore(
Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6430 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6431 VT == MVT::nxv8bf16) {
6432 SelectPredicatedStore(
Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6434 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6435 SelectPredicatedStore(
Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6437 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6438 SelectPredicatedStore(
Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6447 if (VT == MVT::v8i8) {
6448 SelectPostLoad(
Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6450 }
else if (VT == MVT::v16i8) {
6451 SelectPostLoad(
Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6453 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6454 SelectPostLoad(
Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6456 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6457 SelectPostLoad(
Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6459 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6460 SelectPostLoad(
Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6462 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6463 SelectPostLoad(
Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6465 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6466 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6468 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6469 SelectPostLoad(
Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6475 if (VT == MVT::v8i8) {
6476 SelectPostLoad(
Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6478 }
else if (VT == MVT::v16i8) {
6479 SelectPostLoad(
Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6481 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6482 SelectPostLoad(
Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6484 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6485 SelectPostLoad(
Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6487 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6488 SelectPostLoad(
Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6490 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6491 SelectPostLoad(
Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6493 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6494 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6496 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6497 SelectPostLoad(
Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6503 if (VT == MVT::v8i8) {
6504 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6506 }
else if (VT == MVT::v16i8) {
6507 SelectPostLoad(
Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6509 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6510 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6512 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6513 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6515 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6516 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6518 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6519 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6521 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6522 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6524 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6525 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6531 if (VT == MVT::v8i8) {
6532 SelectPostLoad(
Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6534 }
else if (VT == MVT::v16i8) {
6535 SelectPostLoad(
Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6537 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6538 SelectPostLoad(
Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6540 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6541 SelectPostLoad(
Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6543 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6544 SelectPostLoad(
Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6546 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6547 SelectPostLoad(
Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6549 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6550 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6552 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6553 SelectPostLoad(
Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6559 if (VT == MVT::v8i8) {
6560 SelectPostLoad(
Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6562 }
else if (VT == MVT::v16i8) {
6563 SelectPostLoad(
Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6565 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6566 SelectPostLoad(
Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6568 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6569 SelectPostLoad(
Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6571 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6572 SelectPostLoad(
Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6574 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6575 SelectPostLoad(
Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6577 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6578 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6580 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6581 SelectPostLoad(
Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6587 if (VT == MVT::v8i8) {
6588 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6590 }
else if (VT == MVT::v16i8) {
6591 SelectPostLoad(
Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6593 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6594 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6596 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6597 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6599 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6600 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6602 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6603 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6605 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6606 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6608 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6609 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6615 if (VT == MVT::v8i8) {
6616 SelectPostLoad(
Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6618 }
else if (VT == MVT::v16i8) {
6619 SelectPostLoad(
Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6621 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6622 SelectPostLoad(
Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6624 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6625 SelectPostLoad(
Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6627 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6628 SelectPostLoad(
Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6630 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6631 SelectPostLoad(
Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6633 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6634 SelectPostLoad(
Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6636 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6637 SelectPostLoad(
Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6643 if (VT == MVT::v8i8) {
6644 SelectPostLoad(
Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6646 }
else if (VT == MVT::v16i8) {
6647 SelectPostLoad(
Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6649 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6650 SelectPostLoad(
Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6652 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6653 SelectPostLoad(
Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6655 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6656 SelectPostLoad(
Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6658 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6659 SelectPostLoad(
Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6661 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6662 SelectPostLoad(
Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6664 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6665 SelectPostLoad(
Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
6671 if (VT == MVT::v8i8) {
6672 SelectPostLoad(
Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
6674 }
else if (VT == MVT::v16i8) {
6675 SelectPostLoad(
Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
6677 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6678 SelectPostLoad(
Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
6680 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6681 SelectPostLoad(
Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
6683 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6684 SelectPostLoad(
Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
6686 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6687 SelectPostLoad(
Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
6689 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6690 SelectPostLoad(
Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
6692 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6693 SelectPostLoad(
Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
6699 if (VT == MVT::v8i8) {
6700 SelectPostLoad(
Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
6702 }
else if (VT == MVT::v16i8) {
6703 SelectPostLoad(
Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
6705 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6706 SelectPostLoad(
Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
6708 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6709 SelectPostLoad(
Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
6711 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6712 SelectPostLoad(
Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
6714 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6715 SelectPostLoad(
Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
6717 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6718 SelectPostLoad(
Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
6720 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6721 SelectPostLoad(
Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
6727 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6728 SelectPostLoadLane(
Node, 1, AArch64::LD1i8_POST);
6730 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6731 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6732 SelectPostLoadLane(
Node, 1, AArch64::LD1i16_POST);
6734 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6736 SelectPostLoadLane(
Node, 1, AArch64::LD1i32_POST);
6738 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6740 SelectPostLoadLane(
Node, 1, AArch64::LD1i64_POST);
6746 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6747 SelectPostLoadLane(
Node, 2, AArch64::LD2i8_POST);
6749 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6750 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6751 SelectPostLoadLane(
Node, 2, AArch64::LD2i16_POST);
6753 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6755 SelectPostLoadLane(
Node, 2, AArch64::LD2i32_POST);
6757 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6759 SelectPostLoadLane(
Node, 2, AArch64::LD2i64_POST);
6765 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6766 SelectPostLoadLane(
Node, 3, AArch64::LD3i8_POST);
6768 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6769 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6770 SelectPostLoadLane(
Node, 3, AArch64::LD3i16_POST);
6772 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6774 SelectPostLoadLane(
Node, 3, AArch64::LD3i32_POST);
6776 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6778 SelectPostLoadLane(
Node, 3, AArch64::LD3i64_POST);
6784 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6785 SelectPostLoadLane(
Node, 4, AArch64::LD4i8_POST);
6787 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6788 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6789 SelectPostLoadLane(
Node, 4, AArch64::LD4i16_POST);
6791 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6793 SelectPostLoadLane(
Node, 4, AArch64::LD4i32_POST);
6795 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6797 SelectPostLoadLane(
Node, 4, AArch64::LD4i64_POST);
6803 VT =
Node->getOperand(1).getValueType();
6804 if (VT == MVT::v8i8) {
6805 SelectPostStore(
Node, 2, AArch64::ST2Twov8b_POST);
6807 }
else if (VT == MVT::v16i8) {
6808 SelectPostStore(
Node, 2, AArch64::ST2Twov16b_POST);
6810 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6811 SelectPostStore(
Node, 2, AArch64::ST2Twov4h_POST);
6813 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6814 SelectPostStore(
Node, 2, AArch64::ST2Twov8h_POST);
6816 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6817 SelectPostStore(
Node, 2, AArch64::ST2Twov2s_POST);
6819 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6820 SelectPostStore(
Node, 2, AArch64::ST2Twov4s_POST);
6822 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6823 SelectPostStore(
Node, 2, AArch64::ST2Twov2d_POST);
6825 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6826 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
6832 VT =
Node->getOperand(1).getValueType();
6833 if (VT == MVT::v8i8) {
6834 SelectPostStore(
Node, 3, AArch64::ST3Threev8b_POST);
6836 }
else if (VT == MVT::v16i8) {
6837 SelectPostStore(
Node, 3, AArch64::ST3Threev16b_POST);
6839 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6840 SelectPostStore(
Node, 3, AArch64::ST3Threev4h_POST);
6842 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6843 SelectPostStore(
Node, 3, AArch64::ST3Threev8h_POST);
6845 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6846 SelectPostStore(
Node, 3, AArch64::ST3Threev2s_POST);
6848 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6849 SelectPostStore(
Node, 3, AArch64::ST3Threev4s_POST);
6851 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6852 SelectPostStore(
Node, 3, AArch64::ST3Threev2d_POST);
6854 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6855 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
6861 VT =
Node->getOperand(1).getValueType();
6862 if (VT == MVT::v8i8) {
6863 SelectPostStore(
Node, 4, AArch64::ST4Fourv8b_POST);
6865 }
else if (VT == MVT::v16i8) {
6866 SelectPostStore(
Node, 4, AArch64::ST4Fourv16b_POST);
6868 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6869 SelectPostStore(
Node, 4, AArch64::ST4Fourv4h_POST);
6871 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6872 SelectPostStore(
Node, 4, AArch64::ST4Fourv8h_POST);
6874 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6875 SelectPostStore(
Node, 4, AArch64::ST4Fourv2s_POST);
6877 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6878 SelectPostStore(
Node, 4, AArch64::ST4Fourv4s_POST);
6880 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6881 SelectPostStore(
Node, 4, AArch64::ST4Fourv2d_POST);
6883 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6884 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
6890 VT =
Node->getOperand(1).getValueType();
6891 if (VT == MVT::v8i8) {
6892 SelectPostStore(
Node, 2, AArch64::ST1Twov8b_POST);
6894 }
else if (VT == MVT::v16i8) {
6895 SelectPostStore(
Node, 2, AArch64::ST1Twov16b_POST);
6897 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6898 SelectPostStore(
Node, 2, AArch64::ST1Twov4h_POST);
6900 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6901 SelectPostStore(
Node, 2, AArch64::ST1Twov8h_POST);
6903 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6904 SelectPostStore(
Node, 2, AArch64::ST1Twov2s_POST);
6906 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6907 SelectPostStore(
Node, 2, AArch64::ST1Twov4s_POST);
6909 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6910 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
6912 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6913 SelectPostStore(
Node, 2, AArch64::ST1Twov2d_POST);
6919 VT =
Node->getOperand(1).getValueType();
6920 if (VT == MVT::v8i8) {
6921 SelectPostStore(
Node, 3, AArch64::ST1Threev8b_POST);
6923 }
else if (VT == MVT::v16i8) {
6924 SelectPostStore(
Node, 3, AArch64::ST1Threev16b_POST);
6926 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6927 SelectPostStore(
Node, 3, AArch64::ST1Threev4h_POST);
6929 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
6930 SelectPostStore(
Node, 3, AArch64::ST1Threev8h_POST);
6932 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6933 SelectPostStore(
Node, 3, AArch64::ST1Threev2s_POST);
6935 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6936 SelectPostStore(
Node, 3, AArch64::ST1Threev4s_POST);
6938 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6939 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
6941 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6942 SelectPostStore(
Node, 3, AArch64::ST1Threev2d_POST);
6948 VT =
Node->getOperand(1).getValueType();
6949 if (VT == MVT::v8i8) {
6950 SelectPostStore(
Node, 4, AArch64::ST1Fourv8b_POST);
6952 }
else if (VT == MVT::v16i8) {
6953 SelectPostStore(
Node, 4, AArch64::ST1Fourv16b_POST);
6955 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6956 SelectPostStore(
Node, 4, AArch64::ST1Fourv4h_POST);
6958 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6959 SelectPostStore(
Node, 4, AArch64::ST1Fourv8h_POST);
6961 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6962 SelectPostStore(
Node, 4, AArch64::ST1Fourv2s_POST);
6964 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6965 SelectPostStore(
Node, 4, AArch64::ST1Fourv4s_POST);
6967 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6968 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
6970 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6971 SelectPostStore(
Node, 4, AArch64::ST1Fourv2d_POST);
6977 VT =
Node->getOperand(1).getValueType();
6978 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6979 SelectPostStoreLane(
Node, 2, AArch64::ST2i8_POST);
6981 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6982 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6983 SelectPostStoreLane(
Node, 2, AArch64::ST2i16_POST);
6985 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6987 SelectPostStoreLane(
Node, 2, AArch64::ST2i32_POST);
6989 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6991 SelectPostStoreLane(
Node, 2, AArch64::ST2i64_POST);
6997 VT =
Node->getOperand(1).getValueType();
6998 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6999 SelectPostStoreLane(
Node, 3, AArch64::ST3i8_POST);
7001 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7002 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7003 SelectPostStoreLane(
Node, 3, AArch64::ST3i16_POST);
7005 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7007 SelectPostStoreLane(
Node, 3, AArch64::ST3i32_POST);
7009 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7011 SelectPostStoreLane(
Node, 3, AArch64::ST3i64_POST);
7017 VT =
Node->getOperand(1).getValueType();
7018 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7019 SelectPostStoreLane(
Node, 4, AArch64::ST4i8_POST);
7021 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7022 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7023 SelectPostStoreLane(
Node, 4, AArch64::ST4i16_POST);
7025 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7027 SelectPostStoreLane(
Node, 4, AArch64::ST4i32_POST);
7029 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7031 SelectPostStoreLane(
Node, 4, AArch64::ST4i64_POST);
7037 if (VT == MVT::nxv16i8) {
7038 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B);
7040 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7041 VT == MVT::nxv8bf16) {
7042 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H);
7044 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7045 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W);
7047 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7048 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D);
7054 if (VT == MVT::nxv16i8) {
7055 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B);
7057 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7058 VT == MVT::nxv8bf16) {
7059 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H);
7061 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7062 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W);
7064 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7065 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D);
7071 if (VT == MVT::nxv16i8) {
7072 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B);
7074 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7075 VT == MVT::nxv8bf16) {
7076 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H);
7078 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7079 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W);
7081 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7082 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D);
7097 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7109 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7113 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7114 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7128 if (isa<MemSDNode>(Root))
7129 return cast<MemSDNode>(Root)->getMemoryVT();
7131 if (isa<MemIntrinsicSDNode>(Root))
7132 return cast<MemIntrinsicSDNode>(Root)->getMemoryVT();
7134 const unsigned Opcode = Root->
getOpcode();
7142 return cast<VTSDNode>(Root->
getOperand(3))->getVT();
7144 return cast<VTSDNode>(Root->
getOperand(4))->getVT();
7164 case Intrinsic::aarch64_sme_ldr:
7165 case Intrinsic::aarch64_sme_str:
7166 return MVT::nxv16i8;
7167 case Intrinsic::aarch64_sve_prf:
7172 case Intrinsic::aarch64_sve_ld2_sret:
7173 case Intrinsic::aarch64_sve_ld2q_sret:
7176 case Intrinsic::aarch64_sve_st2q:
7179 case Intrinsic::aarch64_sve_ld3_sret:
7180 case Intrinsic::aarch64_sve_ld3q_sret:
7183 case Intrinsic::aarch64_sve_st3q:
7186 case Intrinsic::aarch64_sve_ld4_sret:
7187 case Intrinsic::aarch64_sve_ld4q_sret:
7190 case Intrinsic::aarch64_sve_st4q:
7193 case Intrinsic::aarch64_sve_ld1udq:
7194 case Intrinsic::aarch64_sve_st1dq:
7195 return EVT(MVT::nxv1i64);
7196 case Intrinsic::aarch64_sve_ld1uwq:
7197 case Intrinsic::aarch64_sve_st1wq:
7198 return EVT(MVT::nxv1i32);
7205template <
int64_t Min,
int64_t Max>
7206bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(
SDNode *Root,
SDValue N,
7214 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
7219 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7238 int64_t MulImm = cast<ConstantSDNode>(VScale.
getOperand(0))->getSExtValue();
7240 if ((MulImm % MemWidthBytes) != 0)
7243 int64_t
Offset = MulImm / MemWidthBytes;
7244 if (Offset < Min || Offset > Max)
7247 Base =
N.getOperand(0);
7249 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
7256 OffImm = CurDAG->getTargetConstant(
Offset,
SDLoc(
N), MVT::i64);
7262bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7280 if (
auto C = dyn_cast<ConstantSDNode>(RHS)) {
7281 int64_t ImmOff =
C->getSExtValue();
7282 unsigned Size = 1 << Scale;
7291 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7293 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
7303 if (
auto *
C = dyn_cast<ConstantSDNode>(ShiftRHS))
7304 if (
C->getZExtValue() == Scale) {
7313bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7320bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7321 EVT VT =
N.getValueType();
7325bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7330 if (
auto C = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
7331 int64_t ImmOff =
C->getSExtValue();
7332 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0))) {
7333 Base =
N.getOperand(0);
7334 Offset = CurDAG->getTargetConstant(ImmOff / Scale,
SDLoc(
N), MVT::i64);
7341 Offset = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
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 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 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 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 void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
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 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.
amdgpu 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
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
support::ulittle16_t & Lo
support::ulittle16_t & Hi
DEMANGLE_DUMP_METHOD void dump() const
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool isLittleEndian() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
bool getExactInverse(APFloat *inv) const
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to 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.
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.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
An arbitrary precision integer that knows its signedness.
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
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
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 getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint8_t getStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
A description of a memory reference used in the backend.
An SDNode that represents everything that will be needed to construct a MachineInstr.
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.
iterator_range< use_iterator > uses()
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.
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 bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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),...
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,...
static constexpr unsigned MaxRecursionDepth
SDValue getRegister(unsigned Reg, EVT VT)
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)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
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...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
bool hasOneUse() const
Return true if there is exactly one use of this value.
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)
const SysReg * lookupSysRegByName(StringRef)
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 bool processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t &Encoding)
processLogicalImmediate - Determine if an immediate value can be encoded as the immediate operand of ...
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 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, ptr, val) 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.
@ 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...
@ 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...
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).
@ Undef
Value of the register doesn't matter.
Not(const Pred &P) -> Not< Pred >
Reg
All possible values of the reg field in the ModR/M byte.
DiagnosticInfoOptimizationBase::Argument NV
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.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
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.
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...
CodeGenOptLevel
Code generation optimization level.
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,...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
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
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
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 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.