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;
69 std::vector<SDValue> &OutOps)
override;
71 template <
signed Low,
signed High,
signed Scale>
79 return SelectShiftedRegister(
N,
false, Reg, Shift);
82 return SelectShiftedRegister(
N,
true, Reg, Shift);
85 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
88 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
91 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
94 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
97 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
100 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
103 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
106 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
109 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
112 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
115 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
118 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
121 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
124 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
127 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
130 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
133 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
135 template <
unsigned Size,
unsigned Max>
139 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
141 if (
auto *CI = dyn_cast<ConstantSDNode>(OffImm)) {
142 int64_t
C = CI->getSExtValue();
150 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
157 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
163 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
168 N =
N->getOperand(0);
170 !isa<ConstantSDNode>(
N->getOperand(1)))
172 EVT VT =
N->getValueType(0);
173 EVT LVT =
N->getOperand(0).getValueType();
174 unsigned Index =
N->getConstantOperandVal(1);
178 Res =
N->getOperand(0);
186 EVT VT =
Op.getValueType();
187 unsigned ShtAmt =
N->getConstantOperandVal(1);
194 Op.getOperand(1).getConstantOperandVal(0)
195 <<
Op.getOperand(1).getConstantOperandVal(1));
197 isa<ConstantSDNode>(
Op.getOperand(1).getOperand(0)))
199 Op.getOperand(1).getConstantOperandVal(0));
203 if (Imm != 1ULL << (ShtAmt - 1))
206 Res1 =
Op.getOperand(0);
207 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
211 bool SelectDupZeroOrUndef(
SDValue N) {
212 switch(
N->getOpcode()) {
217 auto Opnd0 =
N->getOperand(0);
232 switch(
N->getOpcode()) {
235 auto Opnd0 =
N->getOperand(0);
247 template<MVT::SimpleValueType VT>
249 return SelectSVEAddSubImm(
N, VT, Imm, Shift);
252 template <MVT::SimpleValueType VT,
bool Negate>
254 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
257 template <MVT::SimpleValueType VT>
259 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
262 template <MVT::SimpleValueType VT,
bool Invert = false>
264 return SelectSVELogicalImm(
N, VT, Imm, Invert);
267 template <MVT::SimpleValueType VT>
269 return SelectSVEArithImm(
N, VT, Imm);
272 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
274 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
281 EVT EltVT =
N->getValueType(0).getVectorElementType();
282 return SelectSVEShiftImm(
N->getOperand(0), 1,
288 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
290 if (!isa<ConstantSDNode>(
N))
293 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
295 MulImm = 1LL << MulImm;
297 if ((MulImm % std::abs(Scale)) != 0)
301 if ((MulImm >= Min) && (MulImm <= Max)) {
302 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
309 template <
signed Max,
signed Scale>
311 if (!isa<ConstantSDNode>(
N))
314 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
316 if (MulImm >= 0 && MulImm <= Max) {
318 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
325 template <
unsigned BaseReg,
unsigned Max>
327 if (
auto *CI = dyn_cast<ConstantSDNode>(
N)) {
333 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
356 const unsigned SubRegs[]);
358 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
360 bool tryIndexedLoad(
SDNode *
N);
362 void SelectPtrauthAuth(
SDNode *
N);
363 void SelectPtrauthResign(
SDNode *
N);
365 bool trySelectStackSlotTagP(
SDNode *
N);
368 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
370 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
372 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
373 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
374 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
375 unsigned Opc_rr,
unsigned Opc_ri,
376 bool IsIntr =
false);
377 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
378 unsigned Scale,
unsigned Opc_ri,
380 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
381 bool IsZmMulti,
unsigned Opcode,
382 bool HasPred =
false);
383 void SelectPExtPair(
SDNode *
N,
unsigned Opc);
384 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
385 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
386 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
387 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
388 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
389 bool IsTupleInput,
unsigned Opc);
390 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 template <
unsigned MaxIdx,
unsigned Scale>
393 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
395 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
396 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
397 unsigned BaseReg = 0);
400 template <
int64_t Min,
int64_t Max>
404 template <
unsigned Scale>
406 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
409 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
412 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
414 template <
unsigned MaxIdx,
unsigned Scale>
419 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
420 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
421 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
422 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
423 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
424 unsigned Opc_rr,
unsigned Opc_ri);
425 std::tuple<unsigned, SDValue, SDValue>
426 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
430 bool tryBitfieldExtractOp(
SDNode *
N);
431 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
432 bool tryBitfieldInsertOp(
SDNode *
N);
433 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
434 bool tryShiftAmountMod(
SDNode *
N);
436 bool tryReadRegister(
SDNode *
N);
437 bool tryWriteRegister(
SDNode *
N);
439 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
440 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
445#include "AArch64GenDAGISel.inc"
453 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
455 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
468 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
469 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
470 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
473 template<
unsigned RegW
idth>
475 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
478 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
480 template<
unsigned RegW
idth>
482 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
488 bool SelectCMP_SWAP(
SDNode *
N);
498 bool AllowSaturation,
SDValue &Imm);
506 bool SelectAllActivePredicate(
SDValue N);
516 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
520char AArch64DAGToDAGISelLegacy::ID = 0;
528 Imm =
C->getZExtValue();
545 return N->getOpcode() == Opc &&
556 return Imm == ImmExpected;
560bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
562 std::vector<SDValue> &OutOps) {
563 switch(ConstraintID) {
566 case InlineAsm::ConstraintCode::m:
567 case InlineAsm::ConstraintCode::o:
568 case InlineAsm::ConstraintCode::Q:
574 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
576 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
577 dl,
Op.getValueType(),
579 OutOps.push_back(NewOp);
595 if (!isa<ConstantSDNode>(
N.getNode()))
598 uint64_t Immed =
N.getNode()->getAsZExtVal();
601 if (Immed >> 12 == 0) {
603 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
611 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
612 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
625 if (!isa<ConstantSDNode>(
N.getNode()))
629 uint64_t Immed =
N.getNode()->getAsZExtVal();
637 if (
N.getValueType() == MVT::i32)
640 Immed = ~Immed + 1ULL;
641 if (Immed & 0xFFFFFFFFFF000000ULL)
644 Immed &= 0xFFFFFFULL;
645 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(
N), MVT::i32), Val,
652 switch (
N.getOpcode()) {
671 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
674 unsigned ShiftVal = CSD->getZExtValue();
683 if (!isa<MemSDNode>(*UI))
685 if (!isa<MemSDNode>(*UII))
692bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
695 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
700 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
722bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(
SDValue N,
SDValue &Reg,
724 EVT VT =
N.getValueType();
725 if (VT != MVT::i32 && VT != MVT::i64)
728 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
734 unsigned LHSOpcode =
LHS->getOpcode();
748 unsigned LowZBits, MaskLen;
752 unsigned BitWidth =
N.getValueSizeInBits();
759 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
762 NewShiftC = LowZBits - ShiftAmtC;
763 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
769 NewShiftC = LowZBits + ShiftAmtC;
782 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
784 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
788 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
790 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
791 NewShiftAmt, BitWidthMinus1),
794 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
806 SrcVT = cast<VTSDNode>(
N.getOperand(1))->getVT();
808 SrcVT =
N.getOperand(0).getValueType();
810 if (!IsLoadStore && SrcVT == MVT::i8)
812 else if (!IsLoadStore && SrcVT == MVT::i16)
814 else if (SrcVT == MVT::i32)
816 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
821 EVT SrcVT =
N.getOperand(0).getValueType();
822 if (!IsLoadStore && SrcVT == MVT::i8)
824 else if (!IsLoadStore && SrcVT == MVT::i16)
826 else if (SrcVT == MVT::i32)
828 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
856bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
859 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
864 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
865 V.getConstantOperandVal(1) <= 4 &&
878bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
880 if (SelectShiftedRegisterFromAnd(
N, Reg, Shift))
890 unsigned BitSize =
N.getValueSizeInBits();
891 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
894 Reg =
N.getOperand(0);
895 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(
N), MVT::i32);
896 return isWorthFoldingALU(
N,
true);
907 if (
N.getValueType() == MVT::i32)
915template<
signed Low,
signed High,
signed Scale>
917 if (!isa<ConstantSDNode>(
N))
920 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
921 if ((MulImm % std::abs(Scale)) == 0) {
922 int64_t RDVLImm = MulImm / Scale;
923 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
924 Imm = CurDAG->getSignedTargetConstant(RDVLImm,
SDLoc(
N), MVT::i32);
934bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
936 unsigned ShiftVal = 0;
951 Reg =
N.getOperand(0).getOperand(0);
957 Reg =
N.getOperand(0);
962 unsigned Opc =
N.getOpcode();
963 return Opc !=
ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG &&
980 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
982 return isWorthFoldingALU(
N);
987bool AArch64DAGToDAGISel::SelectArithUXTXRegister(
SDValue N,
SDValue &Reg,
989 unsigned ShiftVal = 0;
1003 Reg =
N.getOperand(0);
1004 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
1006 return isWorthFoldingALU(
N);
1015 for (
auto *
User :
N->users()) {
1042bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1043 unsigned BW,
unsigned Size,
1050 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1052 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1058 if (CurDAG->isBaseWithConstantOffset(
N)) {
1059 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1061 int64_t RHSC =
RHS->getSExtValue();
1063 int64_t
Range = 0x1LL << (BW - 1);
1065 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1066 RHSC < (
Range << Scale)) {
1067 Base =
N.getOperand(0);
1069 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1072 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1081 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1082 Base =
N.getOperand(0);
1084 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1087 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1098 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1105bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1111 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1113 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1119 dyn_cast<GlobalAddressSDNode>(
N.getOperand(1).getNode());
1120 Base =
N.getOperand(0);
1121 OffImm =
N.getOperand(1);
1130 if (CurDAG->isBaseWithConstantOffset(
N)) {
1131 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1132 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1135 Base =
N.getOperand(0);
1137 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1140 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1148 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1156 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1165bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1168 if (!CurDAG->isBaseWithConstantOffset(
N))
1170 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1171 int64_t RHSC =
RHS->getSExtValue();
1172 if (RHSC >= -256 && RHSC < 256) {
1173 Base =
N.getOperand(0);
1175 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1177 Base = CurDAG->getTargetFrameIndex(
1180 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(
N), MVT::i64);
1190 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1197bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1217 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1223 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1226 return isWorthFoldingAddr(
N,
Size);
1229bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1241 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1249 if (!isa<MemSDNode>(*UI))
1254 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1257 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1258 SelectExtendedSHL(RHS,
Size,
true,
Offset, SignExtend)) {
1260 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1265 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1266 SelectExtendedSHL(LHS,
Size,
true,
Offset, SignExtend)) {
1268 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1273 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1277 if (IsExtendedRegisterWorthFolding &&
1284 if (isWorthFoldingAddr(LHS,
Size))
1289 if (IsExtendedRegisterWorthFolding &&
1296 if (isWorthFoldingAddr(RHS,
Size))
1308 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1311 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1313 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1314 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1318bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1333 if (!isa<MemSDNode>(*UI))
1348 if (isa<ConstantSDNode>(RHS)) {
1349 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1359 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
1362 N = CurDAG->getNode(
ISD::ADD,
DL, MVT::i64, LHS, MOVIV);
1366 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1369 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1370 SelectExtendedSHL(RHS,
Size,
false,
Offset, SignExtend)) {
1372 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1377 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1378 SelectExtendedSHL(LHS,
Size,
false,
Offset, SignExtend)) {
1380 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1387 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1388 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1394 static const unsigned RegClassIDs[] = {
1395 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1396 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1397 AArch64::dsub2, AArch64::dsub3};
1403 static const unsigned RegClassIDs[] = {
1404 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1405 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1406 AArch64::qsub2, AArch64::qsub3};
1412 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1413 AArch64::ZPR3RegClassID,
1414 AArch64::ZPR4RegClassID};
1415 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1416 AArch64::zsub2, AArch64::zsub3};
1426 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1427 AArch64::ZPR4Mul4RegClassID};
1428 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1429 AArch64::zsub2, AArch64::zsub3};
1434 const unsigned RegClassIDs[],
1435 const unsigned SubRegs[]) {
1438 if (Regs.
size() == 1)
1449 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1452 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1454 Ops.
push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1458 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped, Ops);
1462void AArch64DAGToDAGISel::SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1465 EVT VT =
N->getValueType(0);
1467 unsigned ExtOff = isExt;
1470 unsigned Vec0Off = ExtOff + 1;
1472 N->op_begin() + Vec0Off + NumVecs);
1479 Ops.
push_back(
N->getOperand(NumVecs + ExtOff + 1));
1480 ReplaceNode(
N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
1483static std::tuple<SDValue, SDValue>
1503 auto *ConstDiscN = dyn_cast<ConstantSDNode>(ConstDisc);
1504 if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue()))
1509 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1511 return std::make_tuple(
1516void AArch64DAGToDAGISel::SelectPtrauthAuth(
SDNode *
N) {
1521 SDValue AUTDisc =
N->getOperand(3);
1523 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1524 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1526 SDValue AUTAddrDisc, AUTConstDisc;
1527 std::tie(AUTConstDisc, AUTAddrDisc) =
1530 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1531 AArch64::X16, Val,
SDValue());
1532 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1534 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUT,
DL, MVT::i64, Ops);
1535 ReplaceNode(
N, AUT);
1538void AArch64DAGToDAGISel::SelectPtrauthResign(
SDNode *
N) {
1543 SDValue AUTDisc =
N->getOperand(3);
1545 SDValue PACDisc =
N->getOperand(5);
1547 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1548 unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
1550 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1551 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1553 SDValue AUTAddrDisc, AUTConstDisc;
1554 std::tie(AUTConstDisc, AUTAddrDisc) =
1557 SDValue PACAddrDisc, PACConstDisc;
1558 std::tie(PACConstDisc, PACAddrDisc) =
1561 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1562 AArch64::X16, Val,
SDValue());
1564 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1565 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1567 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64, Ops);
1568 ReplaceNode(
N, AUTPAC);
1571bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
1573 if (
LD->isUnindexed())
1575 EVT VT =
LD->getMemoryVT();
1576 EVT DstVT =
N->getValueType(0);
1583 unsigned Opcode = 0;
1586 bool InsertTo64 =
false;
1588 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1589 else if (VT == MVT::i32) {
1591 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1593 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1595 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1601 }
else if (VT == MVT::i16) {
1603 if (DstVT == MVT::i64)
1604 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1606 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1608 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1609 InsertTo64 = DstVT == MVT::i64;
1614 }
else if (VT == MVT::i8) {
1616 if (DstVT == MVT::i64)
1617 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1619 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1621 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1622 InsertTo64 = DstVT == MVT::i64;
1627 }
else if (VT == MVT::f16) {
1628 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1629 }
else if (VT == MVT::bf16) {
1630 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1631 }
else if (VT == MVT::f32) {
1632 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1634 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1636 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1644 SDValue Offset = CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1646 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1651 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {
MemOp});
1656 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1658 SDValue(CurDAG->getMachineNode(
1659 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1660 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1665 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1668 CurDAG->RemoveDeadNode(
N);
1672void AArch64DAGToDAGISel::SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1673 unsigned SubRegIdx) {
1675 EVT VT =
N->getValueType(0);
1681 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1683 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1685 for (
unsigned i = 0; i < NumVecs; ++i)
1687 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1693 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(
N)) {
1695 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
1698 CurDAG->RemoveDeadNode(
N);
1701void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
1702 unsigned Opc,
unsigned SubRegIdx) {
1704 EVT VT =
N->getValueType(0);
1711 const EVT ResTys[] = {MVT::i64,
1712 MVT::Untyped, MVT::Other};
1714 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1722 ReplaceUses(
SDValue(
N, 0), SuperReg);
1724 for (
unsigned i = 0; i < NumVecs; ++i)
1726 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1730 CurDAG->RemoveDeadNode(
N);
1736std::tuple<unsigned, SDValue, SDValue>
1737AArch64DAGToDAGISel::findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
1743 SDValue NewOffset = OldOffset;
1745 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1746 N, OldBase, NewBase, NewOffset);
1750 const bool IsRegReg =
1751 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1754 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1767template <SelectTypeKind Kind>
1779 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1784 if (EltVT != MVT::i1)
1788 if (EltVT == MVT::bf16)
1790 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1820void AArch64DAGToDAGISel::SelectPExtPair(
SDNode *
N,
unsigned Opc) {
1823 if (
Imm->getZExtValue() > 1)
1827 EVT VT =
N->getValueType(0);
1828 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1829 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1832 for (
unsigned I = 0;
I < 2; ++
I)
1833 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1834 AArch64::psub0 +
I,
DL, VT, SuperReg));
1836 CurDAG->RemoveDeadNode(
N);
1839void AArch64DAGToDAGISel::SelectWhilePair(
SDNode *
N,
unsigned Opc) {
1841 EVT VT =
N->getValueType(0);
1843 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1845 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1848 for (
unsigned I = 0;
I < 2; ++
I)
1849 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1850 AArch64::psub0 +
I,
DL, VT, SuperReg));
1852 CurDAG->RemoveDeadNode(
N);
1855void AArch64DAGToDAGISel::SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
1857 EVT VT =
N->getValueType(0);
1859 SDValue Ops = createZTuple(Regs);
1863 for (
unsigned i = 0; i < NumVecs; ++i)
1864 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1865 AArch64::zsub0 + i,
DL, VT, SuperReg));
1867 CurDAG->RemoveDeadNode(
N);
1870void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
1873 EVT VT =
N->getValueType(0);
1875 Ops.push_back(
N->getOperand(0));
1878 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other}, Ops);
1881 for (
unsigned i = 0; i < NumVecs; ++i)
1882 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1883 AArch64::zsub0 + i,
DL, VT, SuperReg));
1886 unsigned ChainIdx = NumVecs;
1888 CurDAG->RemoveDeadNode(
N);
1891void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(
SDNode *
N,
1896 assert(Opcode != 0 &&
"Unexpected opcode");
1899 EVT VT =
N->getValueType(0);
1900 unsigned FirstVecIdx = HasPred ? 2 : 1;
1902 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1904 return createZMulTuple(Regs);
1907 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1911 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1913 Zm =
N->getOperand(NumVecs + FirstVecIdx);
1917 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1918 N->getOperand(1), Zdn, Zm);
1920 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
1922 for (
unsigned i = 0; i < NumVecs; ++i)
1923 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1924 AArch64::zsub0 + i,
DL, VT, SuperReg));
1926 CurDAG->RemoveDeadNode(
N);
1929void AArch64DAGToDAGISel::SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
1930 unsigned Scale,
unsigned Opc_ri,
1931 unsigned Opc_rr,
bool IsIntr) {
1932 assert(Scale < 5 &&
"Invalid scaling value.");
1934 EVT VT =
N->getValueType(0);
1940 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
1941 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
1942 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
1944 SDValue Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
1948 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1950 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1952 for (
unsigned i = 0; i < NumVecs; ++i)
1953 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1954 AArch64::zsub0 + i,
DL, VT, SuperReg));
1957 unsigned ChainIdx = NumVecs;
1959 CurDAG->RemoveDeadNode(
N);
1962void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(
SDNode *
N,
1967 assert(Scale < 4 &&
"Invalid scaling value.");
1969 EVT VT =
N->getValueType(0);
1977 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
1983 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1985 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1987 for (
unsigned i = 0; i < NumVecs; ++i)
1988 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1989 AArch64::zsub0 + i,
DL, VT, SuperReg));
1992 unsigned ChainIdx = NumVecs;
1994 CurDAG->RemoveDeadNode(
N);
1997void AArch64DAGToDAGISel::SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
1999 if (
N->getValueType(0) != MVT::nxv4f32)
2001 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2004void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(
SDNode *
Node,
2005 unsigned NumOutVecs,
2009 if (
Imm->getZExtValue() > MaxImm)
2013 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2018 EVT VT =
Node->getValueType(0);
2021 CurDAG->getMachineNode(Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2024 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2025 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2026 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2029 unsigned ChainIdx = NumOutVecs;
2031 CurDAG->RemoveDeadNode(
Node);
2034void AArch64DAGToDAGISel::SelectMultiVectorLuti(
SDNode *
Node,
2035 unsigned NumOutVecs,
2040 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2046 EVT VT =
Node->getValueType(0);
2049 CurDAG->getMachineNode(Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2052 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2053 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2054 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2057 unsigned ChainIdx = NumOutVecs;
2059 CurDAG->RemoveDeadNode(
Node);
2062void AArch64DAGToDAGISel::SelectClamp(
SDNode *
N,
unsigned NumVecs,
2065 EVT VT =
N->getValueType(0);
2068 SDValue Zd = createZMulTuple(Regs);
2069 SDValue Zn =
N->getOperand(1 + NumVecs);
2070 SDValue Zm =
N->getOperand(2 + NumVecs);
2076 for (
unsigned i = 0; i < NumVecs; ++i)
2077 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2078 AArch64::zsub0 + i,
DL, VT, SuperReg));
2080 CurDAG->RemoveDeadNode(
N);
2110template <
unsigned MaxIdx,
unsigned Scale>
2111void AArch64DAGToDAGISel::SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
2112 unsigned BaseReg,
unsigned Op) {
2113 unsigned TileNum = 0;
2114 if (BaseReg != AArch64::ZA)
2115 TileNum =
N->getConstantOperandVal(2);
2121 if (BaseReg == AArch64::ZA)
2122 SliceBase =
N->getOperand(2);
2124 SliceBase =
N->getOperand(3);
2126 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2132 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2134 EVT VT =
N->getValueType(0);
2135 for (
unsigned I = 0;
I < NumVecs; ++
I)
2137 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2140 unsigned ChainIdx = NumVecs;
2142 CurDAG->RemoveDeadNode(
N);
2145void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
2146 unsigned Op,
unsigned MaxIdx,
2147 unsigned Scale,
unsigned BaseReg) {
2151 SDValue SliceBase =
N->getOperand(2);
2152 if (BaseReg != AArch64::ZA)
2153 SliceBase =
N->getOperand(3);
2156 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2163 if (BaseReg != AArch64::ZA )
2168 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2170 EVT VT =
N->getValueType(0);
2171 for (
unsigned I = 0;
I < NumVecs; ++
I)
2173 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2177 unsigned ChainIdx = NumVecs;
2179 CurDAG->RemoveDeadNode(
N);
2182void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(
SDNode *
N,
2183 unsigned NumOutVecs,
2187 EVT VT =
N->getValueType(0);
2188 unsigned NumInVecs =
N->getNumOperands() - 1;
2192 assert((NumInVecs == 2 || NumInVecs == 4) &&
2193 "Don't know how to handle multi-register input!");
2198 for (
unsigned I = 0;
I < NumInVecs;
I++)
2202 SDNode *Res = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
2205 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2206 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2207 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2208 CurDAG->RemoveDeadNode(
N);
2211void AArch64DAGToDAGISel::SelectStore(
SDNode *
N,
unsigned NumVecs,
2214 EVT VT =
N->getOperand(2)->getValueType(0);
2221 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
N->getOperand(0)};
2222 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2226 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2231void AArch64DAGToDAGISel::SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
2232 unsigned Scale,
unsigned Opc_rr,
2238 SDValue RegSeq = createZTuple(Regs);
2243 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
2244 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2245 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2247 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
2251 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2263 if (
auto FINode = dyn_cast<FrameIndexSDNode>(
N)) {
2264 int FI = FINode->getIndex();
2266 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2273void AArch64DAGToDAGISel::SelectPostStore(
SDNode *
N,
unsigned NumVecs,
2276 EVT VT =
N->getOperand(2)->getValueType(0);
2277 const EVT ResTys[] = {MVT::i64,
2286 N->getOperand(NumVecs + 1),
2287 N->getOperand(NumVecs + 2),
2289 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2329void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
2332 EVT VT =
N->getValueType(0);
2340 WidenVector(*CurDAG));
2344 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2346 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2348 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2349 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2350 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2354 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2355 AArch64::qsub2, AArch64::qsub3 };
2356 for (
unsigned i = 0; i < NumVecs; ++i) {
2357 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2364 CurDAG->RemoveDeadNode(
N);
2367void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
2370 EVT VT =
N->getValueType(0);
2378 WidenVector(*CurDAG));
2382 const EVT ResTys[] = {MVT::i64,
2385 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2388 CurDAG->getTargetConstant(LaneNo, dl,
2390 N->getOperand(NumVecs + 2),
2391 N->getOperand(NumVecs + 3),
2393 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2405 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2406 AArch64::qsub2, AArch64::qsub3 };
2407 for (
unsigned i = 0; i < NumVecs; ++i) {
2408 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2418 CurDAG->RemoveDeadNode(
N);
2421void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
2424 EVT VT =
N->getOperand(2)->getValueType(0);
2432 WidenVector(*CurDAG));
2436 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2438 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2439 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2440 SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
2444 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2449void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
2452 EVT VT =
N->getOperand(2)->getValueType(0);
2460 WidenVector(*CurDAG));
2464 const EVT ResTys[] = {MVT::i64,
2467 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2469 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2470 N->getOperand(NumVecs + 2),
2471 N->getOperand(NumVecs + 3),
2473 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2477 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2484 unsigned &LSB,
unsigned &MSB,
2485 unsigned NumberOfIgnoredLowBits,
2486 bool BiggerPattern) {
2488 "N must be a AND operation to call this function");
2490 EVT VT =
N->getValueType(0);
2495 assert((VT == MVT::i32 || VT == MVT::i64) &&
2496 "Type checking must have been done before calling this function");
2510 const SDNode *Op0 =
N->getOperand(0).getNode();
2514 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
2517 if (AndImm & (AndImm + 1))
2520 bool ClampMSB =
false;
2540 ClampMSB = (VT == MVT::i32);
2541 }
else if (BiggerPattern) {
2547 Opd0 =
N->getOperand(0);
2553 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2556 <<
": Found large shift immediate, this should not happen\n"));
2562 (VT == MVT::i32 ? llvm::countr_one<uint32_t>(AndImm)
2563 : llvm::countr_one<uint64_t>(AndImm)) -
2570 MSB = MSB > 31 ? 31 : MSB;
2572 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2577 SDValue &Opd0,
unsigned &Immr,
2581 EVT VT =
N->getValueType(0);
2583 assert((VT == MVT::i32 || VT == MVT::i64) &&
2584 "Type checking must have been done before calling this function");
2588 Op =
Op->getOperand(0);
2589 VT =
Op->getValueType(0);
2598 unsigned Width = cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2602 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2603 Opd0 =
Op.getOperand(0);
2605 Imms = ShiftImm + Width - 1;
2633 Opd0 =
N->getOperand(0).getOperand(0);
2643 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2650 unsigned &Immr,
unsigned &Imms,
2651 bool BiggerPattern) {
2653 "N must be a SHR/SRA operation to call this function");
2655 EVT VT =
N->getValueType(0);
2660 assert((VT == MVT::i32 || VT == MVT::i64) &&
2661 "Type checking must have been done before calling this function");
2671 Opd0 =
N->getOperand(0).getOperand(0);
2672 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2678 Opd0 =
N->getOperand(0).getOperand(0);
2681 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2682 }
else if (BiggerPattern) {
2686 Opd0 =
N->getOperand(0);
2695 <<
": Found large shift immediate, this should not happen\n"));
2704 "bad amount in shift node!");
2705 int immr = SrlImm - ShlImm;
2710 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2712 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2716bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *
N) {
2719 EVT VT =
N->getValueType(0);
2720 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2721 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2732 unsigned Immr = ShiftImm;
2734 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2735 CurDAG->getTargetConstant(Imms, dl, VT)};
2736 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT, Ops);
2741 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2742 unsigned NumberOfIgnoredLowBits = 0,
2743 bool BiggerPattern =
false) {
2744 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2747 switch (
N->getOpcode()) {
2749 if (!
N->isMachineOpcode())
2754 NumberOfIgnoredLowBits, BiggerPattern);
2763 unsigned NOpc =
N->getMachineOpcode();
2767 case AArch64::SBFMWri:
2768 case AArch64::UBFMWri:
2769 case AArch64::SBFMXri:
2770 case AArch64::UBFMXri:
2772 Opd0 =
N->getOperand(0);
2773 Immr =
N->getConstantOperandVal(1);
2774 Imms =
N->getConstantOperandVal(2);
2781bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *
N) {
2782 unsigned Opc, Immr, Imms;
2787 EVT VT =
N->getValueType(0);
2792 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2793 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2794 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2796 SDNode *
BFM = CurDAG->getMachineNode(Opc, dl, MVT::i64, Ops64);
2797 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2803 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2804 CurDAG->getTargetConstant(Imms, dl, VT)};
2805 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
2814 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2815 assert((VT == MVT::i32 || VT == MVT::i64) &&
2816 "i32 or i64 mask type expected!");
2820 APInt SignificantDstMask =
2824 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2825 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2848 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2858 APInt OpUsefulBits(UsefulBits);
2862 OpUsefulBits <<= MSB - Imm + 1;
2867 OpUsefulBits <<= Imm;
2869 OpUsefulBits <<= MSB + 1;
2872 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2878 UsefulBits &= OpUsefulBits;
2884 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2886 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2894 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2895 APInt Mask(UsefulBits);
2896 Mask.clearAllBits();
2904 Mask.lshrInPlace(ShiftAmt);
2910 Mask.lshrInPlace(ShiftAmt);
2922 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2924 cast<const ConstantSDNode>(
Op.getOperand(3).getNode())->getZExtValue();
2926 APInt OpUsefulBits(UsefulBits);
2940 OpUsefulBits <<= Width;
2943 if (
Op.getOperand(1) == Orig) {
2945 Mask = ResultUsefulBits & OpUsefulBits;
2949 if (
Op.getOperand(0) == Orig)
2951 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2957 OpUsefulBits <<= Width;
2959 OpUsefulBits <<= LSB;
2961 if (
Op.getOperand(1) == Orig) {
2963 Mask = ResultUsefulBits & OpUsefulBits;
2964 Mask.lshrInPlace(LSB);
2967 if (
Op.getOperand(0) == Orig)
2968 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2985 case AArch64::ANDSWri:
2986 case AArch64::ANDSXri:
2987 case AArch64::ANDWri:
2988 case AArch64::ANDXri:
2992 case AArch64::UBFMWri:
2993 case AArch64::UBFMXri:
2996 case AArch64::ORRWrs:
2997 case AArch64::ORRXrs:
3002 case AArch64::BFMWri:
3003 case AArch64::BFMXri:
3006 case AArch64::STRBBui:
3007 case AArch64::STURBBi:
3013 case AArch64::STRHHui:
3014 case AArch64::STURHHi:
3027 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3029 UsefulBits =
APInt(Bitwidth, 0);
3038 UsersUsefulBits |= UsefulBitsForUse;
3043 UsefulBits &= UsersUsefulBits;
3053 EVT VT =
Op.getValueType();
3056 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3059 if (ShlAmount > 0) {
3062 UBFMOpc, dl, VT,
Op,
3067 assert(ShlAmount < 0 &&
"expected right shift");
3068 int ShrAmount = -ShlAmount;
3094 bool BiggerPattern,
SDValue &Src,
3095 int &DstLSB,
int &Width) {
3096 EVT VT =
Op.getValueType();
3105 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3109 switch (
Op.getOpcode()) {
3114 NonZeroBits, Src, DstLSB, Width);
3117 NonZeroBits, Src, DstLSB, Width);
3130 EVT VT =
Op.getValueType();
3131 assert((VT == MVT::i32 || VT == MVT::i64) &&
3132 "Caller guarantees VT is one of i32 or i64");
3145 assert((~AndImm & NonZeroBits) == 0 &&
3146 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3175 if (!BiggerPattern && !AndOp0.
hasOneUse())
3194 <<
"Found large Width in bit-field-positioning -- this indicates no "
3195 "proper combining / constant folding was performed\n");
3204 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3219 "Op.getNode() should be a SHL node to call this function");
3221 "Op.getNode() should shift ShlImm to call this function");
3228 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3252 EVT VT =
Op.getValueType();
3253 assert((VT == MVT::i32 || VT == MVT::i64) &&
3254 "Caller guarantees that type is i32 or i64");
3261 if (!BiggerPattern && !
Op.hasOneUse())
3270 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3278 assert(VT == MVT::i32 || VT == MVT::i64);
3289 EVT VT =
N->getValueType(0);
3290 if (VT != MVT::i32 && VT != MVT::i64)
3308 if (!
And.hasOneUse() ||
3318 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3325 if ((OrImm & NotKnownZero) != 0) {
3337 unsigned ImmS = Width - 1;
3343 bool IsBFI = LSB != 0;
3348 unsigned OrChunks = 0, BFIChunks = 0;
3349 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3350 if (((OrImm >> Shift) & 0xFFFF) != 0)
3352 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3355 if (BFIChunks > OrChunks)
3361 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3369 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3378 if (!Dst.hasOneUse())
3381 EVT VT = Dst.getValueType();
3382 assert((VT == MVT::i32 || VT == MVT::i64) &&
3383 "Caller should guarantee that VT is one of i32 or i64");
3391 SDValue DstOp0 = Dst.getOperand(0);
3411 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3412 unsigned MaskWidth =
3415 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3421 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3422 ShiftedOperand =
SDValue(UBFMNode, 0);
3432 ShiftedOperand = Dst.getOperand(0);
3439 ShiftedOperand = Dst.getOperand(0);
3451 const bool BiggerPattern) {
3452 EVT VT =
N->getValueType(0);
3453 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3454 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3455 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3456 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3457 assert((VT == MVT::i32 || VT == MVT::i64) &&
3458 "Expect result type to be i32 or i64 since N is combinable to BFM");
3465 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3468 if (BiggerPattern) {
3482 SDValue Ops[] = {OrOpd0, ShiftedOperand,
3491 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3553 EVT VT =
N->getValueType(0);
3554 if (VT != MVT::i32 && VT != MVT::i64)
3562 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3563 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3583 for (
int I = 0;
I < 4; ++
I) {
3586 unsigned ImmR, ImmS;
3587 bool BiggerPattern =
I / 2;
3588 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3590 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3596 NumberOfIgnoredLowBits, BiggerPattern)) {
3599 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3600 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3605 Width = ImmS - ImmR + 1;
3616 Src, DstLSB, Width)) {
3624 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3634 APInt BitsToBeInserted =
3637 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3661 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3694 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3696 if (Src->hasOneUse() &&
3699 Src = Src->getOperand(0);
3709 unsigned ImmS = Width - 1;
3715 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3723bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *
N) {
3732 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3745bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *
N) {
3749 EVT VT =
N->getValueType(0);
3750 if (VT != MVT::i32 && VT != MVT::i64)
3756 Op0, DstLSB, Width))
3762 unsigned ImmS = Width - 1;
3765 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3766 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3767 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3768 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3774bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
3775 EVT VT =
N->getValueType(0);
3778 switch (
N->getOpcode()) {
3780 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3783 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3786 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3789 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3797 if (VT == MVT::i32) {
3800 }
else if (VT == MVT::i64) {
3806 SDValue ShiftAmt =
N->getOperand(1);
3826 (Add0Imm %
Size == 0)) {
3832 if (SubVT == MVT::i32) {
3833 NegOpc = AArch64::SUBWrr;
3834 ZeroReg = AArch64::WZR;
3836 assert(SubVT == MVT::i64);
3837 NegOpc = AArch64::SUBXrr;
3838 ZeroReg = AArch64::XZR;
3841 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3843 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3844 NewShiftAmt =
SDValue(Neg, 0);
3852 if (SubVT == MVT::i32) {
3853 NotOpc = AArch64::ORNWrr;
3854 ZeroReg = AArch64::WZR;
3856 assert(SubVT == MVT::i64);
3857 NotOpc = AArch64::ORNXrr;
3858 ZeroReg = AArch64::XZR;
3861 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3863 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3864 NewShiftAmt =
SDValue(Not, 0);
3885 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3886 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3888 AArch64::SUBREG_TO_REG,
DL, VT,
3889 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3890 NewShiftAmt =
SDValue(Ext, 0);
3893 SDValue Ops[] = {
N->getOperand(0), NewShiftAmt};
3894 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3901 bool isReciprocal) {
3904 FVal = CN->getValueAPF();
3905 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(
N)) {
3908 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
3912 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
3913 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
3936 if (!IsExact || !IntVal.isPowerOf2())
3938 unsigned FBits = IntVal.logBase2();
3942 if (FBits == 0 || FBits > RegWidth)
return false;
3948bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
3949 unsigned RegWidth) {
3954bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
3956 unsigned RegWidth) {
3966 RegString.
split(Fields,
':');
3968 if (Fields.
size() == 1)
3972 &&
"Invalid number of fields in read register string");
3975 bool AllIntFields =
true;
3979 AllIntFields &= !
Field.getAsInteger(10, IntField);
3984 "Unexpected non-integer value in special register string.");
3989 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
3990 (Ops[3] << 3) | (Ops[4]);
3997bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *
N) {
3998 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
3999 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4004 unsigned Opcode64Bit = AArch64::MRS;
4009 const auto *TheReg =
4011 if (TheReg && TheReg->Readable &&
4012 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4013 Imm = TheReg->Encoding;
4019 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4020 Opcode64Bit = AArch64::ADR;
4028 SDValue InChain =
N->getOperand(0);
4029 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4030 if (!ReadIs128Bit) {
4031 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4032 {SysRegImm, InChain});
4036 {MVT::Untyped , MVT::Other },
4037 {SysRegImm, InChain});
4041 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4043 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4049 ReplaceUses(
SDValue(
N, 2), OutChain);
4058bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *
N) {
4059 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4060 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4065 if (!WriteIs128Bit) {
4071 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4073 assert(isa<ConstantSDNode>(
N->getOperand(2)) &&
4074 "Expected a constant integer expression.");
4075 unsigned Reg = PMapper->Encoding;
4076 uint64_t Immed =
N->getConstantOperandVal(2);
4077 CurDAG->SelectNodeTo(
4078 N, State, MVT::Other, CurDAG->getTargetConstant(Reg,
DL, MVT::i32),
4079 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4085 if (trySelectPState(
4086 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4087 AArch64::MSRpstateImm4))
4089 if (trySelectPState(
4090 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4091 AArch64::MSRpstateImm1))
4101 if (TheReg && TheReg->Writeable &&
4102 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4103 Imm = TheReg->Encoding;
4111 SDValue InChain =
N->getOperand(0);
4112 if (!WriteIs128Bit) {
4113 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4114 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4115 N->getOperand(2), InChain);
4119 SDNode *Pair = CurDAG->getMachineNode(
4120 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4121 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4124 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4126 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4128 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4129 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4137bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *
N) {
4139 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
4142 if (Subtarget->hasLSE())
return false;
4144 if (MemTy == MVT::i8)
4145 Opcode = AArch64::CMP_SWAP_8;
4146 else if (MemTy == MVT::i16)
4147 Opcode = AArch64::CMP_SWAP_16;
4148 else if (MemTy == MVT::i32)
4149 Opcode = AArch64::CMP_SWAP_32;
4150 else if (MemTy == MVT::i64)
4151 Opcode = AArch64::CMP_SWAP_64;
4155 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4156 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4158 SDNode *CmpSwap = CurDAG->getMachineNode(
4160 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
4163 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {
MemOp});
4167 CurDAG->RemoveDeadNode(
N);
4174 if (!isa<ConstantSDNode>(
N))
4186 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4187 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4194 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4195 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4199 if (Val <= 65280 && Val % 256 == 0) {
4200 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4201 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4212bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N,
MVT VT,
4215 if (!isa<ConstantSDNode>(
N))
4219 int64_t Val = cast<ConstantSDNode>(
N)
4236 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4237 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4244 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4245 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4249 if (Val <= 65280 && Val % 256 == 0) {
4250 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4251 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4264 if (!isa<ConstantSDNode>(
N))
4268 int64_t Val = cast<ConstantSDNode>(
N)
4276 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4277 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4283 if (Val >= -128 && Val <= 127) {
4284 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4285 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4289 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) {
4290 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4291 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF,
DL, MVT::i32);
4302bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4303 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4304 int64_t ImmVal = CNode->getSExtValue();
4306 if (ImmVal >= -128 && ImmVal < 128) {
4307 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4315 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4316 uint64_t ImmVal = CNode->getZExtValue();
4326 ImmVal &= 0xFFFFFFFF;
4335 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4344 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4345 uint64_t ImmVal = CNode->getZExtValue();
4355 ImmVal |= ImmVal << 8;
4356 ImmVal |= ImmVal << 16;
4357 ImmVal |= ImmVal << 32;
4361 ImmVal |= ImmVal << 16;
4362 ImmVal |= ImmVal << 32;
4365 ImmVal &= 0xFFFFFFFF;
4366 ImmVal |= ImmVal << 32;
4376 Imm = CurDAG->getTargetConstant(encoding,
DL, MVT::i64);
4391 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
4392 uint64_t ImmVal = CN->getZExtValue();
4399 if (ImmVal >
High) {
4400 if (!AllowSaturation)
4405 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4412bool AArch64DAGToDAGISel::trySelectStackSlotTagP(
SDNode *
N) {
4416 if (!(isa<FrameIndexSDNode>(
N->getOperand(1)))) {
4428 int FI = cast<FrameIndexSDNode>(
N->getOperand(1))->getIndex();
4429 SDValue FiOp = CurDAG->getTargetFrameIndex(
4431 int TagOffset =
N->getConstantOperandVal(3);
4433 SDNode *Out = CurDAG->getMachineNode(
4434 AArch64::TAGPstack,
DL, MVT::i64,
4435 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->getOperand(2),
4436 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4437 ReplaceNode(
N, Out);
4441void AArch64DAGToDAGISel::SelectTagP(
SDNode *
N) {
4442 assert(isa<ConstantSDNode>(
N->getOperand(3)) &&
4443 "llvm.aarch64.tagp third argument must be an immediate");
4444 if (trySelectStackSlotTagP(
N))
4451 int TagOffset =
N->getConstantOperandVal(3);
4452 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4453 {
N->getOperand(1),
N->getOperand(2)});
4454 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4455 {
SDValue(N1, 0),
N->getOperand(2)});
4456 SDNode *N3 = CurDAG->getMachineNode(
4457 AArch64::ADDG,
DL, MVT::i64,
4458 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4459 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4463bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(
SDNode *
N) {
4467 if (
N->getConstantOperandVal(2) != 0)
4469 if (!
N->getOperand(0).isUndef())
4473 EVT VT =
N->getValueType(0);
4474 EVT InVT =
N->getOperand(1).getValueType();
4485 "Expected to insert into a packed scalable vector!");
4488 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4489 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4490 N->getOperand(1), RC));
4494bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(
SDNode *
N) {
4498 if (
N->getConstantOperandVal(1) != 0)
4502 EVT VT =
N->getValueType(0);
4503 EVT InVT =
N->getOperand(0).getValueType();
4514 "Expected to extract from a packed scalable vector!");
4517 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4518 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4519 N->getOperand(0), RC));
4523bool AArch64DAGToDAGISel::trySelectXAR(
SDNode *
N) {
4528 EVT VT =
N->getValueType(0);
4540 (Subtarget->hasSVE2() ||
4541 (Subtarget->hasSME() && Subtarget->isStreaming()))) {
4550 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4551 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4558 APInt ShlAmt, ShrAmt;
4571 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4572 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4573 AArch64::XAR_ZZZI_D})) {
4574 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
4580 if (!Subtarget->hasSHA3())
4602 if (ShAmt + HsAmt != 64)
4606 CurDAG->SelectNodeTo(
N, AArch64::XAR, N0.
getValueType(), Ops);
4611void AArch64DAGToDAGISel::Select(
SDNode *
Node) {
4613 if (
Node->isMachineOpcode()) {
4615 Node->setNodeId(-1);
4620 EVT VT =
Node->getValueType(0);
4622 switch (
Node->getOpcode()) {
4627 if (SelectCMP_SWAP(
Node))
4633 if (tryReadRegister(
Node))
4639 if (tryWriteRegister(
Node))
4646 if (tryIndexedLoad(
Node))
4655 if (tryBitfieldExtractOp(
Node))
4657 if (tryBitfieldInsertInZeroOp(
Node))
4662 if (tryShiftAmountMod(
Node))
4667 if (tryBitfieldExtractOpFromSExt(
Node))
4672 if (tryBitfieldInsertOp(
Node))
4674 if (trySelectXAR(
Node))
4679 if (trySelectCastScalableToFixedLengthVector(
Node))
4685 if (trySelectCastFixedLengthToScalableVector(
Node))
4694 if (ConstNode->
isZero()) {
4695 if (VT == MVT::i32) {
4697 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::WZR, MVT::i32);
4698 ReplaceNode(
Node,
New.getNode());
4700 }
else if (VT == MVT::i64) {
4702 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::XZR, MVT::i64);
4703 ReplaceNode(
Node,
New.getNode());
4712 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
4715 SDValue TFI = CurDAG->getTargetFrameIndex(
4718 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4719 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4720 CurDAG->SelectNodeTo(
Node, AArch64::ADDXri, MVT::i64, Ops);
4724 unsigned IntNo =
Node->getConstantOperandVal(1);
4728 case Intrinsic::aarch64_gcsss: {
4732 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4734 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4735 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4736 MVT::Other, Zero,
SDValue(SS1, 0));
4737 ReplaceNode(
Node, SS2);
4740 case Intrinsic::aarch64_ldaxp:
4741 case Intrinsic::aarch64_ldxp: {
4743 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4748 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4749 MVT::Other, MemAddr, Chain);
4753 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4754 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
4755 ReplaceNode(
Node, Ld);
4758 case Intrinsic::aarch64_stlxp:
4759 case Intrinsic::aarch64_stxp: {
4761 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4769 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4771 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other, Ops);
4774 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4775 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
4777 ReplaceNode(
Node, St);
4780 case Intrinsic::aarch64_neon_ld1x2:
4781 if (VT == MVT::v8i8) {
4782 SelectLoad(
Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4784 }
else if (VT == MVT::v16i8) {
4785 SelectLoad(
Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4787 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4788 SelectLoad(
Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4790 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4791 SelectLoad(
Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4793 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4794 SelectLoad(
Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4796 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4797 SelectLoad(
Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4799 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4800 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4802 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4803 SelectLoad(
Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4807 case Intrinsic::aarch64_neon_ld1x3:
4808 if (VT == MVT::v8i8) {
4809 SelectLoad(
Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
4811 }
else if (VT == MVT::v16i8) {
4812 SelectLoad(
Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
4814 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4815 SelectLoad(
Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
4817 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4818 SelectLoad(
Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
4820 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4821 SelectLoad(
Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
4823 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4824 SelectLoad(
Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
4826 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4827 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4829 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4830 SelectLoad(
Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
4834 case Intrinsic::aarch64_neon_ld1x4:
4835 if (VT == MVT::v8i8) {
4836 SelectLoad(
Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
4838 }
else if (VT == MVT::v16i8) {
4839 SelectLoad(
Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
4841 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4842 SelectLoad(
Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
4844 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4845 SelectLoad(
Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
4847 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4848 SelectLoad(
Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
4850 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4851 SelectLoad(
Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
4853 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4854 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4856 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4857 SelectLoad(
Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
4861 case Intrinsic::aarch64_neon_ld2:
4862 if (VT == MVT::v8i8) {
4863 SelectLoad(
Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
4865 }
else if (VT == MVT::v16i8) {
4866 SelectLoad(
Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
4868 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4869 SelectLoad(
Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
4871 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4872 SelectLoad(
Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
4874 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4875 SelectLoad(
Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
4877 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4878 SelectLoad(
Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
4880 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4881 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4883 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4884 SelectLoad(
Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
4888 case Intrinsic::aarch64_neon_ld3:
4889 if (VT == MVT::v8i8) {
4890 SelectLoad(
Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
4892 }
else if (VT == MVT::v16i8) {
4893 SelectLoad(
Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
4895 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4896 SelectLoad(
Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
4898 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4899 SelectLoad(
Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
4901 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4902 SelectLoad(
Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
4904 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4905 SelectLoad(
Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
4907 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4908 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4910 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4911 SelectLoad(
Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
4915 case Intrinsic::aarch64_neon_ld4:
4916 if (VT == MVT::v8i8) {
4917 SelectLoad(
Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
4919 }
else if (VT == MVT::v16i8) {
4920 SelectLoad(
Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
4922 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4923 SelectLoad(
Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
4925 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4926 SelectLoad(
Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
4928 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4929 SelectLoad(
Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
4931 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4932 SelectLoad(
Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
4934 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4935 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4937 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4938 SelectLoad(
Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
4942 case Intrinsic::aarch64_neon_ld2r:
4943 if (VT == MVT::v8i8) {
4944 SelectLoad(
Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
4946 }
else if (VT == MVT::v16i8) {
4947 SelectLoad(
Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
4949 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4950 SelectLoad(
Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
4952 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4953 SelectLoad(
Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
4955 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4956 SelectLoad(
Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
4958 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4959 SelectLoad(
Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
4961 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4962 SelectLoad(
Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
4964 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4965 SelectLoad(
Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
4969 case Intrinsic::aarch64_neon_ld3r:
4970 if (VT == MVT::v8i8) {
4971 SelectLoad(
Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
4973 }
else if (VT == MVT::v16i8) {
4974 SelectLoad(
Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
4976 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4977 SelectLoad(
Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
4979 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4980 SelectLoad(
Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
4982 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4983 SelectLoad(
Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
4985 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4986 SelectLoad(
Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
4988 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4989 SelectLoad(
Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
4991 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4992 SelectLoad(
Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
4996 case Intrinsic::aarch64_neon_ld4r:
4997 if (VT == MVT::v8i8) {
4998 SelectLoad(
Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5000 }
else if (VT == MVT::v16i8) {
5001 SelectLoad(
Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5003 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5004 SelectLoad(
Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5006 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5007 SelectLoad(
Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5009 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5010 SelectLoad(
Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5012 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5013 SelectLoad(
Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5015 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5016 SelectLoad(
Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5018 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5019 SelectLoad(
Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5023 case Intrinsic::aarch64_neon_ld2lane:
5024 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5025 SelectLoadLane(
Node, 2, AArch64::LD2i8);
5027 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5028 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5029 SelectLoadLane(
Node, 2, AArch64::LD2i16);
5031 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5033 SelectLoadLane(
Node, 2, AArch64::LD2i32);
5035 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5037 SelectLoadLane(
Node, 2, AArch64::LD2i64);
5041 case Intrinsic::aarch64_neon_ld3lane:
5042 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5043 SelectLoadLane(
Node, 3, AArch64::LD3i8);
5045 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5046 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5047 SelectLoadLane(
Node, 3, AArch64::LD3i16);
5049 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5051 SelectLoadLane(
Node, 3, AArch64::LD3i32);
5053 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5055 SelectLoadLane(
Node, 3, AArch64::LD3i64);
5059 case Intrinsic::aarch64_neon_ld4lane:
5060 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5061 SelectLoadLane(
Node, 4, AArch64::LD4i8);
5063 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5064 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5065 SelectLoadLane(
Node, 4, AArch64::LD4i16);
5067 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5069 SelectLoadLane(
Node, 4, AArch64::LD4i32);
5071 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5073 SelectLoadLane(
Node, 4, AArch64::LD4i64);
5077 case Intrinsic::aarch64_ld64b:
5078 SelectLoad(
Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5080 case Intrinsic::aarch64_sve_ld2q_sret: {
5081 SelectPredicatedLoad(
Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5084 case Intrinsic::aarch64_sve_ld3q_sret: {
5085 SelectPredicatedLoad(
Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5088 case Intrinsic::aarch64_sve_ld4q_sret: {
5089 SelectPredicatedLoad(
Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5092 case Intrinsic::aarch64_sve_ld2_sret: {
5093 if (VT == MVT::nxv16i8) {
5094 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5097 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5098 VT == MVT::nxv8bf16) {
5099 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5102 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5103 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5106 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5107 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5113 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5114 if (VT == MVT::nxv16i8) {
5115 if (Subtarget->hasSME2())
5116 SelectContiguousMultiVectorLoad(
5117 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5118 else if (Subtarget->hasSVE2p1())
5119 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LD1B_2Z_IMM,
5124 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5125 VT == MVT::nxv8bf16) {
5126 if (Subtarget->hasSME2())
5127 SelectContiguousMultiVectorLoad(
5128 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5129 else if (Subtarget->hasSVE2p1())
5130 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LD1H_2Z_IMM,
5135 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5136 if (Subtarget->hasSME2())
5137 SelectContiguousMultiVectorLoad(
5138 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5139 else if (Subtarget->hasSVE2p1())
5140 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LD1W_2Z_IMM,
5145 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5146 if (Subtarget->hasSME2())
5147 SelectContiguousMultiVectorLoad(
5148 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5149 else if (Subtarget->hasSVE2p1())
5150 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LD1D_2Z_IMM,
5158 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5159 if (VT == MVT::nxv16i8) {
5160 if (Subtarget->hasSME2())
5161 SelectContiguousMultiVectorLoad(
5162 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5163 else if (Subtarget->hasSVE2p1())
5164 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LD1B_4Z_IMM,
5169 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5170 VT == MVT::nxv8bf16) {
5171 if (Subtarget->hasSME2())
5172 SelectContiguousMultiVectorLoad(
5173 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5174 else if (Subtarget->hasSVE2p1())
5175 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LD1H_4Z_IMM,
5180 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5181 if (Subtarget->hasSME2())
5182 SelectContiguousMultiVectorLoad(
5183 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5184 else if (Subtarget->hasSVE2p1())
5185 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LD1W_4Z_IMM,
5190 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5191 if (Subtarget->hasSME2())
5192 SelectContiguousMultiVectorLoad(
5193 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5194 else if (Subtarget->hasSVE2p1())
5195 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LD1D_4Z_IMM,
5203 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5204 if (VT == MVT::nxv16i8) {
5205 if (Subtarget->hasSME2())
5206 SelectContiguousMultiVectorLoad(
Node, 2, 0,
5207 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5208 AArch64::LDNT1B_2Z_PSEUDO);
5209 else if (Subtarget->hasSVE2p1())
5210 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5211 AArch64::LDNT1B_2Z);
5215 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5216 VT == MVT::nxv8bf16) {
5217 if (Subtarget->hasSME2())
5218 SelectContiguousMultiVectorLoad(
Node, 2, 1,
5219 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5220 AArch64::LDNT1H_2Z_PSEUDO);
5221 else if (Subtarget->hasSVE2p1())
5222 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5223 AArch64::LDNT1H_2Z);
5227 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5228 if (Subtarget->hasSME2())
5229 SelectContiguousMultiVectorLoad(
Node, 2, 2,
5230 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5231 AArch64::LDNT1W_2Z_PSEUDO);
5232 else if (Subtarget->hasSVE2p1())
5233 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5234 AArch64::LDNT1W_2Z);
5238 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5239 if (Subtarget->hasSME2())
5240 SelectContiguousMultiVectorLoad(
Node, 2, 3,
5241 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5242 AArch64::LDNT1D_2Z_PSEUDO);
5243 else if (Subtarget->hasSVE2p1())
5244 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5245 AArch64::LDNT1D_2Z);
5252 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5253 if (VT == MVT::nxv16i8) {
5254 if (Subtarget->hasSME2())
5255 SelectContiguousMultiVectorLoad(
Node, 4, 0,
5256 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5257 AArch64::LDNT1B_4Z_PSEUDO);
5258 else if (Subtarget->hasSVE2p1())
5259 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5260 AArch64::LDNT1B_4Z);
5264 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5265 VT == MVT::nxv8bf16) {
5266 if (Subtarget->hasSME2())
5267 SelectContiguousMultiVectorLoad(
Node, 4, 1,
5268 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5269 AArch64::LDNT1H_4Z_PSEUDO);
5270 else if (Subtarget->hasSVE2p1())
5271 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5272 AArch64::LDNT1H_4Z);
5276 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5277 if (Subtarget->hasSME2())
5278 SelectContiguousMultiVectorLoad(
Node, 4, 2,
5279 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5280 AArch64::LDNT1W_4Z_PSEUDO);
5281 else if (Subtarget->hasSVE2p1())
5282 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5283 AArch64::LDNT1W_4Z);
5287 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5288 if (Subtarget->hasSME2())
5289 SelectContiguousMultiVectorLoad(
Node, 4, 3,
5290 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5291 AArch64::LDNT1D_4Z_PSEUDO);
5292 else if (Subtarget->hasSVE2p1())
5293 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5294 AArch64::LDNT1D_4Z);
5301 case Intrinsic::aarch64_sve_ld3_sret: {
5302 if (VT == MVT::nxv16i8) {
5303 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5306 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5307 VT == MVT::nxv8bf16) {
5308 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5311 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5312 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5315 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5316 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5322 case Intrinsic::aarch64_sve_ld4_sret: {
5323 if (VT == MVT::nxv16i8) {
5324 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5327 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5328 VT == MVT::nxv8bf16) {
5329 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5332 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5333 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5336 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5337 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5343 case Intrinsic::aarch64_sme_read_hor_vg2: {
5344 if (VT == MVT::nxv16i8) {
5345 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5346 AArch64::MOVA_2ZMXI_H_B);
5348 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5349 VT == MVT::nxv8bf16) {
5350 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5351 AArch64::MOVA_2ZMXI_H_H);
5353 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5354 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5355 AArch64::MOVA_2ZMXI_H_S);
5357 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5358 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5359 AArch64::MOVA_2ZMXI_H_D);
5364 case Intrinsic::aarch64_sme_read_ver_vg2: {
5365 if (VT == MVT::nxv16i8) {
5366 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5367 AArch64::MOVA_2ZMXI_V_B);
5369 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5370 VT == MVT::nxv8bf16) {
5371 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5372 AArch64::MOVA_2ZMXI_V_H);
5374 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5375 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5376 AArch64::MOVA_2ZMXI_V_S);
5378 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5379 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5380 AArch64::MOVA_2ZMXI_V_D);
5385 case Intrinsic::aarch64_sme_read_hor_vg4: {
5386 if (VT == MVT::nxv16i8) {
5387 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5388 AArch64::MOVA_4ZMXI_H_B);
5390 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5391 VT == MVT::nxv8bf16) {
5392 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5393 AArch64::MOVA_4ZMXI_H_H);
5395 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5396 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAS0,
5397 AArch64::MOVA_4ZMXI_H_S);
5399 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5400 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAD0,
5401 AArch64::MOVA_4ZMXI_H_D);
5406 case Intrinsic::aarch64_sme_read_ver_vg4: {
5407 if (VT == MVT::nxv16i8) {
5408 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5409 AArch64::MOVA_4ZMXI_V_B);
5411 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5412 VT == MVT::nxv8bf16) {
5413 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5414 AArch64::MOVA_4ZMXI_V_H);
5416 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5417 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAS0,
5418 AArch64::MOVA_4ZMXI_V_S);
5420 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5421 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAD0,
5422 AArch64::MOVA_4ZMXI_V_D);
5427 case Intrinsic::aarch64_sme_read_vg1x2: {
5428 SelectMultiVectorMove<7, 1>(
Node, 2, AArch64::ZA,
5429 AArch64::MOVA_VG2_2ZMXI);
5432 case Intrinsic::aarch64_sme_read_vg1x4: {
5433 SelectMultiVectorMove<7, 1>(
Node, 4, AArch64::ZA,
5434 AArch64::MOVA_VG4_4ZMXI);
5437 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5438 if (VT == MVT::nxv16i8) {
5439 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5441 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5442 VT == MVT::nxv8bf16) {
5443 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5445 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5446 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5448 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5449 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5454 case Intrinsic::aarch64_sme_readz_vert_x2: {
5455 if (VT == MVT::nxv16i8) {
5456 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5458 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5459 VT == MVT::nxv8bf16) {
5460 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5462 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5463 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5465 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5466 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5471 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5472 if (VT == MVT::nxv16i8) {
5473 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5475 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5476 VT == MVT::nxv8bf16) {
5477 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5479 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5480 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5482 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5483 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5488 case Intrinsic::aarch64_sme_readz_vert_x4: {
5489 if (VT == MVT::nxv16i8) {
5490 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5492 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5493 VT == MVT::nxv8bf16) {
5494 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5496 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5497 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5499 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5500 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5505 case Intrinsic::aarch64_sme_readz_x2: {
5506 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5510 case Intrinsic::aarch64_sme_readz_x4: {
5511 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5515 case Intrinsic::swift_async_context_addr: {
5518 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5520 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5521 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5522 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5526 CurDAG->RemoveDeadNode(
Node);
5528 auto &MF = CurDAG->getMachineFunction();
5529 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5533 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5534 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5535 Node->getValueType(0),
5536 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5537 AArch64::LUTI2_4ZTZI_S}))
5539 SelectMultiVectorLutiLane(
Node, 4, Opc, 3);
5542 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5543 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5544 Node->getValueType(0),
5545 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5547 SelectMultiVectorLutiLane(
Node, 4, Opc, 1);
5550 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5551 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5552 Node->getValueType(0),
5553 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5554 AArch64::LUTI2_2ZTZI_S}))
5556 SelectMultiVectorLutiLane(
Node, 2, Opc, 7);
5559 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5560 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5561 Node->getValueType(0),
5562 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5563 AArch64::LUTI4_2ZTZI_S}))
5565 SelectMultiVectorLutiLane(
Node, 2, Opc, 3);
5568 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5569 SelectMultiVectorLuti(
Node, 4, AArch64::LUTI4_4ZZT2Z);
5572 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5573 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5574 Node->getValueType(0),
5575 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5576 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5578 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5579 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5580 Node->getValueType(0),
5581 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5582 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5584 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5585 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5586 Node->getValueType(0),
5587 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5588 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5590 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5591 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5592 Node->getValueType(0),
5593 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5594 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5599 unsigned IntNo =
Node->getConstantOperandVal(0);
5603 case Intrinsic::aarch64_tagp:
5607 case Intrinsic::ptrauth_auth:
5608 SelectPtrauthAuth(
Node);
5611 case Intrinsic::ptrauth_resign:
5612 SelectPtrauthResign(
Node);
5615 case Intrinsic::aarch64_neon_tbl2:
5616 SelectTable(
Node, 2,
5617 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5620 case Intrinsic::aarch64_neon_tbl3:
5621 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5622 : AArch64::TBLv16i8Three,
5625 case Intrinsic::aarch64_neon_tbl4:
5626 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5627 : AArch64::TBLv16i8Four,
5630 case Intrinsic::aarch64_neon_tbx2:
5631 SelectTable(
Node, 2,
5632 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5635 case Intrinsic::aarch64_neon_tbx3:
5636 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5637 : AArch64::TBXv16i8Three,
5640 case Intrinsic::aarch64_neon_tbx4:
5641 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5642 : AArch64::TBXv16i8Four,
5645 case Intrinsic::aarch64_sve_srshl_single_x2:
5646 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5647 Node->getValueType(0),
5648 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5649 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5650 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5652 case Intrinsic::aarch64_sve_srshl_single_x4:
5653 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5654 Node->getValueType(0),
5655 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5656 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5657 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5659 case Intrinsic::aarch64_sve_urshl_single_x2:
5660 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5661 Node->getValueType(0),
5662 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5663 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5664 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5666 case Intrinsic::aarch64_sve_urshl_single_x4:
5667 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5668 Node->getValueType(0),
5669 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5670 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5671 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5673 case Intrinsic::aarch64_sve_srshl_x2:
5674 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5675 Node->getValueType(0),
5676 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5677 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5678 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5680 case Intrinsic::aarch64_sve_srshl_x4:
5681 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5682 Node->getValueType(0),
5683 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5684 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5685 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5687 case Intrinsic::aarch64_sve_urshl_x2:
5688 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5689 Node->getValueType(0),
5690 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5691 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5692 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5694 case Intrinsic::aarch64_sve_urshl_x4:
5695 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5696 Node->getValueType(0),
5697 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5698 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5699 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5701 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5702 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5703 Node->getValueType(0),
5704 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5705 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5706 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5708 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5709 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5710 Node->getValueType(0),
5711 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5712 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5713 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5715 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5716 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5717 Node->getValueType(0),
5718 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5719 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5720 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5722 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5723 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5724 Node->getValueType(0),
5725 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5726 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5727 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5729 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5730 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5731 Node->getValueType(0),
5732 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5733 AArch64::FSCALE_2ZZ_D}))
5734 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5736 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5737 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5738 Node->getValueType(0),
5739 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5740 AArch64::FSCALE_4ZZ_D}))
5741 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5743 case Intrinsic::aarch64_sme_fp8_scale_x2:
5744 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5745 Node->getValueType(0),
5746 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5747 AArch64::FSCALE_2Z2Z_D}))
5748 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5750 case Intrinsic::aarch64_sme_fp8_scale_x4:
5751 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5752 Node->getValueType(0),
5753 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5754 AArch64::FSCALE_4Z4Z_D}))
5755 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5757 case Intrinsic::aarch64_sve_whilege_x2:
5758 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5759 Node->getValueType(0),
5760 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5761 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5762 SelectWhilePair(
Node,
Op);
5764 case Intrinsic::aarch64_sve_whilegt_x2:
5765 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5766 Node->getValueType(0),
5767 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5768 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5769 SelectWhilePair(
Node,
Op);
5771 case Intrinsic::aarch64_sve_whilehi_x2:
5772 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5773 Node->getValueType(0),
5774 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5775 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5776 SelectWhilePair(
Node,
Op);
5778 case Intrinsic::aarch64_sve_whilehs_x2:
5779 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5780 Node->getValueType(0),
5781 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5782 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5783 SelectWhilePair(
Node,
Op);
5785 case Intrinsic::aarch64_sve_whilele_x2:
5786 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5787 Node->getValueType(0),
5788 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5789 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5790 SelectWhilePair(
Node,
Op);
5792 case Intrinsic::aarch64_sve_whilelo_x2:
5793 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5794 Node->getValueType(0),
5795 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5796 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5797 SelectWhilePair(
Node,
Op);
5799 case Intrinsic::aarch64_sve_whilels_x2:
5800 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5801 Node->getValueType(0),
5802 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5803 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5804 SelectWhilePair(
Node,
Op);
5806 case Intrinsic::aarch64_sve_whilelt_x2:
5807 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5808 Node->getValueType(0),
5809 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
5810 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
5811 SelectWhilePair(
Node,
Op);
5813 case Intrinsic::aarch64_sve_smax_single_x2:
5814 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5815 Node->getValueType(0),
5816 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
5817 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
5818 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5820 case Intrinsic::aarch64_sve_umax_single_x2:
5821 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5822 Node->getValueType(0),
5823 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
5824 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
5825 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5827 case Intrinsic::aarch64_sve_fmax_single_x2:
5828 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5829 Node->getValueType(0),
5830 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
5831 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
5832 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5834 case Intrinsic::aarch64_sve_smax_single_x4:
5835 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5836 Node->getValueType(0),
5837 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
5838 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
5839 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5841 case Intrinsic::aarch64_sve_umax_single_x4:
5842 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5843 Node->getValueType(0),
5844 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
5845 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
5846 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5848 case Intrinsic::aarch64_sve_fmax_single_x4:
5849 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5850 Node->getValueType(0),
5851 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
5852 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
5853 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5855 case Intrinsic::aarch64_sve_smin_single_x2:
5856 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5857 Node->getValueType(0),
5858 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
5859 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
5860 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5862 case Intrinsic::aarch64_sve_umin_single_x2:
5863 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5864 Node->getValueType(0),
5865 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
5866 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
5867 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5869 case Intrinsic::aarch64_sve_fmin_single_x2:
5870 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5871 Node->getValueType(0),
5872 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
5873 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
5874 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5876 case Intrinsic::aarch64_sve_smin_single_x4:
5877 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5878 Node->getValueType(0),
5879 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
5880 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
5881 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5883 case Intrinsic::aarch64_sve_umin_single_x4:
5884 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5885 Node->getValueType(0),
5886 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
5887 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
5888 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5890 case Intrinsic::aarch64_sve_fmin_single_x4:
5891 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5892 Node->getValueType(0),
5893 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
5894 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
5895 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5897 case Intrinsic::aarch64_sve_smax_x2:
5898 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5899 Node->getValueType(0),
5900 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
5901 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
5902 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5904 case Intrinsic::aarch64_sve_umax_x2:
5905 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5906 Node->getValueType(0),
5907 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
5908 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
5909 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5911 case Intrinsic::aarch64_sve_fmax_x2:
5912 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5913 Node->getValueType(0),
5914 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
5915 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
5916 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5918 case Intrinsic::aarch64_sve_smax_x4:
5919 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5920 Node->getValueType(0),
5921 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
5922 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
5923 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5925 case Intrinsic::aarch64_sve_umax_x4:
5926 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5927 Node->getValueType(0),
5928 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
5929 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
5930 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5932 case Intrinsic::aarch64_sve_fmax_x4:
5933 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5934 Node->getValueType(0),
5935 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
5936 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
5937 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5939 case Intrinsic::aarch64_sme_famax_x2:
5940 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5941 Node->getValueType(0),
5942 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
5943 AArch64::FAMAX_2Z2Z_D}))
5944 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5946 case Intrinsic::aarch64_sme_famax_x4:
5947 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5948 Node->getValueType(0),
5949 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
5950 AArch64::FAMAX_4Z4Z_D}))
5951 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5953 case Intrinsic::aarch64_sme_famin_x2:
5954 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5955 Node->getValueType(0),
5956 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
5957 AArch64::FAMIN_2Z2Z_D}))
5958 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5960 case Intrinsic::aarch64_sme_famin_x4:
5961 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5962 Node->getValueType(0),
5963 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
5964 AArch64::FAMIN_4Z4Z_D}))
5965 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5967 case Intrinsic::aarch64_sve_smin_x2:
5968 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5969 Node->getValueType(0),
5970 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
5971 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
5972 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5974 case Intrinsic::aarch64_sve_umin_x2:
5975 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5976 Node->getValueType(0),
5977 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
5978 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
5979 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5981 case Intrinsic::aarch64_sve_fmin_x2:
5982 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5983 Node->getValueType(0),
5984 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
5985 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
5986 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5988 case Intrinsic::aarch64_sve_smin_x4:
5989 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5990 Node->getValueType(0),
5991 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
5992 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
5993 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5995 case Intrinsic::aarch64_sve_umin_x4:
5996 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5997 Node->getValueType(0),
5998 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
5999 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6000 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6002 case Intrinsic::aarch64_sve_fmin_x4:
6003 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6004 Node->getValueType(0),
6005 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6006 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6007 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6009 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6010 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6011 Node->getValueType(0),
6012 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6013 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6014 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6016 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6017 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6018 Node->getValueType(0),
6019 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6020 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6021 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6023 case Intrinsic::aarch64_sve_fminnm_single_x2:
6024 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6025 Node->getValueType(0),
6026 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6027 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6028 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6030 case Intrinsic::aarch64_sve_fminnm_single_x4:
6031 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6032 Node->getValueType(0),
6033 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6034 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6035 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6037 case Intrinsic::aarch64_sve_fmaxnm_x2:
6038 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6039 Node->getValueType(0),
6040 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6041 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6042 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6044 case Intrinsic::aarch64_sve_fmaxnm_x4:
6045 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6046 Node->getValueType(0),
6047 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6048 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6049 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6051 case Intrinsic::aarch64_sve_fminnm_x2:
6052 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6053 Node->getValueType(0),
6054 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6055 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6056 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6058 case Intrinsic::aarch64_sve_fminnm_x4:
6059 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6060 Node->getValueType(0),
6061 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6062 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6063 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6065 case Intrinsic::aarch64_sve_fcvtzs_x2:
6066 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6068 case Intrinsic::aarch64_sve_scvtf_x2:
6069 SelectCVTIntrinsic(
Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6071 case Intrinsic::aarch64_sve_fcvtzu_x2:
6072 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6074 case Intrinsic::aarch64_sve_ucvtf_x2:
6075 SelectCVTIntrinsic(
Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6077 case Intrinsic::aarch64_sve_fcvtzs_x4:
6078 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6080 case Intrinsic::aarch64_sve_scvtf_x4:
6081 SelectCVTIntrinsic(
Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6083 case Intrinsic::aarch64_sve_fcvtzu_x4:
6084 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6086 case Intrinsic::aarch64_sve_ucvtf_x4:
6087 SelectCVTIntrinsic(
Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6089 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6090 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6092 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6093 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6095 case Intrinsic::aarch64_sve_sclamp_single_x2:
6096 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6097 Node->getValueType(0),
6098 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6099 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6100 SelectClamp(
Node, 2,
Op);
6102 case Intrinsic::aarch64_sve_uclamp_single_x2:
6103 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6104 Node->getValueType(0),
6105 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6106 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6107 SelectClamp(
Node, 2,
Op);
6109 case Intrinsic::aarch64_sve_fclamp_single_x2:
6110 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6111 Node->getValueType(0),
6112 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6113 AArch64::FCLAMP_VG2_2Z2Z_D}))
6114 SelectClamp(
Node, 2,
Op);
6116 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6117 SelectClamp(
Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6119 case Intrinsic::aarch64_sve_sclamp_single_x4:
6120 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6121 Node->getValueType(0),
6122 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6123 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6124 SelectClamp(
Node, 4,
Op);
6126 case Intrinsic::aarch64_sve_uclamp_single_x4:
6127 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6128 Node->getValueType(0),
6129 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6130 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6131 SelectClamp(
Node, 4,
Op);
6133 case Intrinsic::aarch64_sve_fclamp_single_x4:
6134 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6135 Node->getValueType(0),
6136 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6137 AArch64::FCLAMP_VG4_4Z4Z_D}))
6138 SelectClamp(
Node, 4,
Op);
6140 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6141 SelectClamp(
Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6143 case Intrinsic::aarch64_sve_add_single_x2:
6144 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6145 Node->getValueType(0),
6146 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6147 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6148 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6150 case Intrinsic::aarch64_sve_add_single_x4:
6151 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6152 Node->getValueType(0),
6153 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6154 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6155 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6157 case Intrinsic::aarch64_sve_zip_x2:
6158 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6159 Node->getValueType(0),
6160 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6161 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6162 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6164 case Intrinsic::aarch64_sve_zipq_x2:
6165 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6166 AArch64::ZIP_VG2_2ZZZ_Q);
6168 case Intrinsic::aarch64_sve_zip_x4:
6169 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6170 Node->getValueType(0),
6171 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6172 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6173 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6175 case Intrinsic::aarch64_sve_zipq_x4:
6176 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6177 AArch64::ZIP_VG4_4Z4Z_Q);
6179 case Intrinsic::aarch64_sve_uzp_x2:
6180 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6181 Node->getValueType(0),
6182 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6183 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6184 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6186 case Intrinsic::aarch64_sve_uzpq_x2:
6187 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6188 AArch64::UZP_VG2_2ZZZ_Q);
6190 case Intrinsic::aarch64_sve_uzp_x4:
6191 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6192 Node->getValueType(0),
6193 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6194 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6195 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6197 case Intrinsic::aarch64_sve_uzpq_x4:
6198 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6199 AArch64::UZP_VG4_4Z4Z_Q);
6201 case Intrinsic::aarch64_sve_sel_x2:
6202 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6203 Node->getValueType(0),
6204 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6205 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6206 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op,
true);
6208 case Intrinsic::aarch64_sve_sel_x4:
6209 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6210 Node->getValueType(0),
6211 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6212 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6213 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op,
true);
6215 case Intrinsic::aarch64_sve_frinta_x2:
6216 SelectFrintFromVT(
Node, 2, AArch64::FRINTA_2Z2Z_S);
6218 case Intrinsic::aarch64_sve_frinta_x4:
6219 SelectFrintFromVT(
Node, 4, AArch64::FRINTA_4Z4Z_S);
6221 case Intrinsic::aarch64_sve_frintm_x2:
6222 SelectFrintFromVT(
Node, 2, AArch64::FRINTM_2Z2Z_S);
6224 case Intrinsic::aarch64_sve_frintm_x4:
6225 SelectFrintFromVT(
Node, 4, AArch64::FRINTM_4Z4Z_S);
6227 case Intrinsic::aarch64_sve_frintn_x2:
6228 SelectFrintFromVT(
Node, 2, AArch64::FRINTN_2Z2Z_S);
6230 case Intrinsic::aarch64_sve_frintn_x4:
6231 SelectFrintFromVT(
Node, 4, AArch64::FRINTN_4Z4Z_S);
6233 case Intrinsic::aarch64_sve_frintp_x2:
6234 SelectFrintFromVT(
Node, 2, AArch64::FRINTP_2Z2Z_S);
6236 case Intrinsic::aarch64_sve_frintp_x4:
6237 SelectFrintFromVT(
Node, 4, AArch64::FRINTP_4Z4Z_S);
6239 case Intrinsic::aarch64_sve_sunpk_x2:
6240 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6241 Node->getValueType(0),
6242 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6243 AArch64::SUNPK_VG2_2ZZ_D}))
6244 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6246 case Intrinsic::aarch64_sve_uunpk_x2:
6247 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6248 Node->getValueType(0),
6249 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6250 AArch64::UUNPK_VG2_2ZZ_D}))
6251 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6253 case Intrinsic::aarch64_sve_sunpk_x4:
6254 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6255 Node->getValueType(0),
6256 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6257 AArch64::SUNPK_VG4_4Z2Z_D}))
6258 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6260 case Intrinsic::aarch64_sve_uunpk_x4:
6261 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6262 Node->getValueType(0),
6263 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6264 AArch64::UUNPK_VG4_4Z2Z_D}))
6265 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6267 case Intrinsic::aarch64_sve_pext_x2: {
6268 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6269 Node->getValueType(0),
6270 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6271 AArch64::PEXT_2PCI_D}))
6272 SelectPExtPair(
Node,
Op);
6279 unsigned IntNo =
Node->getConstantOperandVal(1);
6280 if (
Node->getNumOperands() >= 3)
6281 VT =
Node->getOperand(2)->getValueType(0);
6285 case Intrinsic::aarch64_neon_st1x2: {
6286 if (VT == MVT::v8i8) {
6287 SelectStore(
Node, 2, AArch64::ST1Twov8b);
6289 }
else if (VT == MVT::v16i8) {
6290 SelectStore(
Node, 2, AArch64::ST1Twov16b);
6292 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6293 VT == MVT::v4bf16) {
6294 SelectStore(
Node, 2, AArch64::ST1Twov4h);
6296 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6297 VT == MVT::v8bf16) {
6298 SelectStore(
Node, 2, AArch64::ST1Twov8h);
6300 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6301 SelectStore(
Node, 2, AArch64::ST1Twov2s);
6303 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6304 SelectStore(
Node, 2, AArch64::ST1Twov4s);
6306 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6307 SelectStore(
Node, 2, AArch64::ST1Twov2d);
6309 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6310 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6315 case Intrinsic::aarch64_neon_st1x3: {
6316 if (VT == MVT::v8i8) {
6317 SelectStore(
Node, 3, AArch64::ST1Threev8b);
6319 }
else if (VT == MVT::v16i8) {
6320 SelectStore(
Node, 3, AArch64::ST1Threev16b);
6322 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6323 VT == MVT::v4bf16) {
6324 SelectStore(
Node, 3, AArch64::ST1Threev4h);
6326 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6327 VT == MVT::v8bf16) {
6328 SelectStore(
Node, 3, AArch64::ST1Threev8h);
6330 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6331 SelectStore(
Node, 3, AArch64::ST1Threev2s);
6333 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6334 SelectStore(
Node, 3, AArch64::ST1Threev4s);
6336 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6337 SelectStore(
Node, 3, AArch64::ST1Threev2d);
6339 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6340 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6345 case Intrinsic::aarch64_neon_st1x4: {
6346 if (VT == MVT::v8i8) {
6347 SelectStore(
Node, 4, AArch64::ST1Fourv8b);
6349 }
else if (VT == MVT::v16i8) {
6350 SelectStore(
Node, 4, AArch64::ST1Fourv16b);
6352 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6353 VT == MVT::v4bf16) {
6354 SelectStore(
Node, 4, AArch64::ST1Fourv4h);
6356 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6357 VT == MVT::v8bf16) {
6358 SelectStore(
Node, 4, AArch64::ST1Fourv8h);
6360 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6361 SelectStore(
Node, 4, AArch64::ST1Fourv2s);
6363 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6364 SelectStore(
Node, 4, AArch64::ST1Fourv4s);
6366 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6367 SelectStore(
Node, 4, AArch64::ST1Fourv2d);
6369 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6370 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6375 case Intrinsic::aarch64_neon_st2: {
6376 if (VT == MVT::v8i8) {
6377 SelectStore(
Node, 2, AArch64::ST2Twov8b);
6379 }
else if (VT == MVT::v16i8) {
6380 SelectStore(
Node, 2, AArch64::ST2Twov16b);
6382 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6383 VT == MVT::v4bf16) {
6384 SelectStore(
Node, 2, AArch64::ST2Twov4h);
6386 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6387 VT == MVT::v8bf16) {
6388 SelectStore(
Node, 2, AArch64::ST2Twov8h);
6390 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6391 SelectStore(
Node, 2, AArch64::ST2Twov2s);
6393 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6394 SelectStore(
Node, 2, AArch64::ST2Twov4s);
6396 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6397 SelectStore(
Node, 2, AArch64::ST2Twov2d);
6399 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6400 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6405 case Intrinsic::aarch64_neon_st3: {
6406 if (VT == MVT::v8i8) {
6407 SelectStore(
Node, 3, AArch64::ST3Threev8b);
6409 }
else if (VT == MVT::v16i8) {
6410 SelectStore(
Node, 3, AArch64::ST3Threev16b);
6412 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6413 VT == MVT::v4bf16) {
6414 SelectStore(
Node, 3, AArch64::ST3Threev4h);
6416 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6417 VT == MVT::v8bf16) {
6418 SelectStore(
Node, 3, AArch64::ST3Threev8h);
6420 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6421 SelectStore(
Node, 3, AArch64::ST3Threev2s);
6423 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6424 SelectStore(
Node, 3, AArch64::ST3Threev4s);
6426 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6427 SelectStore(
Node, 3, AArch64::ST3Threev2d);
6429 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6430 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6435 case Intrinsic::aarch64_neon_st4: {
6436 if (VT == MVT::v8i8) {
6437 SelectStore(
Node, 4, AArch64::ST4Fourv8b);
6439 }
else if (VT == MVT::v16i8) {
6440 SelectStore(
Node, 4, AArch64::ST4Fourv16b);
6442 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6443 VT == MVT::v4bf16) {
6444 SelectStore(
Node, 4, AArch64::ST4Fourv4h);
6446 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6447 VT == MVT::v8bf16) {
6448 SelectStore(
Node, 4, AArch64::ST4Fourv8h);
6450 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6451 SelectStore(
Node, 4, AArch64::ST4Fourv2s);
6453 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6454 SelectStore(
Node, 4, AArch64::ST4Fourv4s);
6456 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6457 SelectStore(
Node, 4, AArch64::ST4Fourv2d);
6459 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6460 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6465 case Intrinsic::aarch64_neon_st2lane: {
6466 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6467 SelectStoreLane(
Node, 2, AArch64::ST2i8);
6469 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6470 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6471 SelectStoreLane(
Node, 2, AArch64::ST2i16);
6473 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6475 SelectStoreLane(
Node, 2, AArch64::ST2i32);
6477 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6479 SelectStoreLane(
Node, 2, AArch64::ST2i64);
6484 case Intrinsic::aarch64_neon_st3lane: {
6485 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6486 SelectStoreLane(
Node, 3, AArch64::ST3i8);
6488 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6489 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6490 SelectStoreLane(
Node, 3, AArch64::ST3i16);
6492 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6494 SelectStoreLane(
Node, 3, AArch64::ST3i32);
6496 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6498 SelectStoreLane(
Node, 3, AArch64::ST3i64);
6503 case Intrinsic::aarch64_neon_st4lane: {
6504 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6505 SelectStoreLane(
Node, 4, AArch64::ST4i8);
6507 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6508 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6509 SelectStoreLane(
Node, 4, AArch64::ST4i16);
6511 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6513 SelectStoreLane(
Node, 4, AArch64::ST4i32);
6515 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6517 SelectStoreLane(
Node, 4, AArch64::ST4i64);
6522 case Intrinsic::aarch64_sve_st2q: {
6523 SelectPredicatedStore(
Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6526 case Intrinsic::aarch64_sve_st3q: {
6527 SelectPredicatedStore(
Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6530 case Intrinsic::aarch64_sve_st4q: {
6531 SelectPredicatedStore(
Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6534 case Intrinsic::aarch64_sve_st2: {
6535 if (VT == MVT::nxv16i8) {
6536 SelectPredicatedStore(
Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6538 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6539 VT == MVT::nxv8bf16) {
6540 SelectPredicatedStore(
Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6542 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6543 SelectPredicatedStore(
Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6545 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6546 SelectPredicatedStore(
Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6551 case Intrinsic::aarch64_sve_st3: {
6552 if (VT == MVT::nxv16i8) {
6553 SelectPredicatedStore(
Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6555 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6556 VT == MVT::nxv8bf16) {
6557 SelectPredicatedStore(
Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6559 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6560 SelectPredicatedStore(
Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6562 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6563 SelectPredicatedStore(
Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6568 case Intrinsic::aarch64_sve_st4: {
6569 if (VT == MVT::nxv16i8) {
6570 SelectPredicatedStore(
Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6572 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6573 VT == MVT::nxv8bf16) {
6574 SelectPredicatedStore(
Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6576 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6577 SelectPredicatedStore(
Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6579 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6580 SelectPredicatedStore(
Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6589 if (VT == MVT::v8i8) {
6590 SelectPostLoad(
Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6592 }
else if (VT == MVT::v16i8) {
6593 SelectPostLoad(
Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6595 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6596 SelectPostLoad(
Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6598 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6599 SelectPostLoad(
Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6601 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6602 SelectPostLoad(
Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6604 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6605 SelectPostLoad(
Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6607 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6608 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6610 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6611 SelectPostLoad(
Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6617 if (VT == MVT::v8i8) {
6618 SelectPostLoad(
Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6620 }
else if (VT == MVT::v16i8) {
6621 SelectPostLoad(
Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6623 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6624 SelectPostLoad(
Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6626 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6627 SelectPostLoad(
Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6629 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6630 SelectPostLoad(
Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6632 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6633 SelectPostLoad(
Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6635 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6636 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6638 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6639 SelectPostLoad(
Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6645 if (VT == MVT::v8i8) {
6646 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6648 }
else if (VT == MVT::v16i8) {
6649 SelectPostLoad(
Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6651 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6652 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6654 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6655 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6657 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6658 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6660 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6661 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6663 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6664 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6666 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6667 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6673 if (VT == MVT::v8i8) {
6674 SelectPostLoad(
Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6676 }
else if (VT == MVT::v16i8) {
6677 SelectPostLoad(
Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6679 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6680 SelectPostLoad(
Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6682 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6683 SelectPostLoad(
Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6685 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6686 SelectPostLoad(
Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6688 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6689 SelectPostLoad(
Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6691 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6692 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6694 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6695 SelectPostLoad(
Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6701 if (VT == MVT::v8i8) {
6702 SelectPostLoad(
Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6704 }
else if (VT == MVT::v16i8) {
6705 SelectPostLoad(
Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6707 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6708 SelectPostLoad(
Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6710 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6711 SelectPostLoad(
Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6713 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6714 SelectPostLoad(
Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6716 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6717 SelectPostLoad(
Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6719 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6720 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6722 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6723 SelectPostLoad(
Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6729 if (VT == MVT::v8i8) {
6730 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6732 }
else if (VT == MVT::v16i8) {
6733 SelectPostLoad(
Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6735 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6736 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6738 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6739 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6741 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6742 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6744 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6745 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6747 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6748 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6750 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6751 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6757 if (VT == MVT::v8i8) {
6758 SelectPostLoad(
Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6760 }
else if (VT == MVT::v16i8) {
6761 SelectPostLoad(
Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6763 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6764 SelectPostLoad(
Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6766 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6767 SelectPostLoad(
Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6769 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6770 SelectPostLoad(
Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6772 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6773 SelectPostLoad(
Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6775 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6776 SelectPostLoad(
Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6778 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6779 SelectPostLoad(
Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6785 if (VT == MVT::v8i8) {
6786 SelectPostLoad(
Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6788 }
else if (VT == MVT::v16i8) {
6789 SelectPostLoad(
Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6791 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6792 SelectPostLoad(
Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6794 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6795 SelectPostLoad(
Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6797 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6798 SelectPostLoad(
Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6800 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6801 SelectPostLoad(
Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6803 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6804 SelectPostLoad(
Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6806 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6807 SelectPostLoad(
Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
6813 if (VT == MVT::v8i8) {
6814 SelectPostLoad(
Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
6816 }
else if (VT == MVT::v16i8) {
6817 SelectPostLoad(
Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
6819 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6820 SelectPostLoad(
Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
6822 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6823 SelectPostLoad(
Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
6825 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6826 SelectPostLoad(
Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
6828 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6829 SelectPostLoad(
Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
6831 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6832 SelectPostLoad(
Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
6834 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6835 SelectPostLoad(
Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
6841 if (VT == MVT::v8i8) {
6842 SelectPostLoad(
Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
6844 }
else if (VT == MVT::v16i8) {
6845 SelectPostLoad(
Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
6847 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6848 SelectPostLoad(
Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
6850 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6851 SelectPostLoad(
Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
6853 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6854 SelectPostLoad(
Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
6856 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6857 SelectPostLoad(
Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
6859 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6860 SelectPostLoad(
Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
6862 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6863 SelectPostLoad(
Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
6869 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6870 SelectPostLoadLane(
Node, 1, AArch64::LD1i8_POST);
6872 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6873 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6874 SelectPostLoadLane(
Node, 1, AArch64::LD1i16_POST);
6876 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6878 SelectPostLoadLane(
Node, 1, AArch64::LD1i32_POST);
6880 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6882 SelectPostLoadLane(
Node, 1, AArch64::LD1i64_POST);
6888 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6889 SelectPostLoadLane(
Node, 2, AArch64::LD2i8_POST);
6891 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6892 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6893 SelectPostLoadLane(
Node, 2, AArch64::LD2i16_POST);
6895 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6897 SelectPostLoadLane(
Node, 2, AArch64::LD2i32_POST);
6899 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6901 SelectPostLoadLane(
Node, 2, AArch64::LD2i64_POST);
6907 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6908 SelectPostLoadLane(
Node, 3, AArch64::LD3i8_POST);
6910 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6911 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6912 SelectPostLoadLane(
Node, 3, AArch64::LD3i16_POST);
6914 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6916 SelectPostLoadLane(
Node, 3, AArch64::LD3i32_POST);
6918 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6920 SelectPostLoadLane(
Node, 3, AArch64::LD3i64_POST);
6926 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6927 SelectPostLoadLane(
Node, 4, AArch64::LD4i8_POST);
6929 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6930 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6931 SelectPostLoadLane(
Node, 4, AArch64::LD4i16_POST);
6933 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6935 SelectPostLoadLane(
Node, 4, AArch64::LD4i32_POST);
6937 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6939 SelectPostLoadLane(
Node, 4, AArch64::LD4i64_POST);
6945 VT =
Node->getOperand(1).getValueType();
6946 if (VT == MVT::v8i8) {
6947 SelectPostStore(
Node, 2, AArch64::ST2Twov8b_POST);
6949 }
else if (VT == MVT::v16i8) {
6950 SelectPostStore(
Node, 2, AArch64::ST2Twov16b_POST);
6952 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6953 SelectPostStore(
Node, 2, AArch64::ST2Twov4h_POST);
6955 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6956 SelectPostStore(
Node, 2, AArch64::ST2Twov8h_POST);
6958 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6959 SelectPostStore(
Node, 2, AArch64::ST2Twov2s_POST);
6961 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6962 SelectPostStore(
Node, 2, AArch64::ST2Twov4s_POST);
6964 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6965 SelectPostStore(
Node, 2, AArch64::ST2Twov2d_POST);
6967 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6968 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
6974 VT =
Node->getOperand(1).getValueType();
6975 if (VT == MVT::v8i8) {
6976 SelectPostStore(
Node, 3, AArch64::ST3Threev8b_POST);
6978 }
else if (VT == MVT::v16i8) {
6979 SelectPostStore(
Node, 3, AArch64::ST3Threev16b_POST);
6981 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6982 SelectPostStore(
Node, 3, AArch64::ST3Threev4h_POST);
6984 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6985 SelectPostStore(
Node, 3, AArch64::ST3Threev8h_POST);
6987 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6988 SelectPostStore(
Node, 3, AArch64::ST3Threev2s_POST);
6990 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6991 SelectPostStore(
Node, 3, AArch64::ST3Threev4s_POST);
6993 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6994 SelectPostStore(
Node, 3, AArch64::ST3Threev2d_POST);
6996 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6997 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7003 VT =
Node->getOperand(1).getValueType();
7004 if (VT == MVT::v8i8) {
7005 SelectPostStore(
Node, 4, AArch64::ST4Fourv8b_POST);
7007 }
else if (VT == MVT::v16i8) {
7008 SelectPostStore(
Node, 4, AArch64::ST4Fourv16b_POST);
7010 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7011 SelectPostStore(
Node, 4, AArch64::ST4Fourv4h_POST);
7013 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7014 SelectPostStore(
Node, 4, AArch64::ST4Fourv8h_POST);
7016 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7017 SelectPostStore(
Node, 4, AArch64::ST4Fourv2s_POST);
7019 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7020 SelectPostStore(
Node, 4, AArch64::ST4Fourv4s_POST);
7022 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7023 SelectPostStore(
Node, 4, AArch64::ST4Fourv2d_POST);
7025 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7026 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7032 VT =
Node->getOperand(1).getValueType();
7033 if (VT == MVT::v8i8) {
7034 SelectPostStore(
Node, 2, AArch64::ST1Twov8b_POST);
7036 }
else if (VT == MVT::v16i8) {
7037 SelectPostStore(
Node, 2, AArch64::ST1Twov16b_POST);
7039 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7040 SelectPostStore(
Node, 2, AArch64::ST1Twov4h_POST);
7042 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7043 SelectPostStore(
Node, 2, AArch64::ST1Twov8h_POST);
7045 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7046 SelectPostStore(
Node, 2, AArch64::ST1Twov2s_POST);
7048 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7049 SelectPostStore(
Node, 2, AArch64::ST1Twov4s_POST);
7051 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7052 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7054 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7055 SelectPostStore(
Node, 2, AArch64::ST1Twov2d_POST);
7061 VT =
Node->getOperand(1).getValueType();
7062 if (VT == MVT::v8i8) {
7063 SelectPostStore(
Node, 3, AArch64::ST1Threev8b_POST);
7065 }
else if (VT == MVT::v16i8) {
7066 SelectPostStore(
Node, 3, AArch64::ST1Threev16b_POST);
7068 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7069 SelectPostStore(
Node, 3, AArch64::ST1Threev4h_POST);
7071 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7072 SelectPostStore(
Node, 3, AArch64::ST1Threev8h_POST);
7074 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7075 SelectPostStore(
Node, 3, AArch64::ST1Threev2s_POST);
7077 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7078 SelectPostStore(
Node, 3, AArch64::ST1Threev4s_POST);
7080 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7081 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7083 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7084 SelectPostStore(
Node, 3, AArch64::ST1Threev2d_POST);
7090 VT =
Node->getOperand(1).getValueType();
7091 if (VT == MVT::v8i8) {
7092 SelectPostStore(
Node, 4, AArch64::ST1Fourv8b_POST);
7094 }
else if (VT == MVT::v16i8) {
7095 SelectPostStore(
Node, 4, AArch64::ST1Fourv16b_POST);
7097 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7098 SelectPostStore(
Node, 4, AArch64::ST1Fourv4h_POST);
7100 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7101 SelectPostStore(
Node, 4, AArch64::ST1Fourv8h_POST);
7103 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7104 SelectPostStore(
Node, 4, AArch64::ST1Fourv2s_POST);
7106 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7107 SelectPostStore(
Node, 4, AArch64::ST1Fourv4s_POST);
7109 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7110 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7112 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7113 SelectPostStore(
Node, 4, AArch64::ST1Fourv2d_POST);
7119 VT =
Node->getOperand(1).getValueType();
7120 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7121 SelectPostStoreLane(
Node, 2, AArch64::ST2i8_POST);
7123 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7124 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7125 SelectPostStoreLane(
Node, 2, AArch64::ST2i16_POST);
7127 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7129 SelectPostStoreLane(
Node, 2, AArch64::ST2i32_POST);
7131 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7133 SelectPostStoreLane(
Node, 2, AArch64::ST2i64_POST);
7139 VT =
Node->getOperand(1).getValueType();
7140 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7141 SelectPostStoreLane(
Node, 3, AArch64::ST3i8_POST);
7143 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7144 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7145 SelectPostStoreLane(
Node, 3, AArch64::ST3i16_POST);
7147 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7149 SelectPostStoreLane(
Node, 3, AArch64::ST3i32_POST);
7151 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7153 SelectPostStoreLane(
Node, 3, AArch64::ST3i64_POST);
7159 VT =
Node->getOperand(1).getValueType();
7160 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7161 SelectPostStoreLane(
Node, 4, AArch64::ST4i8_POST);
7163 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7164 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7165 SelectPostStoreLane(
Node, 4, AArch64::ST4i16_POST);
7167 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7169 SelectPostStoreLane(
Node, 4, AArch64::ST4i32_POST);
7171 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7173 SelectPostStoreLane(
Node, 4, AArch64::ST4i64_POST);
7179 if (VT == MVT::nxv16i8) {
7180 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B);
7182 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7183 VT == MVT::nxv8bf16) {
7184 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H);
7186 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7187 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W);
7189 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7190 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D);
7196 if (VT == MVT::nxv16i8) {
7197 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B);
7199 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7200 VT == MVT::nxv8bf16) {
7201 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H);
7203 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7204 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W);
7206 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7207 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D);
7213 if (VT == MVT::nxv16i8) {
7214 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B);
7216 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7217 VT == MVT::nxv8bf16) {
7218 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H);
7220 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7221 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W);
7223 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7224 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D);
7239 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7251 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7255 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7256 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7270 if (isa<MemSDNode>(Root))
7271 return cast<MemSDNode>(Root)->getMemoryVT();
7273 if (isa<MemIntrinsicSDNode>(Root))
7274 return cast<MemIntrinsicSDNode>(Root)->getMemoryVT();
7276 const unsigned Opcode = Root->
getOpcode();
7284 return cast<VTSDNode>(Root->
getOperand(3))->getVT();
7286 return cast<VTSDNode>(Root->
getOperand(4))->getVT();
7306 case Intrinsic::aarch64_sme_ldr:
7307 case Intrinsic::aarch64_sme_str:
7308 return MVT::nxv16i8;
7309 case Intrinsic::aarch64_sve_prf:
7314 case Intrinsic::aarch64_sve_ld2_sret:
7315 case Intrinsic::aarch64_sve_ld2q_sret:
7318 case Intrinsic::aarch64_sve_st2q:
7321 case Intrinsic::aarch64_sve_ld3_sret:
7322 case Intrinsic::aarch64_sve_ld3q_sret:
7325 case Intrinsic::aarch64_sve_st3q:
7328 case Intrinsic::aarch64_sve_ld4_sret:
7329 case Intrinsic::aarch64_sve_ld4q_sret:
7332 case Intrinsic::aarch64_sve_st4q:
7335 case Intrinsic::aarch64_sve_ld1udq:
7336 case Intrinsic::aarch64_sve_st1dq:
7337 return EVT(MVT::nxv1i64);
7338 case Intrinsic::aarch64_sve_ld1uwq:
7339 case Intrinsic::aarch64_sve_st1wq:
7340 return EVT(MVT::nxv1i32);
7347template <
int64_t Min,
int64_t Max>
7348bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(
SDNode *Root,
SDValue N,
7356 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
7361 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7380 int64_t MulImm = cast<ConstantSDNode>(VScale.
getOperand(0))->getSExtValue();
7382 if ((MulImm % MemWidthBytes) != 0)
7385 int64_t
Offset = MulImm / MemWidthBytes;
7386 if (Offset < Min || Offset > Max)
7389 Base =
N.getOperand(0);
7391 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
7398 OffImm = CurDAG->getTargetConstant(
Offset,
SDLoc(
N), MVT::i64);
7404bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7422 if (
auto C = dyn_cast<ConstantSDNode>(RHS)) {
7423 int64_t ImmOff =
C->getSExtValue();
7424 unsigned Size = 1 << Scale;
7433 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7435 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
7445 if (
auto *
C = dyn_cast<ConstantSDNode>(ShiftRHS))
7446 if (
C->getZExtValue() == Scale) {
7455bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7462bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7463 EVT VT =
N.getValueType();
7467bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7471 if (CurDAG->isBaseWithConstantOffset(
N))
7472 if (
auto C = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
7473 int64_t ImmOff =
C->getSExtValue();
7474 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0))) {
7475 Base =
N.getOperand(0);
7476 Offset = CurDAG->getTargetConstant(ImmOff / Scale,
SDLoc(
N), MVT::i64);
7483 Offset = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static bool isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
support::ulittle16_t & Lo
support::ulittle16_t & Hi
DEMANGLE_DUMP_METHOD void dump() const
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool isLittleEndian() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
bool getExactInverse(APFloat *inv) const
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint8_t getStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
A description of a memory reference used in the backend.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
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 SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasOneUse() const
Return true if there is exactly one use of this value.
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
const SysReg * lookupSysRegByName(StringRef)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t &Encoding)
processLogicalImmediate - Determine if an immediate value can be encoded as the immediate operand of ...
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static constexpr unsigned SVEBitsPerBlock
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
@ Undef
Value of the register doesn't matter.
Not(const Pred &P) -> Not< Pred >
Reg
All possible values of the reg field in the ModR/M byte.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
CodeGenOptLevel
Code generation optimization level.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.