22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
67 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
69 std::vector<SDValue> &OutOps)
override;
71 template <
signed Low,
signed High,
signed Scale>
74 template <
signed Low,
signed High>
82 return SelectShiftedRegister(
N,
false,
Reg, Shift);
85 return SelectShiftedRegister(
N,
true,
Reg, Shift);
88 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
91 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
94 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
97 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
100 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
103 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
106 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
109 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
112 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
115 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
118 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
121 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
124 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
127 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
130 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
133 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
136 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
138 template <
unsigned Size,
unsigned Max>
142 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
145 int64_t
C = CI->getSExtValue();
153 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
160 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
166 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
171 N =
N->getOperand(0);
175 EVT VT =
N->getValueType(0);
176 EVT LVT =
N->getOperand(0).getValueType();
177 unsigned Index =
N->getConstantOperandVal(1);
181 Res =
N->getOperand(0);
186 if (
N.getOpcode() != AArch64ISD::VLSHR)
189 EVT VT =
Op.getValueType();
190 unsigned ShtAmt =
N->getConstantOperandVal(1);
195 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
197 Op.getOperand(1).getConstantOperandVal(0)
198 <<
Op.getOperand(1).getConstantOperandVal(1));
199 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
202 Op.getOperand(1).getConstantOperandVal(0));
206 if (Imm != 1ULL << (ShtAmt - 1))
209 Res1 =
Op.getOperand(0);
210 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
214 bool SelectDupZeroOrUndef(
SDValue N) {
215 switch(
N->getOpcode()) {
218 case AArch64ISD::DUP:
220 auto Opnd0 =
N->getOperand(0);
234 bool SelectAny(
SDValue) {
return true; }
237 switch(
N->getOpcode()) {
238 case AArch64ISD::DUP:
240 auto Opnd0 =
N->getOperand(0);
252 template <MVT::SimpleValueType VT,
bool Negate>
254 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
257 template <MVT::SimpleValueType VT,
bool Negate>
259 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
262 template <MVT::SimpleValueType VT>
264 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
267 template <MVT::SimpleValueType VT,
bool Invert = false>
269 return SelectSVELogicalImm(
N, VT, Imm, Invert);
272 template <MVT::SimpleValueType VT>
274 return SelectSVEArithImm(
N, VT, Imm);
277 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
279 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
286 EVT EltVT =
N->getValueType(0).getVectorElementType();
287 return SelectSVEShiftImm(
N->getOperand(0), 1,
293 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
300 MulImm = 1LL << MulImm;
302 if ((MulImm % std::abs(Scale)) != 0)
306 if ((MulImm >= Min) && (MulImm <= Max)) {
307 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
314 template <
signed Max,
signed Scale>
321 if (MulImm >= 0 && MulImm <= Max) {
323 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
330 template <
unsigned BaseReg,
unsigned Max>
338 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
361 const unsigned SubRegs[]);
363 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
365 bool tryIndexedLoad(
SDNode *
N);
367 void SelectPtrauthAuth(
SDNode *
N);
368 void SelectPtrauthResign(
SDNode *
N);
370 bool trySelectStackSlotTagP(
SDNode *
N);
373 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
375 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
377 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
378 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
380 unsigned Opc_rr,
unsigned Opc_ri,
381 bool IsIntr =
false);
382 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
383 unsigned Scale,
unsigned Opc_ri,
385 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
386 bool IsZmMulti,
unsigned Opcode,
387 bool HasPred =
false);
389 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
390 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
391 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
394 bool IsTupleInput,
unsigned Opc);
395 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
397 template <
unsigned MaxIdx,
unsigned Scale>
398 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
400 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
401 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
402 unsigned BaseReg = 0);
405 template <
int64_t Min,
int64_t Max>
409 template <
unsigned Scale>
411 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
414 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
417 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
419 template <
unsigned MaxIdx,
unsigned Scale>
424 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
425 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
429 unsigned Opc_rr,
unsigned Opc_ri);
430 std::tuple<unsigned, SDValue, SDValue>
431 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
435 bool tryBitfieldExtractOp(
SDNode *
N);
436 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
437 bool tryBitfieldInsertOp(
SDNode *
N);
438 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
439 bool tryShiftAmountMod(
SDNode *
N);
441 bool tryReadRegister(
SDNode *
N);
442 bool tryWriteRegister(
SDNode *
N);
444 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
445 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
450#include "AArch64GenDAGISel.inc"
458 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
460 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
473 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
474 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
475 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
478 template<
unsigned RegW
idth>
480 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
483 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
485 template<
unsigned RegW
idth>
487 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
493 bool SelectCMP_SWAP(
SDNode *
N);
504 bool AllowSaturation,
SDValue &Imm);
512 bool SelectAllActivePredicate(
SDValue N);
517 template <
bool MatchCBB>
527 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
531char AArch64DAGToDAGISelLegacy::ID = 0;
539 Imm =
C->getZExtValue();
556 return N->getOpcode() ==
Opc &&
567 return Imm == ImmExpected;
571bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
573 std::vector<SDValue> &OutOps) {
574 switch(ConstraintID) {
577 case InlineAsm::ConstraintCode::m:
578 case InlineAsm::ConstraintCode::o:
579 case InlineAsm::ConstraintCode::Q:
583 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
585 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
587 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
588 dl,
Op.getValueType(),
590 OutOps.push_back(NewOp);
609 uint64_t Immed =
N.getNode()->getAsZExtVal();
612 if (Immed >> 12 == 0) {
614 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
622 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
623 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
640 uint64_t Immed =
N.getNode()->getAsZExtVal();
648 if (
N.getValueType() == MVT::i32)
649 Immed = ~((uint32_t)Immed) + 1;
651 Immed = ~Immed + 1ULL;
652 if (Immed & 0xFFFFFFFFFF000000ULL)
655 Immed &= 0xFFFFFFULL;
656 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
663 switch (
N.getOpcode()) {
689 unsigned ShiftVal = CSD->getZExtValue();
707bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
710 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
715 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
739 EVT VT =
N.getValueType();
740 if (VT != MVT::i32 && VT != MVT::i64)
743 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
749 unsigned LHSOpcode =
LHS->getOpcode();
763 unsigned LowZBits, MaskLen;
767 unsigned BitWidth =
N.getValueSizeInBits();
774 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
777 NewShiftC = LowZBits - ShiftAmtC;
778 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
784 NewShiftC = LowZBits + ShiftAmtC;
797 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
799 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
803 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
805 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
806 NewShiftAmt, BitWidthMinus1),
809 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
823 SrcVT =
N.getOperand(0).getValueType();
825 if (!IsLoadStore && SrcVT == MVT::i8)
827 else if (!IsLoadStore && SrcVT == MVT::i16)
829 else if (SrcVT == MVT::i32)
831 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
836 EVT SrcVT =
N.getOperand(0).getValueType();
837 if (!IsLoadStore && SrcVT == MVT::i8)
839 else if (!IsLoadStore && SrcVT == MVT::i16)
841 else if (SrcVT == MVT::i32)
843 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
871bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
874 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
879 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
880 V.getConstantOperandVal(1) <= 4 &&
893bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
895 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
905 unsigned BitSize =
N.getValueSizeInBits();
906 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
909 Reg =
N.getOperand(0);
910 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
911 return isWorthFoldingALU(
N,
true);
922 if (
N.getValueType() == MVT::i32)
930template<
signed Low,
signed High,
signed Scale>
936 if ((MulImm % std::abs(Scale)) == 0) {
937 int64_t RDVLImm = MulImm / Scale;
938 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
939 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
948template <
signed Low,
signed High>
949bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
954 if (MulImm >=
Low && MulImm <=
High) {
955 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
966 unsigned ShiftVal = 0;
981 Reg =
N.getOperand(0).getOperand(0);
987 Reg =
N.getOperand(0);
992 unsigned Opc =
N.getOpcode();
1010 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1012 return isWorthFoldingALU(
N);
1019 unsigned ShiftVal = 0;
1033 Reg =
N.getOperand(0);
1034 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1036 return isWorthFoldingALU(
N);
1045 for (
auto *
User :
N->users()) {
1046 if (
User->getOpcode() != ISD::LOAD &&
User->getOpcode() != ISD::STORE &&
1047 User->getOpcode() != ISD::ATOMIC_LOAD &&
1048 User->getOpcode() != ISD::ATOMIC_STORE)
1072bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1073 unsigned BW,
unsigned Size,
1077 const DataLayout &
DL = CurDAG->getDataLayout();
1078 const TargetLowering *TLI = getTargetLowering();
1082 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1088 if (CurDAG->isBaseWithConstantOffset(
N)) {
1091 int64_t RHSC =
RHS->getSExtValue();
1093 int64_t
Range = 0x1LL << (BW - 1);
1095 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1096 RHSC < (
Range << Scale)) {
1097 Base =
N.getOperand(0);
1102 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1107 uint64_t RHSC =
RHS->getZExtValue();
1109 uint64_t
Range = 0x1ULL << BW;
1111 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1112 Base =
N.getOperand(0);
1117 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1128 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1135bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1138 const DataLayout &
DL = CurDAG->getDataLayout();
1139 const TargetLowering *TLI = getTargetLowering();
1143 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1148 GlobalAddressSDNode *GAN =
1150 Base =
N.getOperand(0);
1160 if (CurDAG->isBaseWithConstantOffset(
N)) {
1162 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1165 Base =
N.getOperand(0);
1170 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1178 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1186 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1195bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1198 if (!CurDAG->isBaseWithConstantOffset(
N))
1201 int64_t RHSC =
RHS->getSExtValue();
1202 if (RHSC >= -256 && RHSC < 256) {
1203 Base =
N.getOperand(0);
1206 const TargetLowering *TLI = getTargetLowering();
1207 Base = CurDAG->getTargetFrameIndex(
1210 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1220 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1227bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1247 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1253 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1256 return isWorthFoldingAddr(
N,
Size);
1259bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1277 const SDNode *
Node =
N.getNode();
1278 for (SDNode *UI :
Node->users()) {
1284 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1287 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1290 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1295 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1298 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1303 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1307 if (IsExtendedRegisterWorthFolding &&
1314 if (isWorthFoldingAddr(
LHS,
Size))
1319 if (IsExtendedRegisterWorthFolding &&
1326 if (isWorthFoldingAddr(
RHS,
Size))
1338 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1341 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1343 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1344 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1348bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1361 const SDNode *
Node =
N.getNode();
1362 for (SDNode *UI :
Node->users()) {
1379 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1389 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1396 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1399 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1402 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1407 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1410 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1417 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1418 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1424 static const unsigned RegClassIDs[] = {
1425 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1426 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1427 AArch64::dsub2, AArch64::dsub3};
1433 static const unsigned RegClassIDs[] = {
1434 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1435 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1436 AArch64::qsub2, AArch64::qsub3};
1442 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1443 AArch64::ZPR3RegClassID,
1444 AArch64::ZPR4RegClassID};
1445 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1446 AArch64::zsub2, AArch64::zsub3};
1456 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1457 AArch64::ZPR4Mul4RegClassID};
1458 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1459 AArch64::zsub2, AArch64::zsub3};
1464 const unsigned RegClassIDs[],
1465 const unsigned SubRegs[]) {
1468 if (Regs.
size() == 1)
1479 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1482 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1483 Ops.push_back(Regs[i]);
1484 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1488 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1492void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1495 EVT VT =
N->getValueType(0);
1497 unsigned ExtOff = isExt;
1500 unsigned Vec0Off = ExtOff + 1;
1506 Ops.push_back(
N->getOperand(1));
1507 Ops.push_back(RegSeq);
1508 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1509 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1512static std::tuple<SDValue, SDValue>
1533 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1538 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1540 return std::make_tuple(
1545void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1550 SDValue AUTDisc =
N->getOperand(3);
1553 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1555 SDValue AUTAddrDisc, AUTConstDisc;
1556 std::tie(AUTConstDisc, AUTAddrDisc) =
1560 SDValue Ops[] = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1563 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1564 ReplaceNode(
N, AUT);
1566 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1567 AArch64::X16, Val,
SDValue());
1570 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1571 ReplaceNode(
N, AUT);
1575void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1587 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1588 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1590 SDValue AUTAddrDisc, AUTConstDisc;
1591 std::tie(AUTConstDisc, AUTAddrDisc) =
1594 SDValue PACAddrDisc, PACConstDisc;
1595 std::tie(PACConstDisc, PACAddrDisc) =
1598 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1599 AArch64::X16, Val,
SDValue());
1601 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1602 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1604 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1605 ReplaceNode(
N, AUTPAC);
1608bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1610 if (
LD->isUnindexed())
1612 EVT VT =
LD->getMemoryVT();
1613 EVT DstVT =
N->getValueType(0);
1617 int OffsetVal = (int)
OffsetOp->getZExtValue();
1622 unsigned Opcode = 0;
1625 bool InsertTo64 =
false;
1627 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1628 else if (VT == MVT::i32) {
1630 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1632 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1634 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1640 }
else if (VT == MVT::i16) {
1642 if (DstVT == MVT::i64)
1643 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1645 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1647 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1648 InsertTo64 = DstVT == MVT::i64;
1653 }
else if (VT == MVT::i8) {
1655 if (DstVT == MVT::i64)
1656 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1658 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1660 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1661 InsertTo64 = DstVT == MVT::i64;
1666 }
else if (VT == MVT::f16) {
1667 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1668 }
else if (VT == MVT::bf16) {
1669 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1670 }
else if (VT == MVT::f32) {
1671 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1672 }
else if (VT == MVT::f64 ||
1674 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1676 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1678 if (IsPre || OffsetVal != 8)
1682 Opcode = AArch64::LD1Onev8b_POST;
1685 Opcode = AArch64::LD1Onev4h_POST;
1688 Opcode = AArch64::LD1Onev2s_POST;
1691 Opcode = AArch64::LD1Onev1d_POST;
1697 if (IsPre || OffsetVal != 16)
1701 Opcode = AArch64::LD1Onev16b_POST;
1704 Opcode = AArch64::LD1Onev8h_POST;
1707 Opcode = AArch64::LD1Onev4s_POST;
1710 Opcode = AArch64::LD1Onev2d_POST;
1722 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1723 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1725 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1735 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1737 SDValue(CurDAG->getMachineNode(
1738 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1739 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1744 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1747 CurDAG->RemoveDeadNode(
N);
1751void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1752 unsigned SubRegIdx) {
1754 EVT VT =
N->getValueType(0);
1760 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1762 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1764 for (
unsigned i = 0; i < NumVecs; ++i)
1766 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1773 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1777 CurDAG->RemoveDeadNode(
N);
1780void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1781 unsigned Opc,
unsigned SubRegIdx) {
1783 EVT VT =
N->getValueType(0);
1790 const EVT ResTys[] = {MVT::i64,
1791 MVT::Untyped, MVT::Other};
1793 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1801 ReplaceUses(
SDValue(
N, 0), SuperReg);
1803 for (
unsigned i = 0; i < NumVecs; ++i)
1805 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1809 CurDAG->RemoveDeadNode(
N);
1815std::tuple<unsigned, SDValue, SDValue>
1816AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1822 SDValue NewOffset = OldOffset;
1824 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1825 N, OldBase, NewBase, NewOffset);
1829 const bool IsRegReg =
1830 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1833 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1846template <SelectTypeKind Kind>
1858 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1863 if (EltVT != MVT::i1)
1867 if (EltVT == MVT::bf16)
1869 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1899void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
1902 if (
Imm->getZExtValue() > 1)
1906 EVT VT =
N->getValueType(0);
1908 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1911 for (
unsigned I = 0;
I < 2; ++
I)
1912 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1913 AArch64::psub0 +
I,
DL, VT, SuperReg));
1915 CurDAG->RemoveDeadNode(
N);
1918void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
1920 EVT VT =
N->getValueType(0);
1924 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1927 for (
unsigned I = 0;
I < 2; ++
I)
1928 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1929 AArch64::psub0 +
I,
DL, VT, SuperReg));
1931 CurDAG->RemoveDeadNode(
N);
1934void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
1936 EVT VT =
N->getValueType(0);
1940 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
1942 for (
unsigned i = 0; i < NumVecs; ++i)
1943 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1944 AArch64::zsub0 + i,
DL, VT, SuperReg));
1946 CurDAG->RemoveDeadNode(
N);
1949void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
1952 EVT VT =
N->getValueType(0);
1954 Ops.push_back(
N->getOperand(0));
1957 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
1960 for (
unsigned i = 0; i < NumVecs; ++i)
1961 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1962 AArch64::zsub0 + i,
DL, VT, SuperReg));
1965 unsigned ChainIdx = NumVecs;
1967 CurDAG->RemoveDeadNode(
N);
1970void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
1975 assert(Opcode != 0 &&
"Unexpected opcode");
1978 EVT VT =
N->getValueType(0);
1979 unsigned FirstVecIdx = HasPred ? 2 : 1;
1981 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1983 return createZMulTuple(Regs);
1986 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1990 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1996 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1997 N->getOperand(1), Zdn, Zm);
1999 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
2001 for (
unsigned i = 0; i < NumVecs; ++i)
2002 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2003 AArch64::zsub0 + i,
DL, VT, SuperReg));
2005 CurDAG->RemoveDeadNode(
N);
2008void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2009 unsigned Scale,
unsigned Opc_ri,
2010 unsigned Opc_rr,
bool IsIntr) {
2011 assert(Scale < 5 &&
"Invalid scaling value.");
2013 EVT VT =
N->getValueType(0);
2020 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2021 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2027 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2029 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2031 for (
unsigned i = 0; i < NumVecs; ++i)
2032 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2033 AArch64::zsub0 + i,
DL, VT, SuperReg));
2036 unsigned ChainIdx = NumVecs;
2038 CurDAG->RemoveDeadNode(
N);
2041void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2046 assert(Scale < 4 &&
"Invalid scaling value.");
2048 EVT VT =
N->getValueType(0);
2056 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2062 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2064 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2066 for (
unsigned i = 0; i < NumVecs; ++i)
2067 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2068 AArch64::zsub0 + i,
DL, VT, SuperReg));
2071 unsigned ChainIdx = NumVecs;
2073 CurDAG->RemoveDeadNode(
N);
2076void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2078 if (
N->getValueType(0) != MVT::nxv4f32)
2080 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2083void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2084 unsigned NumOutVecs,
2088 if (
Imm->getZExtValue() > MaxImm)
2092 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2098 EVT VT =
Node->getValueType(0);
2101 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2104 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2105 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2106 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2109 unsigned ChainIdx = NumOutVecs;
2111 CurDAG->RemoveDeadNode(Node);
2114void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2115 unsigned NumOutVecs,
2118 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2123 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2127 EVT VT =
Node->getValueType(0);
2130 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2133 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2134 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2135 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2138 unsigned ChainIdx = NumOutVecs;
2140 CurDAG->RemoveDeadNode(Node);
2143void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2146 EVT VT =
N->getValueType(0);
2149 SDValue Zd = createZMulTuple(Regs);
2150 SDValue Zn =
N->getOperand(1 + NumVecs);
2157 for (
unsigned i = 0; i < NumVecs; ++i)
2158 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2159 AArch64::zsub0 + i,
DL, VT, SuperReg));
2161 CurDAG->RemoveDeadNode(
N);
2191template <
unsigned MaxIdx,
unsigned Scale>
2192void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2193 unsigned BaseReg,
unsigned Op) {
2194 unsigned TileNum = 0;
2195 if (BaseReg != AArch64::ZA)
2196 TileNum =
N->getConstantOperandVal(2);
2202 if (BaseReg == AArch64::ZA)
2207 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2213 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2215 EVT VT =
N->getValueType(0);
2216 for (
unsigned I = 0;
I < NumVecs; ++
I)
2218 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2221 unsigned ChainIdx = NumVecs;
2223 CurDAG->RemoveDeadNode(
N);
2226void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2227 unsigned Op,
unsigned MaxIdx,
2228 unsigned Scale,
unsigned BaseReg) {
2233 if (BaseReg != AArch64::ZA)
2237 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2244 if (BaseReg != AArch64::ZA )
2245 Ops.push_back(
N->getOperand(2));
2248 Ops.push_back(
N->getOperand(0));
2249 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2251 EVT VT =
N->getValueType(0);
2252 for (
unsigned I = 0;
I < NumVecs; ++
I)
2254 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2258 unsigned ChainIdx = NumVecs;
2260 CurDAG->RemoveDeadNode(
N);
2263void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2264 unsigned NumOutVecs,
2268 EVT VT =
N->getValueType(0);
2269 unsigned NumInVecs =
N->getNumOperands() - 1;
2273 assert((NumInVecs == 2 || NumInVecs == 4) &&
2274 "Don't know how to handle multi-register input!");
2276 Ops.push_back(createZMulTuple(Regs));
2279 for (
unsigned I = 0;
I < NumInVecs;
I++)
2280 Ops.push_back(
N->getOperand(1 +
I));
2283 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2286 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2287 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2288 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2289 CurDAG->RemoveDeadNode(
N);
2292void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2295 EVT VT =
N->getOperand(2)->getValueType(0);
2303 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2312void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2313 unsigned Scale,
unsigned Opc_rr,
2319 SDValue RegSeq = createZTuple(Regs);
2325 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2326 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2332 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2340 const DataLayout &
DL = CurDAG->getDataLayout();
2341 const TargetLowering *TLI = getTargetLowering();
2345 int FI = FINode->getIndex();
2347 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2354void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2357 EVT VT =
N->getOperand(2)->getValueType(0);
2358 const EVT ResTys[] = {MVT::i64,
2370 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2410void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2413 EVT VT =
N->getValueType(0);
2425 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2427 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2429 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2431 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2435 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2436 AArch64::qsub2, AArch64::qsub3 };
2437 for (
unsigned i = 0; i < NumVecs; ++i) {
2438 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2445 CurDAG->RemoveDeadNode(
N);
2448void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2451 EVT VT =
N->getValueType(0);
2463 const EVT ResTys[] = {MVT::i64,
2466 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2469 CurDAG->getTargetConstant(LaneNo, dl,
2474 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2486 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2487 AArch64::qsub2, AArch64::qsub3 };
2488 for (
unsigned i = 0; i < NumVecs; ++i) {
2489 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2499 CurDAG->RemoveDeadNode(
N);
2502void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2505 EVT VT =
N->getOperand(2)->getValueType(0);
2517 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2519 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2521 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2530void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2533 EVT VT =
N->getOperand(2)->getValueType(0);
2545 const EVT ResTys[] = {MVT::i64,
2548 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2550 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2554 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2565 unsigned &LSB,
unsigned &MSB,
2566 unsigned NumberOfIgnoredLowBits,
2567 bool BiggerPattern) {
2569 "N must be a AND operation to call this function");
2571 EVT VT =
N->getValueType(0);
2576 assert((VT == MVT::i32 || VT == MVT::i64) &&
2577 "Type checking must have been done before calling this function");
2591 const SDNode *Op0 =
N->getOperand(0).getNode();
2598 if (AndImm & (AndImm + 1))
2601 bool ClampMSB =
false;
2621 ClampMSB = (VT == MVT::i32);
2622 }
else if (BiggerPattern) {
2628 Opd0 =
N->getOperand(0);
2634 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2637 <<
": Found large shift immediate, this should not happen\n"));
2651 MSB = MSB > 31 ? 31 : MSB;
2653 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2658 SDValue &Opd0,
unsigned &Immr,
2662 EVT VT =
N->getValueType(0);
2664 assert((VT == MVT::i32 || VT == MVT::i64) &&
2665 "Type checking must have been done before calling this function");
2669 Op =
Op->getOperand(0);
2670 VT =
Op->getValueType(0);
2679 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2683 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2684 Opd0 =
Op.getOperand(0);
2686 Imms = ShiftImm + Width - 1;
2714 Opd0 =
N->getOperand(0).getOperand(0);
2724 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2731 unsigned &Immr,
unsigned &Imms,
2732 bool BiggerPattern) {
2734 "N must be a SHR/SRA operation to call this function");
2736 EVT VT =
N->getValueType(0);
2741 assert((VT == MVT::i32 || VT == MVT::i64) &&
2742 "Type checking must have been done before calling this function");
2752 Opd0 =
N->getOperand(0).getOperand(0);
2753 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2759 Opd0 =
N->getOperand(0).getOperand(0);
2762 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2763 }
else if (BiggerPattern) {
2767 Opd0 =
N->getOperand(0);
2776 <<
": Found large shift immediate, this should not happen\n"));
2785 "bad amount in shift node!");
2786 int immr = SrlImm - ShlImm;
2791 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2793 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2797bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2800 EVT VT =
N->getValueType(0);
2801 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2802 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2813 unsigned Immr = ShiftImm;
2815 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2816 CurDAG->getTargetConstant(Imms, dl, VT)};
2817 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2822 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2823 unsigned NumberOfIgnoredLowBits = 0,
2824 bool BiggerPattern =
false) {
2825 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2828 switch (
N->getOpcode()) {
2830 if (!
N->isMachineOpcode())
2835 NumberOfIgnoredLowBits, BiggerPattern);
2844 unsigned NOpc =
N->getMachineOpcode();
2848 case AArch64::SBFMWri:
2849 case AArch64::UBFMWri:
2850 case AArch64::SBFMXri:
2851 case AArch64::UBFMXri:
2853 Opd0 =
N->getOperand(0);
2854 Immr =
N->getConstantOperandVal(1);
2855 Imms =
N->getConstantOperandVal(2);
2862bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
2863 unsigned Opc, Immr, Imms;
2868 EVT VT =
N->getValueType(0);
2873 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2874 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2875 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2877 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
2878 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2884 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2885 CurDAG->getTargetConstant(Imms, dl, VT)};
2886 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
2895 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2896 assert((VT == MVT::i32 || VT == MVT::i64) &&
2897 "i32 or i64 mask type expected!");
2901 APInt SignificantDstMask =
2905 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2906 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2939 APInt OpUsefulBits(UsefulBits);
2943 OpUsefulBits <<= MSB - Imm + 1;
2948 OpUsefulBits <<= Imm;
2950 OpUsefulBits <<= MSB + 1;
2953 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2959 UsefulBits &= OpUsefulBits;
2976 APInt Mask(UsefulBits);
2977 Mask.clearAllBits();
2985 Mask.lshrInPlace(ShiftAmt);
2991 Mask.lshrInPlace(ShiftAmt);
3007 APInt OpUsefulBits(UsefulBits);
3021 OpUsefulBits <<= Width;
3024 if (
Op.getOperand(1) == Orig) {
3026 Mask = ResultUsefulBits & OpUsefulBits;
3030 if (
Op.getOperand(0) == Orig)
3032 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3038 OpUsefulBits <<= Width;
3040 OpUsefulBits <<= LSB;
3042 if (
Op.getOperand(1) == Orig) {
3044 Mask = ResultUsefulBits & OpUsefulBits;
3045 Mask.lshrInPlace(LSB);
3048 if (
Op.getOperand(0) == Orig)
3049 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3066 case AArch64::ANDSWri:
3067 case AArch64::ANDSXri:
3068 case AArch64::ANDWri:
3069 case AArch64::ANDXri:
3073 case AArch64::UBFMWri:
3074 case AArch64::UBFMXri:
3077 case AArch64::ORRWrs:
3078 case AArch64::ORRXrs:
3083 case AArch64::BFMWri:
3084 case AArch64::BFMXri:
3087 case AArch64::STRBBui:
3088 case AArch64::STURBBi:
3094 case AArch64::STRHHui:
3095 case AArch64::STURHHi:
3108 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3110 UsefulBits =
APInt(Bitwidth, 0);
3119 UsersUsefulBits |= UsefulBitsForUse;
3124 UsefulBits &= UsersUsefulBits;
3134 EVT VT =
Op.getValueType();
3137 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3140 if (ShlAmount > 0) {
3143 UBFMOpc, dl, VT,
Op,
3148 assert(ShlAmount < 0 &&
"expected right shift");
3149 int ShrAmount = -ShlAmount;
3161 const uint64_t NonZeroBits,
3168 const uint64_t NonZeroBits,
3175 bool BiggerPattern,
SDValue &Src,
3176 int &DstLSB,
int &Width) {
3177 EVT VT =
Op.getValueType();
3186 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3190 switch (
Op.getOpcode()) {
3195 NonZeroBits, Src, DstLSB, Width);
3198 NonZeroBits, Src, DstLSB, Width);
3211 EVT VT =
Op.getValueType();
3212 assert((VT == MVT::i32 || VT == MVT::i64) &&
3213 "Caller guarantees VT is one of i32 or i64");
3226 assert((~AndImm & NonZeroBits) == 0 &&
3227 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3256 if (!BiggerPattern && !AndOp0.
hasOneUse())
3275 <<
"Found large Width in bit-field-positioning -- this indicates no "
3276 "proper combining / constant folding was performed\n");
3285 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3300 "Op.getNode() should be a SHL node to call this function");
3302 "Op.getNode() should shift ShlImm to call this function");
3309 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3333 EVT VT =
Op.getValueType();
3334 assert((VT == MVT::i32 || VT == MVT::i64) &&
3335 "Caller guarantees that type is i32 or i64");
3342 if (!BiggerPattern && !
Op.hasOneUse())
3351 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3359 assert(VT == MVT::i32 || VT == MVT::i64);
3370 EVT VT =
N->getValueType(0);
3371 if (VT != MVT::i32 && VT != MVT::i64)
3389 if (!
And.hasOneUse() ||
3399 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3406 if ((OrImm & NotKnownZero) != 0) {
3418 unsigned ImmS = Width - 1;
3424 bool IsBFI = LSB != 0;
3429 unsigned OrChunks = 0, BFIChunks = 0;
3430 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3431 if (((OrImm >> Shift) & 0xFFFF) != 0)
3433 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3436 if (BFIChunks > OrChunks)
3442 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3450 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3459 if (!Dst.hasOneUse())
3462 EVT VT = Dst.getValueType();
3463 assert((VT == MVT::i32 || VT == MVT::i64) &&
3464 "Caller should guarantee that VT is one of i32 or i64");
3492 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3493 unsigned MaskWidth =
3496 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3502 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3503 ShiftedOperand =
SDValue(UBFMNode, 0);
3532 const bool BiggerPattern) {
3533 EVT VT =
N->getValueType(0);
3534 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3535 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3536 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3537 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3538 assert((VT == MVT::i32 || VT == MVT::i64) &&
3539 "Expect result type to be i32 or i64 since N is combinable to BFM");
3546 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3549 if (BiggerPattern) {
3572 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3634 EVT VT =
N->getValueType(0);
3635 if (VT != MVT::i32 && VT != MVT::i64)
3643 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3644 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3664 for (
int I = 0;
I < 4; ++
I) {
3667 unsigned ImmR, ImmS;
3668 bool BiggerPattern =
I / 2;
3669 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3671 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3677 NumberOfIgnoredLowBits, BiggerPattern)) {
3680 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3681 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3686 Width = ImmS - ImmR + 1;
3697 Src, DstLSB, Width)) {
3705 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3715 APInt BitsToBeInserted =
3718 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3742 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3775 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3777 if (Src->hasOneUse() &&
3780 Src = Src->getOperand(0);
3790 unsigned ImmS = Width - 1;
3796 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3804bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3813 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3826bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3830 EVT VT =
N->getValueType(0);
3831 if (VT != MVT::i32 && VT != MVT::i64)
3837 Op0, DstLSB, Width))
3843 unsigned ImmS = Width - 1;
3846 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3847 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3848 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3849 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3855bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
3856 EVT VT =
N->getValueType(0);
3859 switch (
N->getOpcode()) {
3861 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3864 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3867 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3870 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3878 if (VT == MVT::i32) {
3881 }
else if (VT == MVT::i64) {
3887 SDValue ShiftAmt =
N->getOperand(1);
3907 (Add0Imm %
Size == 0)) {
3913 if (SubVT == MVT::i32) {
3914 NegOpc = AArch64::SUBWrr;
3915 ZeroReg = AArch64::WZR;
3917 assert(SubVT == MVT::i64);
3918 NegOpc = AArch64::SUBXrr;
3919 ZeroReg = AArch64::XZR;
3922 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3923 MachineSDNode *Neg =
3924 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3925 NewShiftAmt =
SDValue(Neg, 0);
3933 if (SubVT == MVT::i32) {
3934 NotOpc = AArch64::ORNWrr;
3935 ZeroReg = AArch64::WZR;
3937 assert(SubVT == MVT::i64);
3938 NotOpc = AArch64::ORNXrr;
3939 ZeroReg = AArch64::XZR;
3942 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3943 MachineSDNode *
Not =
3944 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3945 NewShiftAmt =
SDValue(Not, 0);
3966 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3967 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3968 MachineSDNode *
Ext = CurDAG->getMachineNode(
3969 AArch64::SUBREG_TO_REG,
DL, VT,
3970 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3971 NewShiftAmt =
SDValue(Ext, 0);
3975 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3982 bool isReciprocal) {
3985 FVal = CN->getValueAPF();
3988 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4017 if (!IsExact || !IntVal.isPowerOf2())
4019 unsigned FBits = IntVal.logBase2();
4023 if (FBits == 0 || FBits > RegWidth)
return false;
4029bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4030 unsigned RegWidth) {
4035bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4037 unsigned RegWidth) {
4047 RegString.
split(Fields,
':');
4049 if (Fields.
size() == 1)
4053 &&
"Invalid number of fields in read register string");
4056 bool AllIntFields =
true;
4060 AllIntFields &= !
Field.getAsInteger(10, IntField);
4061 Ops.push_back(IntField);
4065 "Unexpected non-integer value in special register string.");
4070 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4071 (
Ops[3] << 3) | (
Ops[4]);
4078bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4080 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4083 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4085 unsigned Opcode64Bit = AArch64::MRS;
4090 const auto *TheReg =
4091 AArch64SysReg::lookupSysRegByName(RegString->getString());
4092 if (TheReg && TheReg->Readable &&
4093 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4094 Imm = TheReg->Encoding;
4100 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4101 Opcode64Bit = AArch64::ADR;
4109 SDValue InChain =
N->getOperand(0);
4110 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4111 if (!ReadIs128Bit) {
4112 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4113 {SysRegImm, InChain});
4115 SDNode *MRRS = CurDAG->getMachineNode(
4117 {MVT::Untyped , MVT::Other },
4118 {SysRegImm, InChain});
4122 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4124 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4130 ReplaceUses(
SDValue(
N, 2), OutChain);
4139bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4141 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4144 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4146 if (!WriteIs128Bit) {
4152 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4155 "Expected a constant integer expression.");
4156 unsigned Reg = PMapper->Encoding;
4157 uint64_t Immed =
N->getConstantOperandVal(2);
4158 CurDAG->SelectNodeTo(
4159 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4160 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4166 if (trySelectPState(
4167 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4168 AArch64::MSRpstateImm4))
4170 if (trySelectPState(
4171 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4172 AArch64::MSRpstateImm1))
4181 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4182 if (TheReg && TheReg->Writeable &&
4183 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4184 Imm = TheReg->Encoding;
4193 if (!WriteIs128Bit) {
4194 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4195 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4196 N->getOperand(2), InChain);
4200 SDNode *Pair = CurDAG->getMachineNode(
4201 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4202 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4205 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4207 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4209 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4210 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4218bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4223 if (Subtarget->hasLSE())
return false;
4225 if (MemTy == MVT::i8)
4226 Opcode = AArch64::CMP_SWAP_8;
4227 else if (MemTy == MVT::i16)
4228 Opcode = AArch64::CMP_SWAP_16;
4229 else if (MemTy == MVT::i32)
4230 Opcode = AArch64::CMP_SWAP_32;
4231 else if (MemTy == MVT::i64)
4232 Opcode = AArch64::CMP_SWAP_64;
4236 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4237 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4239 SDNode *CmpSwap = CurDAG->getMachineNode(
4241 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4248 CurDAG->RemoveDeadNode(
N);
4253bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4254 SDValue &Shift,
bool Negate) {
4268 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4275 if ((Val & ~0xff) == 0) {
4276 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4281 if ((Val & ~0xff00) == 0) {
4282 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4294bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4318 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4319 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4326 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4327 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4331 if (Val <= 65280 && Val % 256 == 0) {
4332 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4333 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4344bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4354 int32_t ImmVal, ShiftVal;
4359 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4360 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4364bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4366 int64_t ImmVal = CNode->getSExtValue();
4368 if (ImmVal >= -128 && ImmVal < 128) {
4369 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4376bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4378 uint64_t ImmVal = CNode->getZExtValue();
4388 ImmVal &= 0xFFFFFFFF;
4397 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4404bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4408 ImmVal = CI->getZExtValue();
4410 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4421 ImmVal |= ImmVal << 8;
4422 ImmVal |= ImmVal << 16;
4423 ImmVal |= ImmVal << 32;
4427 ImmVal |= ImmVal << 16;
4428 ImmVal |= ImmVal << 32;
4431 ImmVal &= 0xFFFFFFFF;
4432 ImmVal |= ImmVal << 32;
4444 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4453bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4454 uint64_t
High,
bool AllowSaturation,
4457 uint64_t ImmVal = CN->getZExtValue();
4464 if (ImmVal >
High) {
4465 if (!AllowSaturation)
4470 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4477bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4491 const TargetLowering *TLI = getTargetLowering();
4494 SDValue FiOp = CurDAG->getTargetFrameIndex(
4496 int TagOffset =
N->getConstantOperandVal(3);
4498 SDNode *Out = CurDAG->getMachineNode(
4499 AArch64::TAGPstack,
DL, MVT::i64,
4500 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4501 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4502 ReplaceNode(
N, Out);
4506void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4508 "llvm.aarch64.tagp third argument must be an immediate");
4509 if (trySelectStackSlotTagP(
N))
4516 int TagOffset =
N->getConstantOperandVal(3);
4517 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4518 {
N->getOperand(1),
N->getOperand(2)});
4519 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4520 {
SDValue(N1, 0),
N->getOperand(2)});
4521 SDNode *N3 = CurDAG->getMachineNode(
4522 AArch64::ADDG,
DL, MVT::i64,
4523 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4524 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4528bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4532 if (
N->getConstantOperandVal(2) != 0)
4534 if (!
N->getOperand(0).isUndef())
4538 EVT VT =
N->getValueType(0);
4539 EVT InVT =
N->getOperand(1).getValueType();
4550 "Expected to insert into a packed scalable vector!");
4553 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4554 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4555 N->getOperand(1), RC));
4559bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4563 if (
N->getConstantOperandVal(1) != 0)
4567 EVT VT =
N->getValueType(0);
4568 EVT InVT =
N->getOperand(0).getValueType();
4579 "Expected to extract from a packed scalable vector!");
4582 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4583 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4584 N->getOperand(0), RC));
4588bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4594 EVT VT =
N->getValueType(0);
4607 (Subtarget->hasSVE2() ||
4608 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4609 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4612 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4616 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4617 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4618 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4625 bool IsXOROperand =
true;
4627 IsXOROperand =
false;
4633 APInt ShlAmt, ShrAmt;
4641 if (!IsXOROperand) {
4643 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4646 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4647 SDNode *SubRegToReg = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL,
4648 VT, Zero, MOVIV, ZSub);
4659 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4660 AArch64::XAR_ZZZI_D})) {
4661 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4686 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4696 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4704 bool IsXOROperand =
true;
4706 IsXOROperand =
false;
4709 R1 =
XOR.getOperand(0);
4710 R2 =
XOR.getOperand(1);
4720 if (ShAmt + HsAmt != VTSizeInBits)
4723 if (!IsXOROperand) {
4726 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4735 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4741 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4742 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4744 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4747 if (
R2.getValueType() == VT)
4748 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4756 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT, Undef,
4761 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4767 SDNode *XAR =
nullptr;
4771 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4772 AArch64::XAR_ZZZI_D}))
4773 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4775 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4778 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4784 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4785 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4788 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4789 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4795 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4799 ReplaceNode(
N, XAR);
4803void AArch64DAGToDAGISel::Select(SDNode *Node) {
4805 if (
Node->isMachineOpcode()) {
4807 Node->setNodeId(-1);
4812 EVT VT =
Node->getValueType(0);
4814 switch (
Node->getOpcode()) {
4818 case ISD::ATOMIC_CMP_SWAP:
4819 if (SelectCMP_SWAP(Node))
4824 case AArch64ISD::MRRS:
4825 if (tryReadRegister(Node))
4830 case AArch64ISD::MSRR:
4831 if (tryWriteRegister(Node))
4838 if (tryIndexedLoad(Node))
4847 if (tryBitfieldExtractOp(Node))
4849 if (tryBitfieldInsertInZeroOp(Node))
4854 if (tryShiftAmountMod(Node))
4859 if (tryBitfieldExtractOpFromSExt(Node))
4864 if (tryBitfieldInsertOp(Node))
4866 if (trySelectXAR(Node))
4871 if (trySelectCastScalableToFixedLengthVector(Node))
4877 if (trySelectCastFixedLengthToScalableVector(Node))
4886 if (ConstNode->
isZero()) {
4887 if (VT == MVT::i32) {
4889 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
4890 ReplaceNode(Node,
New.getNode());
4892 }
else if (VT == MVT::i64) {
4894 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
4895 ReplaceNode(Node,
New.getNode());
4906 const TargetLowering *TLI = getTargetLowering();
4907 SDValue TFI = CurDAG->getTargetFrameIndex(
4910 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4911 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4912 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
4916 unsigned IntNo =
Node->getConstantOperandVal(1);
4920 case Intrinsic::aarch64_gcsss: {
4924 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4926 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4927 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4928 MVT::Other, Zero,
SDValue(SS1, 0));
4929 ReplaceNode(Node, SS2);
4932 case Intrinsic::aarch64_ldaxp:
4933 case Intrinsic::aarch64_ldxp: {
4935 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4940 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4941 MVT::Other, MemAddr, Chain);
4944 MachineMemOperand *MemOp =
4947 ReplaceNode(Node, Ld);
4950 case Intrinsic::aarch64_stlxp:
4951 case Intrinsic::aarch64_stxp: {
4953 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4961 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4963 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
4965 MachineMemOperand *MemOp =
4969 ReplaceNode(Node, St);
4972 case Intrinsic::aarch64_neon_ld1x2:
4973 if (VT == MVT::v8i8) {
4974 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4976 }
else if (VT == MVT::v16i8) {
4977 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4979 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4980 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4982 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4983 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4985 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4986 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4988 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4989 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4991 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4992 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4994 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4995 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4999 case Intrinsic::aarch64_neon_ld1x3:
5000 if (VT == MVT::v8i8) {
5001 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5003 }
else if (VT == MVT::v16i8) {
5004 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5006 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5007 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5009 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5010 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5012 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5013 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5015 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5016 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5018 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5019 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5021 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5022 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5026 case Intrinsic::aarch64_neon_ld1x4:
5027 if (VT == MVT::v8i8) {
5028 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5030 }
else if (VT == MVT::v16i8) {
5031 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5033 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5034 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5036 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5037 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5039 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5040 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5042 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5043 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5045 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5046 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5048 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5049 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5053 case Intrinsic::aarch64_neon_ld2:
5054 if (VT == MVT::v8i8) {
5055 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5057 }
else if (VT == MVT::v16i8) {
5058 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5060 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5061 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5063 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5064 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5066 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5067 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5069 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5070 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5072 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5073 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5075 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5076 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5080 case Intrinsic::aarch64_neon_ld3:
5081 if (VT == MVT::v8i8) {
5082 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5084 }
else if (VT == MVT::v16i8) {
5085 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5087 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5088 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5090 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5091 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5093 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5094 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5096 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5097 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5099 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5100 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5102 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5103 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5107 case Intrinsic::aarch64_neon_ld4:
5108 if (VT == MVT::v8i8) {
5109 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5111 }
else if (VT == MVT::v16i8) {
5112 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5114 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5115 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5117 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5118 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5120 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5121 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5123 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5124 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5126 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5127 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5129 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5130 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5134 case Intrinsic::aarch64_neon_ld2r:
5135 if (VT == MVT::v8i8) {
5136 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5138 }
else if (VT == MVT::v16i8) {
5139 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5141 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5142 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5144 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5145 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5147 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5148 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5150 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5151 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5153 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5154 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5156 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5157 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5161 case Intrinsic::aarch64_neon_ld3r:
5162 if (VT == MVT::v8i8) {
5163 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5165 }
else if (VT == MVT::v16i8) {
5166 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5168 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5169 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5171 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5172 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5174 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5175 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5177 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5178 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5180 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5181 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5183 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5184 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5188 case Intrinsic::aarch64_neon_ld4r:
5189 if (VT == MVT::v8i8) {
5190 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5192 }
else if (VT == MVT::v16i8) {
5193 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5195 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5196 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5198 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5199 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5201 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5202 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5204 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5205 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5207 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5208 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5210 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5211 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5215 case Intrinsic::aarch64_neon_ld2lane:
5216 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5217 SelectLoadLane(Node, 2, AArch64::LD2i8);
5219 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5220 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5221 SelectLoadLane(Node, 2, AArch64::LD2i16);
5223 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5225 SelectLoadLane(Node, 2, AArch64::LD2i32);
5227 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5229 SelectLoadLane(Node, 2, AArch64::LD2i64);
5233 case Intrinsic::aarch64_neon_ld3lane:
5234 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5235 SelectLoadLane(Node, 3, AArch64::LD3i8);
5237 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5238 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5239 SelectLoadLane(Node, 3, AArch64::LD3i16);
5241 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5243 SelectLoadLane(Node, 3, AArch64::LD3i32);
5245 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5247 SelectLoadLane(Node, 3, AArch64::LD3i64);
5251 case Intrinsic::aarch64_neon_ld4lane:
5252 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5253 SelectLoadLane(Node, 4, AArch64::LD4i8);
5255 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5256 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5257 SelectLoadLane(Node, 4, AArch64::LD4i16);
5259 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5261 SelectLoadLane(Node, 4, AArch64::LD4i32);
5263 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5265 SelectLoadLane(Node, 4, AArch64::LD4i64);
5269 case Intrinsic::aarch64_ld64b:
5270 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5272 case Intrinsic::aarch64_sve_ld2q_sret: {
5273 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5276 case Intrinsic::aarch64_sve_ld3q_sret: {
5277 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5280 case Intrinsic::aarch64_sve_ld4q_sret: {
5281 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5284 case Intrinsic::aarch64_sve_ld2_sret: {
5285 if (VT == MVT::nxv16i8) {
5286 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5289 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5290 VT == MVT::nxv8bf16) {
5291 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5294 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5295 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5298 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5299 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5305 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5306 if (VT == MVT::nxv16i8) {
5307 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5308 SelectContiguousMultiVectorLoad(
5309 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5310 else if (Subtarget->hasSVE2p1())
5311 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5316 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5317 VT == MVT::nxv8bf16) {
5318 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5319 SelectContiguousMultiVectorLoad(
5320 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5321 else if (Subtarget->hasSVE2p1())
5322 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5327 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5328 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5329 SelectContiguousMultiVectorLoad(
5330 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5331 else if (Subtarget->hasSVE2p1())
5332 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5337 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5338 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5339 SelectContiguousMultiVectorLoad(
5340 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5341 else if (Subtarget->hasSVE2p1())
5342 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5350 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5351 if (VT == MVT::nxv16i8) {
5352 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5353 SelectContiguousMultiVectorLoad(
5354 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5355 else if (Subtarget->hasSVE2p1())
5356 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5361 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5362 VT == MVT::nxv8bf16) {
5363 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5364 SelectContiguousMultiVectorLoad(
5365 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5366 else if (Subtarget->hasSVE2p1())
5367 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5372 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5373 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5374 SelectContiguousMultiVectorLoad(
5375 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5376 else if (Subtarget->hasSVE2p1())
5377 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5382 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5383 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5384 SelectContiguousMultiVectorLoad(
5385 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5386 else if (Subtarget->hasSVE2p1())
5387 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5395 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5396 if (VT == MVT::nxv16i8) {
5397 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5398 SelectContiguousMultiVectorLoad(Node, 2, 0,
5399 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5400 AArch64::LDNT1B_2Z_PSEUDO);
5401 else if (Subtarget->hasSVE2p1())
5402 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5403 AArch64::LDNT1B_2Z);
5407 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5408 VT == MVT::nxv8bf16) {
5409 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5410 SelectContiguousMultiVectorLoad(Node, 2, 1,
5411 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5412 AArch64::LDNT1H_2Z_PSEUDO);
5413 else if (Subtarget->hasSVE2p1())
5414 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5415 AArch64::LDNT1H_2Z);
5419 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5420 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5421 SelectContiguousMultiVectorLoad(Node, 2, 2,
5422 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5423 AArch64::LDNT1W_2Z_PSEUDO);
5424 else if (Subtarget->hasSVE2p1())
5425 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5426 AArch64::LDNT1W_2Z);
5430 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5431 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5432 SelectContiguousMultiVectorLoad(Node, 2, 3,
5433 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5434 AArch64::LDNT1D_2Z_PSEUDO);
5435 else if (Subtarget->hasSVE2p1())
5436 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5437 AArch64::LDNT1D_2Z);
5444 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5445 if (VT == MVT::nxv16i8) {
5446 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5447 SelectContiguousMultiVectorLoad(Node, 4, 0,
5448 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5449 AArch64::LDNT1B_4Z_PSEUDO);
5450 else if (Subtarget->hasSVE2p1())
5451 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5452 AArch64::LDNT1B_4Z);
5456 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5457 VT == MVT::nxv8bf16) {
5458 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5459 SelectContiguousMultiVectorLoad(Node, 4, 1,
5460 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5461 AArch64::LDNT1H_4Z_PSEUDO);
5462 else if (Subtarget->hasSVE2p1())
5463 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5464 AArch64::LDNT1H_4Z);
5468 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5469 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5470 SelectContiguousMultiVectorLoad(Node, 4, 2,
5471 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5472 AArch64::LDNT1W_4Z_PSEUDO);
5473 else if (Subtarget->hasSVE2p1())
5474 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5475 AArch64::LDNT1W_4Z);
5479 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5480 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5481 SelectContiguousMultiVectorLoad(Node, 4, 3,
5482 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5483 AArch64::LDNT1D_4Z_PSEUDO);
5484 else if (Subtarget->hasSVE2p1())
5485 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5486 AArch64::LDNT1D_4Z);
5493 case Intrinsic::aarch64_sve_ld3_sret: {
5494 if (VT == MVT::nxv16i8) {
5495 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5498 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5499 VT == MVT::nxv8bf16) {
5500 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5503 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5504 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5507 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5508 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5514 case Intrinsic::aarch64_sve_ld4_sret: {
5515 if (VT == MVT::nxv16i8) {
5516 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5519 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5520 VT == MVT::nxv8bf16) {
5521 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5524 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5525 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5528 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5529 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5535 case Intrinsic::aarch64_sme_read_hor_vg2: {
5536 if (VT == MVT::nxv16i8) {
5537 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5538 AArch64::MOVA_2ZMXI_H_B);
5540 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5541 VT == MVT::nxv8bf16) {
5542 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5543 AArch64::MOVA_2ZMXI_H_H);
5545 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5546 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5547 AArch64::MOVA_2ZMXI_H_S);
5549 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5550 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5551 AArch64::MOVA_2ZMXI_H_D);
5556 case Intrinsic::aarch64_sme_read_ver_vg2: {
5557 if (VT == MVT::nxv16i8) {
5558 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5559 AArch64::MOVA_2ZMXI_V_B);
5561 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5562 VT == MVT::nxv8bf16) {
5563 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5564 AArch64::MOVA_2ZMXI_V_H);
5566 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5567 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5568 AArch64::MOVA_2ZMXI_V_S);
5570 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5571 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5572 AArch64::MOVA_2ZMXI_V_D);
5577 case Intrinsic::aarch64_sme_read_hor_vg4: {
5578 if (VT == MVT::nxv16i8) {
5579 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5580 AArch64::MOVA_4ZMXI_H_B);
5582 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5583 VT == MVT::nxv8bf16) {
5584 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5585 AArch64::MOVA_4ZMXI_H_H);
5587 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5588 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5589 AArch64::MOVA_4ZMXI_H_S);
5591 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5592 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5593 AArch64::MOVA_4ZMXI_H_D);
5598 case Intrinsic::aarch64_sme_read_ver_vg4: {
5599 if (VT == MVT::nxv16i8) {
5600 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5601 AArch64::MOVA_4ZMXI_V_B);
5603 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5604 VT == MVT::nxv8bf16) {
5605 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5606 AArch64::MOVA_4ZMXI_V_H);
5608 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5609 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5610 AArch64::MOVA_4ZMXI_V_S);
5612 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5613 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5614 AArch64::MOVA_4ZMXI_V_D);
5619 case Intrinsic::aarch64_sme_read_vg1x2: {
5620 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5621 AArch64::MOVA_VG2_2ZMXI);
5624 case Intrinsic::aarch64_sme_read_vg1x4: {
5625 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5626 AArch64::MOVA_VG4_4ZMXI);
5629 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5630 if (VT == MVT::nxv16i8) {
5631 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5633 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5634 VT == MVT::nxv8bf16) {
5635 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5637 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5638 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5640 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5641 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5646 case Intrinsic::aarch64_sme_readz_vert_x2: {
5647 if (VT == MVT::nxv16i8) {
5648 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5650 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5651 VT == MVT::nxv8bf16) {
5652 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5654 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5655 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5657 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5658 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5663 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5664 if (VT == MVT::nxv16i8) {
5665 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5667 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5668 VT == MVT::nxv8bf16) {
5669 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5671 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5672 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5674 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5675 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5680 case Intrinsic::aarch64_sme_readz_vert_x4: {
5681 if (VT == MVT::nxv16i8) {
5682 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5684 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5685 VT == MVT::nxv8bf16) {
5686 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5688 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5689 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5691 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5692 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5697 case Intrinsic::aarch64_sme_readz_x2: {
5698 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5702 case Intrinsic::aarch64_sme_readz_x4: {
5703 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5707 case Intrinsic::swift_async_context_addr: {
5710 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5712 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5713 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5714 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5716 ReplaceUses(
SDValue(Node, 0), Res);
5718 CurDAG->RemoveDeadNode(Node);
5720 auto &MF = CurDAG->getMachineFunction();
5721 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5722 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5725 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5727 Node->getValueType(0),
5728 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5729 AArch64::LUTI2_4ZTZI_S}))
5731 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5734 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5736 Node->getValueType(0),
5737 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5739 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5742 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5744 Node->getValueType(0),
5745 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5746 AArch64::LUTI2_2ZTZI_S}))
5748 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5751 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5753 Node->getValueType(0),
5754 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5755 AArch64::LUTI4_2ZTZI_S}))
5757 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5760 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5761 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5764 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5766 Node->getValueType(0),
5767 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5768 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5770 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5772 Node->getValueType(0),
5773 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5774 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5776 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5778 Node->getValueType(0),
5779 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5780 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5782 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5784 Node->getValueType(0),
5785 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5786 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5791 unsigned IntNo =
Node->getConstantOperandVal(0);
5795 case Intrinsic::aarch64_tagp:
5799 case Intrinsic::ptrauth_auth:
5800 SelectPtrauthAuth(Node);
5803 case Intrinsic::ptrauth_resign:
5804 SelectPtrauthResign(Node);
5807 case Intrinsic::aarch64_neon_tbl2:
5808 SelectTable(Node, 2,
5809 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5812 case Intrinsic::aarch64_neon_tbl3:
5813 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5814 : AArch64::TBLv16i8Three,
5817 case Intrinsic::aarch64_neon_tbl4:
5818 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5819 : AArch64::TBLv16i8Four,
5822 case Intrinsic::aarch64_neon_tbx2:
5823 SelectTable(Node, 2,
5824 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5827 case Intrinsic::aarch64_neon_tbx3:
5828 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5829 : AArch64::TBXv16i8Three,
5832 case Intrinsic::aarch64_neon_tbx4:
5833 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5834 : AArch64::TBXv16i8Four,
5837 case Intrinsic::aarch64_sve_srshl_single_x2:
5839 Node->getValueType(0),
5840 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5841 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5842 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5844 case Intrinsic::aarch64_sve_srshl_single_x4:
5846 Node->getValueType(0),
5847 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5848 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5849 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5851 case Intrinsic::aarch64_sve_urshl_single_x2:
5853 Node->getValueType(0),
5854 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5855 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5856 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5858 case Intrinsic::aarch64_sve_urshl_single_x4:
5860 Node->getValueType(0),
5861 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5862 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5863 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5865 case Intrinsic::aarch64_sve_srshl_x2:
5867 Node->getValueType(0),
5868 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5869 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5870 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5872 case Intrinsic::aarch64_sve_srshl_x4:
5874 Node->getValueType(0),
5875 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5876 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5877 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5879 case Intrinsic::aarch64_sve_urshl_x2:
5881 Node->getValueType(0),
5882 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5883 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5884 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5886 case Intrinsic::aarch64_sve_urshl_x4:
5888 Node->getValueType(0),
5889 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5890 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5891 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5893 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5895 Node->getValueType(0),
5896 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5897 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5898 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5900 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5902 Node->getValueType(0),
5903 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5904 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5905 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5907 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5909 Node->getValueType(0),
5910 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5911 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5912 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5914 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5916 Node->getValueType(0),
5917 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5918 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5919 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5921 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5923 Node->getValueType(0),
5924 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5925 AArch64::FSCALE_2ZZ_D}))
5926 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5928 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5930 Node->getValueType(0),
5931 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5932 AArch64::FSCALE_4ZZ_D}))
5933 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5935 case Intrinsic::aarch64_sme_fp8_scale_x2:
5937 Node->getValueType(0),
5938 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5939 AArch64::FSCALE_2Z2Z_D}))
5940 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5942 case Intrinsic::aarch64_sme_fp8_scale_x4:
5944 Node->getValueType(0),
5945 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5946 AArch64::FSCALE_4Z4Z_D}))
5947 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5949 case Intrinsic::aarch64_sve_whilege_x2:
5951 Node->getValueType(0),
5952 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5953 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5954 SelectWhilePair(Node,
Op);
5956 case Intrinsic::aarch64_sve_whilegt_x2:
5958 Node->getValueType(0),
5959 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5960 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5961 SelectWhilePair(Node,
Op);
5963 case Intrinsic::aarch64_sve_whilehi_x2:
5965 Node->getValueType(0),
5966 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5967 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5968 SelectWhilePair(Node,
Op);
5970 case Intrinsic::aarch64_sve_whilehs_x2:
5972 Node->getValueType(0),
5973 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5974 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5975 SelectWhilePair(Node,
Op);
5977 case Intrinsic::aarch64_sve_whilele_x2:
5979 Node->getValueType(0),
5980 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5981 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5982 SelectWhilePair(Node,
Op);
5984 case Intrinsic::aarch64_sve_whilelo_x2:
5986 Node->getValueType(0),
5987 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5988 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5989 SelectWhilePair(Node,
Op);
5991 case Intrinsic::aarch64_sve_whilels_x2:
5993 Node->getValueType(0),
5994 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5995 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5996 SelectWhilePair(Node,
Op);
5998 case Intrinsic::aarch64_sve_whilelt_x2:
6000 Node->getValueType(0),
6001 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6002 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6003 SelectWhilePair(Node,
Op);
6005 case Intrinsic::aarch64_sve_smax_single_x2:
6007 Node->getValueType(0),
6008 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6009 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6010 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6012 case Intrinsic::aarch64_sve_umax_single_x2:
6014 Node->getValueType(0),
6015 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6016 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6017 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6019 case Intrinsic::aarch64_sve_fmax_single_x2:
6021 Node->getValueType(0),
6022 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6023 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6024 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6026 case Intrinsic::aarch64_sve_smax_single_x4:
6028 Node->getValueType(0),
6029 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6030 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6031 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6033 case Intrinsic::aarch64_sve_umax_single_x4:
6035 Node->getValueType(0),
6036 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6037 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6038 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6040 case Intrinsic::aarch64_sve_fmax_single_x4:
6042 Node->getValueType(0),
6043 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6044 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6045 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6047 case Intrinsic::aarch64_sve_smin_single_x2:
6049 Node->getValueType(0),
6050 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6051 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6052 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6054 case Intrinsic::aarch64_sve_umin_single_x2:
6056 Node->getValueType(0),
6057 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6058 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6059 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6061 case Intrinsic::aarch64_sve_fmin_single_x2:
6063 Node->getValueType(0),
6064 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6065 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6066 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6068 case Intrinsic::aarch64_sve_smin_single_x4:
6070 Node->getValueType(0),
6071 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6072 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6073 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6075 case Intrinsic::aarch64_sve_umin_single_x4:
6077 Node->getValueType(0),
6078 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6079 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6080 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6082 case Intrinsic::aarch64_sve_fmin_single_x4:
6084 Node->getValueType(0),
6085 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6086 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6087 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6089 case Intrinsic::aarch64_sve_smax_x2:
6091 Node->getValueType(0),
6092 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6093 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6094 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6096 case Intrinsic::aarch64_sve_umax_x2:
6098 Node->getValueType(0),
6099 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6100 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6101 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6103 case Intrinsic::aarch64_sve_fmax_x2:
6105 Node->getValueType(0),
6106 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6107 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6108 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6110 case Intrinsic::aarch64_sve_smax_x4:
6112 Node->getValueType(0),
6113 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6114 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6115 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6117 case Intrinsic::aarch64_sve_umax_x4:
6119 Node->getValueType(0),
6120 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6121 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6122 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6124 case Intrinsic::aarch64_sve_fmax_x4:
6126 Node->getValueType(0),
6127 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6128 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6129 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6131 case Intrinsic::aarch64_sme_famax_x2:
6133 Node->getValueType(0),
6134 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6135 AArch64::FAMAX_2Z2Z_D}))
6136 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6138 case Intrinsic::aarch64_sme_famax_x4:
6140 Node->getValueType(0),
6141 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6142 AArch64::FAMAX_4Z4Z_D}))
6143 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6145 case Intrinsic::aarch64_sme_famin_x2:
6147 Node->getValueType(0),
6148 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6149 AArch64::FAMIN_2Z2Z_D}))
6150 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6152 case Intrinsic::aarch64_sme_famin_x4:
6154 Node->getValueType(0),
6155 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6156 AArch64::FAMIN_4Z4Z_D}))
6157 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6159 case Intrinsic::aarch64_sve_smin_x2:
6161 Node->getValueType(0),
6162 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6163 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6164 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6166 case Intrinsic::aarch64_sve_umin_x2:
6168 Node->getValueType(0),
6169 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6170 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6171 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6173 case Intrinsic::aarch64_sve_fmin_x2:
6175 Node->getValueType(0),
6176 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6177 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6178 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6180 case Intrinsic::aarch64_sve_smin_x4:
6182 Node->getValueType(0),
6183 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6184 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6185 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6187 case Intrinsic::aarch64_sve_umin_x4:
6189 Node->getValueType(0),
6190 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6191 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6192 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6194 case Intrinsic::aarch64_sve_fmin_x4:
6196 Node->getValueType(0),
6197 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6198 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6199 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6201 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6203 Node->getValueType(0),
6204 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6205 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6206 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6208 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6210 Node->getValueType(0),
6211 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6212 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6213 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6215 case Intrinsic::aarch64_sve_fminnm_single_x2:
6217 Node->getValueType(0),
6218 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6219 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6220 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6222 case Intrinsic::aarch64_sve_fminnm_single_x4:
6224 Node->getValueType(0),
6225 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6226 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6227 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6229 case Intrinsic::aarch64_sve_fmaxnm_x2:
6231 Node->getValueType(0),
6232 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6233 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6234 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6236 case Intrinsic::aarch64_sve_fmaxnm_x4:
6238 Node->getValueType(0),
6239 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6240 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6241 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6243 case Intrinsic::aarch64_sve_fminnm_x2:
6245 Node->getValueType(0),
6246 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6247 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6248 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6250 case Intrinsic::aarch64_sve_fminnm_x4:
6252 Node->getValueType(0),
6253 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6254 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6255 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6257 case Intrinsic::aarch64_sve_fcvtzs_x2:
6258 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6260 case Intrinsic::aarch64_sve_scvtf_x2:
6261 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6263 case Intrinsic::aarch64_sve_fcvtzu_x2:
6264 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6266 case Intrinsic::aarch64_sve_ucvtf_x2:
6267 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6269 case Intrinsic::aarch64_sve_fcvtzs_x4:
6270 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6272 case Intrinsic::aarch64_sve_scvtf_x4:
6273 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6275 case Intrinsic::aarch64_sve_fcvtzu_x4:
6276 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6278 case Intrinsic::aarch64_sve_ucvtf_x4:
6279 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6281 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6282 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6284 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6285 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6287 case Intrinsic::aarch64_sve_sclamp_single_x2:
6289 Node->getValueType(0),
6290 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6291 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6292 SelectClamp(Node, 2,
Op);
6294 case Intrinsic::aarch64_sve_uclamp_single_x2:
6296 Node->getValueType(0),
6297 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6298 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6299 SelectClamp(Node, 2,
Op);
6301 case Intrinsic::aarch64_sve_fclamp_single_x2:
6303 Node->getValueType(0),
6304 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6305 AArch64::FCLAMP_VG2_2Z2Z_D}))
6306 SelectClamp(Node, 2,
Op);
6308 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6309 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6311 case Intrinsic::aarch64_sve_sclamp_single_x4:
6313 Node->getValueType(0),
6314 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6315 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6316 SelectClamp(Node, 4,
Op);
6318 case Intrinsic::aarch64_sve_uclamp_single_x4:
6320 Node->getValueType(0),
6321 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6322 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6323 SelectClamp(Node, 4,
Op);
6325 case Intrinsic::aarch64_sve_fclamp_single_x4:
6327 Node->getValueType(0),
6328 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6329 AArch64::FCLAMP_VG4_4Z4Z_D}))
6330 SelectClamp(Node, 4,
Op);
6332 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6333 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6335 case Intrinsic::aarch64_sve_add_single_x2:
6337 Node->getValueType(0),
6338 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6339 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6340 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6342 case Intrinsic::aarch64_sve_add_single_x4:
6344 Node->getValueType(0),
6345 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6346 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6347 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6349 case Intrinsic::aarch64_sve_zip_x2:
6351 Node->getValueType(0),
6352 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6353 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6354 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6356 case Intrinsic::aarch64_sve_zipq_x2:
6357 SelectUnaryMultiIntrinsic(Node, 2,
false,
6358 AArch64::ZIP_VG2_2ZZZ_Q);
6360 case Intrinsic::aarch64_sve_zip_x4:
6362 Node->getValueType(0),
6363 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6364 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6365 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6367 case Intrinsic::aarch64_sve_zipq_x4:
6368 SelectUnaryMultiIntrinsic(Node, 4,
true,
6369 AArch64::ZIP_VG4_4Z4Z_Q);
6371 case Intrinsic::aarch64_sve_uzp_x2:
6373 Node->getValueType(0),
6374 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6375 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6376 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6378 case Intrinsic::aarch64_sve_uzpq_x2:
6379 SelectUnaryMultiIntrinsic(Node, 2,
false,
6380 AArch64::UZP_VG2_2ZZZ_Q);
6382 case Intrinsic::aarch64_sve_uzp_x4:
6384 Node->getValueType(0),
6385 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6386 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6387 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6389 case Intrinsic::aarch64_sve_uzpq_x4:
6390 SelectUnaryMultiIntrinsic(Node, 4,
true,
6391 AArch64::UZP_VG4_4Z4Z_Q);
6393 case Intrinsic::aarch64_sve_sel_x2:
6395 Node->getValueType(0),
6396 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6397 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6398 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6400 case Intrinsic::aarch64_sve_sel_x4:
6402 Node->getValueType(0),
6403 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6404 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6405 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6407 case Intrinsic::aarch64_sve_frinta_x2:
6408 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6410 case Intrinsic::aarch64_sve_frinta_x4:
6411 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6413 case Intrinsic::aarch64_sve_frintm_x2:
6414 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6416 case Intrinsic::aarch64_sve_frintm_x4:
6417 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6419 case Intrinsic::aarch64_sve_frintn_x2:
6420 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6422 case Intrinsic::aarch64_sve_frintn_x4:
6423 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6425 case Intrinsic::aarch64_sve_frintp_x2:
6426 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6428 case Intrinsic::aarch64_sve_frintp_x4:
6429 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6431 case Intrinsic::aarch64_sve_sunpk_x2:
6433 Node->getValueType(0),
6434 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6435 AArch64::SUNPK_VG2_2ZZ_D}))
6436 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6438 case Intrinsic::aarch64_sve_uunpk_x2:
6440 Node->getValueType(0),
6441 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6442 AArch64::UUNPK_VG2_2ZZ_D}))
6443 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6445 case Intrinsic::aarch64_sve_sunpk_x4:
6447 Node->getValueType(0),
6448 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6449 AArch64::SUNPK_VG4_4Z2Z_D}))
6450 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6452 case Intrinsic::aarch64_sve_uunpk_x4:
6454 Node->getValueType(0),
6455 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6456 AArch64::UUNPK_VG4_4Z2Z_D}))
6457 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6459 case Intrinsic::aarch64_sve_pext_x2: {
6461 Node->getValueType(0),
6462 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6463 AArch64::PEXT_2PCI_D}))
6464 SelectPExtPair(Node,
Op);
6471 unsigned IntNo =
Node->getConstantOperandVal(1);
6472 if (
Node->getNumOperands() >= 3)
6473 VT =
Node->getOperand(2)->getValueType(0);
6477 case Intrinsic::aarch64_neon_st1x2: {
6478 if (VT == MVT::v8i8) {
6479 SelectStore(Node, 2, AArch64::ST1Twov8b);
6481 }
else if (VT == MVT::v16i8) {
6482 SelectStore(Node, 2, AArch64::ST1Twov16b);
6484 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6485 VT == MVT::v4bf16) {
6486 SelectStore(Node, 2, AArch64::ST1Twov4h);
6488 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6489 VT == MVT::v8bf16) {
6490 SelectStore(Node, 2, AArch64::ST1Twov8h);
6492 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6493 SelectStore(Node, 2, AArch64::ST1Twov2s);
6495 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6496 SelectStore(Node, 2, AArch64::ST1Twov4s);
6498 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6499 SelectStore(Node, 2, AArch64::ST1Twov2d);
6501 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6502 SelectStore(Node, 2, AArch64::ST1Twov1d);
6507 case Intrinsic::aarch64_neon_st1x3: {
6508 if (VT == MVT::v8i8) {
6509 SelectStore(Node, 3, AArch64::ST1Threev8b);
6511 }
else if (VT == MVT::v16i8) {
6512 SelectStore(Node, 3, AArch64::ST1Threev16b);
6514 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6515 VT == MVT::v4bf16) {
6516 SelectStore(Node, 3, AArch64::ST1Threev4h);
6518 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6519 VT == MVT::v8bf16) {
6520 SelectStore(Node, 3, AArch64::ST1Threev8h);
6522 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6523 SelectStore(Node, 3, AArch64::ST1Threev2s);
6525 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6526 SelectStore(Node, 3, AArch64::ST1Threev4s);
6528 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6529 SelectStore(Node, 3, AArch64::ST1Threev2d);
6531 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6532 SelectStore(Node, 3, AArch64::ST1Threev1d);
6537 case Intrinsic::aarch64_neon_st1x4: {
6538 if (VT == MVT::v8i8) {
6539 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6541 }
else if (VT == MVT::v16i8) {
6542 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6544 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6545 VT == MVT::v4bf16) {
6546 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6548 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6549 VT == MVT::v8bf16) {
6550 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6552 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6553 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6555 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6556 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6558 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6559 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6561 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6562 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6567 case Intrinsic::aarch64_neon_st2: {
6568 if (VT == MVT::v8i8) {
6569 SelectStore(Node, 2, AArch64::ST2Twov8b);
6571 }
else if (VT == MVT::v16i8) {
6572 SelectStore(Node, 2, AArch64::ST2Twov16b);
6574 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6575 VT == MVT::v4bf16) {
6576 SelectStore(Node, 2, AArch64::ST2Twov4h);
6578 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6579 VT == MVT::v8bf16) {
6580 SelectStore(Node, 2, AArch64::ST2Twov8h);
6582 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6583 SelectStore(Node, 2, AArch64::ST2Twov2s);
6585 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6586 SelectStore(Node, 2, AArch64::ST2Twov4s);
6588 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6589 SelectStore(Node, 2, AArch64::ST2Twov2d);
6591 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6592 SelectStore(Node, 2, AArch64::ST1Twov1d);
6597 case Intrinsic::aarch64_neon_st3: {
6598 if (VT == MVT::v8i8) {
6599 SelectStore(Node, 3, AArch64::ST3Threev8b);
6601 }
else if (VT == MVT::v16i8) {
6602 SelectStore(Node, 3, AArch64::ST3Threev16b);
6604 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6605 VT == MVT::v4bf16) {
6606 SelectStore(Node, 3, AArch64::ST3Threev4h);
6608 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6609 VT == MVT::v8bf16) {
6610 SelectStore(Node, 3, AArch64::ST3Threev8h);
6612 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6613 SelectStore(Node, 3, AArch64::ST3Threev2s);
6615 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6616 SelectStore(Node, 3, AArch64::ST3Threev4s);
6618 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6619 SelectStore(Node, 3, AArch64::ST3Threev2d);
6621 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6622 SelectStore(Node, 3, AArch64::ST1Threev1d);
6627 case Intrinsic::aarch64_neon_st4: {
6628 if (VT == MVT::v8i8) {
6629 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6631 }
else if (VT == MVT::v16i8) {
6632 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6634 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6635 VT == MVT::v4bf16) {
6636 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6638 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6639 VT == MVT::v8bf16) {
6640 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6642 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6643 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6645 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6646 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6648 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6649 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6651 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6652 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6657 case Intrinsic::aarch64_neon_st2lane: {
6658 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6659 SelectStoreLane(Node, 2, AArch64::ST2i8);
6661 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6662 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6663 SelectStoreLane(Node, 2, AArch64::ST2i16);
6665 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6667 SelectStoreLane(Node, 2, AArch64::ST2i32);
6669 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6671 SelectStoreLane(Node, 2, AArch64::ST2i64);
6676 case Intrinsic::aarch64_neon_st3lane: {
6677 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6678 SelectStoreLane(Node, 3, AArch64::ST3i8);
6680 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6681 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6682 SelectStoreLane(Node, 3, AArch64::ST3i16);
6684 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6686 SelectStoreLane(Node, 3, AArch64::ST3i32);
6688 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6690 SelectStoreLane(Node, 3, AArch64::ST3i64);
6695 case Intrinsic::aarch64_neon_st4lane: {
6696 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6697 SelectStoreLane(Node, 4, AArch64::ST4i8);
6699 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6700 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6701 SelectStoreLane(Node, 4, AArch64::ST4i16);
6703 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6705 SelectStoreLane(Node, 4, AArch64::ST4i32);
6707 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6709 SelectStoreLane(Node, 4, AArch64::ST4i64);
6714 case Intrinsic::aarch64_sve_st2q: {
6715 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6718 case Intrinsic::aarch64_sve_st3q: {
6719 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6722 case Intrinsic::aarch64_sve_st4q: {
6723 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6726 case Intrinsic::aarch64_sve_st2: {
6727 if (VT == MVT::nxv16i8) {
6728 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6730 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6731 VT == MVT::nxv8bf16) {
6732 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6734 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6735 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6737 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6738 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6743 case Intrinsic::aarch64_sve_st3: {
6744 if (VT == MVT::nxv16i8) {
6745 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6747 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6748 VT == MVT::nxv8bf16) {
6749 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6751 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6752 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6754 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6755 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6760 case Intrinsic::aarch64_sve_st4: {
6761 if (VT == MVT::nxv16i8) {
6762 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6764 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6765 VT == MVT::nxv8bf16) {
6766 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6768 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6769 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6771 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6772 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6780 case AArch64ISD::LD2post: {
6781 if (VT == MVT::v8i8) {
6782 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6784 }
else if (VT == MVT::v16i8) {
6785 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6787 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6788 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6790 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6791 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6793 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6794 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6796 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6797 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6799 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6800 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6802 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6803 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6808 case AArch64ISD::LD3post: {
6809 if (VT == MVT::v8i8) {
6810 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6812 }
else if (VT == MVT::v16i8) {
6813 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6815 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6816 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6818 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6819 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6821 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6822 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6824 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6825 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6827 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6828 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6830 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6831 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6836 case AArch64ISD::LD4post: {
6837 if (VT == MVT::v8i8) {
6838 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6840 }
else if (VT == MVT::v16i8) {
6841 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6843 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6844 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6846 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6847 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6849 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6850 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6852 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6853 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6855 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6856 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6858 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6859 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6864 case AArch64ISD::LD1x2post: {
6865 if (VT == MVT::v8i8) {
6866 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6868 }
else if (VT == MVT::v16i8) {
6869 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6871 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6872 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6874 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6875 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6877 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6878 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6880 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6881 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6883 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6884 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6886 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6887 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6892 case AArch64ISD::LD1x3post: {
6893 if (VT == MVT::v8i8) {
6894 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6896 }
else if (VT == MVT::v16i8) {
6897 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6899 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6900 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6902 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6903 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6905 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6906 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6908 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6909 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6911 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6912 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6914 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6915 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6920 case AArch64ISD::LD1x4post: {
6921 if (VT == MVT::v8i8) {
6922 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6924 }
else if (VT == MVT::v16i8) {
6925 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6927 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6928 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6930 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6931 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6933 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6934 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6936 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6937 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6939 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6940 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6942 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6943 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6948 case AArch64ISD::LD1DUPpost: {
6949 if (VT == MVT::v8i8) {
6950 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6952 }
else if (VT == MVT::v16i8) {
6953 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6955 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6956 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6958 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6959 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6961 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6962 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6964 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6965 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6967 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6968 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6970 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6971 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6976 case AArch64ISD::LD2DUPpost: {
6977 if (VT == MVT::v8i8) {
6978 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6980 }
else if (VT == MVT::v16i8) {
6981 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6983 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6984 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6986 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6987 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6989 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6990 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6992 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6993 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6995 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6996 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6998 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6999 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7004 case AArch64ISD::LD3DUPpost: {
7005 if (VT == MVT::v8i8) {
7006 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7008 }
else if (VT == MVT::v16i8) {
7009 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7011 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7012 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7014 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7015 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7017 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7018 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7020 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7021 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7023 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7024 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7026 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7027 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7032 case AArch64ISD::LD4DUPpost: {
7033 if (VT == MVT::v8i8) {
7034 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7036 }
else if (VT == MVT::v16i8) {
7037 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7039 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7040 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7042 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7043 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7045 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7046 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7048 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7049 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7051 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7052 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7054 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7055 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7060 case AArch64ISD::LD1LANEpost: {
7061 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7062 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7064 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7065 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7066 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7068 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7070 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7072 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7074 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7079 case AArch64ISD::LD2LANEpost: {
7080 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7081 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7083 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7084 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7085 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7087 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7089 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7091 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7093 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7098 case AArch64ISD::LD3LANEpost: {
7099 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7100 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7102 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7103 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7104 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7106 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7108 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7110 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7112 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7117 case AArch64ISD::LD4LANEpost: {
7118 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7119 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7121 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7122 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7123 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7125 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7127 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7129 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7131 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7136 case AArch64ISD::ST2post: {
7137 VT =
Node->getOperand(1).getValueType();
7138 if (VT == MVT::v8i8) {
7139 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7141 }
else if (VT == MVT::v16i8) {
7142 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7144 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7145 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7147 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7148 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7150 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7151 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7153 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7154 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7156 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7157 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7159 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7160 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7165 case AArch64ISD::ST3post: {
7166 VT =
Node->getOperand(1).getValueType();
7167 if (VT == MVT::v8i8) {
7168 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7170 }
else if (VT == MVT::v16i8) {
7171 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7173 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7174 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7176 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7177 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7179 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7180 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7182 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7183 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7185 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7186 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7188 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7189 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7194 case AArch64ISD::ST4post: {
7195 VT =
Node->getOperand(1).getValueType();
7196 if (VT == MVT::v8i8) {
7197 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7199 }
else if (VT == MVT::v16i8) {
7200 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7202 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7203 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7205 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7206 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7208 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7209 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7211 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7212 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7214 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7215 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7217 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7218 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7223 case AArch64ISD::ST1x2post: {
7224 VT =
Node->getOperand(1).getValueType();
7225 if (VT == MVT::v8i8) {
7226 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7228 }
else if (VT == MVT::v16i8) {
7229 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7231 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7232 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7234 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7235 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7237 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7238 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7240 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7241 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7243 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7244 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7246 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7247 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7252 case AArch64ISD::ST1x3post: {
7253 VT =
Node->getOperand(1).getValueType();
7254 if (VT == MVT::v8i8) {
7255 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7257 }
else if (VT == MVT::v16i8) {
7258 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7260 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7261 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7263 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7264 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7266 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7267 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7269 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7270 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7272 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7273 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7275 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7276 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7281 case AArch64ISD::ST1x4post: {
7282 VT =
Node->getOperand(1).getValueType();
7283 if (VT == MVT::v8i8) {
7284 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7286 }
else if (VT == MVT::v16i8) {
7287 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7289 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7290 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7292 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7293 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7295 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7296 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7298 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7299 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7301 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7302 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7304 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7305 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7310 case AArch64ISD::ST2LANEpost: {
7311 VT =
Node->getOperand(1).getValueType();
7312 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7313 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7315 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7316 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7317 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7319 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7321 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7323 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7325 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7330 case AArch64ISD::ST3LANEpost: {
7331 VT =
Node->getOperand(1).getValueType();
7332 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7333 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7335 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7336 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7337 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7339 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7341 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7343 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7345 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7350 case AArch64ISD::ST4LANEpost: {
7351 VT =
Node->getOperand(1).getValueType();
7352 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7353 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7355 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7356 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7357 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7359 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7361 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7363 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7365 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7380 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7392 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7396 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7397 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7412 return MemIntr->getMemoryVT();
7419 DataVT = Load->getValueType(0);
7421 DataVT = Load->getValueType(0);
7423 DataVT = Store->getValue().getValueType();
7425 DataVT = Store->getValue().getValueType();
7432 const unsigned Opcode = Root->
getOpcode();
7436 case AArch64ISD::LD1_MERGE_ZERO:
7437 case AArch64ISD::LD1S_MERGE_ZERO:
7438 case AArch64ISD::LDNF1_MERGE_ZERO:
7439 case AArch64ISD::LDNF1S_MERGE_ZERO:
7441 case AArch64ISD::ST1_PRED:
7453 case Intrinsic::aarch64_sme_ldr:
7454 case Intrinsic::aarch64_sme_str:
7455 return MVT::nxv16i8;
7456 case Intrinsic::aarch64_sve_prf:
7461 case Intrinsic::aarch64_sve_ld2_sret:
7462 case Intrinsic::aarch64_sve_ld2q_sret:
7465 case Intrinsic::aarch64_sve_st2q:
7468 case Intrinsic::aarch64_sve_ld3_sret:
7469 case Intrinsic::aarch64_sve_ld3q_sret:
7472 case Intrinsic::aarch64_sve_st3q:
7475 case Intrinsic::aarch64_sve_ld4_sret:
7476 case Intrinsic::aarch64_sve_ld4q_sret:
7479 case Intrinsic::aarch64_sve_st4q:
7482 case Intrinsic::aarch64_sve_ld1udq:
7483 case Intrinsic::aarch64_sve_st1dq:
7484 return EVT(MVT::nxv1i64);
7485 case Intrinsic::aarch64_sve_ld1uwq:
7486 case Intrinsic::aarch64_sve_st1wq:
7487 return EVT(MVT::nxv1i32);
7494template <
int64_t Min,
int64_t Max>
7495bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7499 const DataLayout &
DL = CurDAG->getDataLayout();
7500 const MachineFrameInfo &MFI = MF->getFrameInfo();
7508 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7522 int64_t MulImm = std::numeric_limits<int64_t>::max();
7523 if (VScale.
getOpcode() == ISD::VSCALE) {
7526 int64_t ByteOffset =
C->getSExtValue();
7527 const auto KnownVScale =
7530 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7533 MulImm = ByteOffset / KnownVScale;
7540 if ((MulImm % MemWidthBytes) != 0)
7543 int64_t
Offset = MulImm / MemWidthBytes;
7547 Base =
N.getOperand(0);
7556 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7562bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7581 int64_t ImmOff =
C->getSExtValue();
7582 unsigned Size = 1 << Scale;
7591 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7593 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7604 if (
C->getZExtValue() == Scale) {
7613bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7614 const AArch64TargetLowering *TLI =
7615 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7620bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7621 EVT VT =
N.getValueType();
7625bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7630 int64_t ImmOff =
C->getSExtValue();
7631 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7632 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7637 if (
SDValue C = MatchConstantOffset(
N)) {
7638 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7644 if (CurDAG->isBaseWithConstantOffset(
N)) {
7645 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7646 Base =
N.getOperand(0);
7654 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7658bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7678 uint64_t LowerBound = 0, UpperBound = 64;
7696 if (CN->getAPIntValue().uge(LowerBound) &&
7697 CN->getAPIntValue().ult(UpperBound)) {
7699 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7707template <
bool MatchCBB>
7714 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7716 Reg =
N.getOperand(0);
7718 SDLoc(
N), MVT::i32);
7726 Reg =
N.getOperand(0);
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 bool isMemOpOrPrefetch(SDNode *N)
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 SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const AArch64RegisterInfo * getRegisterInfo() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
static constexpr roundingMode rmTowardZero
LLVM_ABI bool getExactInverse(APFloat *Inv) const
If this value is normal and has an exact, normal, multiplicative inverse, store it in inv and return ...
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.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
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
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t &Encoding)
processLogicalImmediate - Determine if an immediate value can be encoded as the immediate operand of ...
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static 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.
@ ADD
Simple integer binary arithmetic operators.
@ 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...
@ SIGN_EXTEND
Conversion operators.
@ 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.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
@ Undef
Value of the register doesn't matter.
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
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.
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
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.