23#include "llvm/IR/IntrinsicsAArch64.h"
32#define DEBUG_TYPE "aarch64-isel"
33#define PASS_NAME "AArch64 Instruction Selection"
36#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
37#pragma inline_depth(0)
53 AArch64DAGToDAGISel() =
delete;
65 void PreprocessISelDAG()
override;
69 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
71 std::vector<SDValue> &OutOps)
override;
73 template <
signed Low,
signed High,
signed Scale>
76 template <
signed Low,
signed High>
84 return SelectShiftedRegister(
N,
false,
Reg, Shift);
87 return SelectShiftedRegister(
N,
true,
Reg, Shift);
90 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
93 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
96 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
99 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
102 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
105 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
108 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
111 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
114 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
117 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
120 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
123 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
126 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
129 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
132 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
135 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
138 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
140 template <
unsigned Size,
unsigned Max>
144 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
147 int64_t
C = CI->getSExtValue();
155 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
162 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
168 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
173 N =
N->getOperand(0);
177 EVT VT =
N->getValueType(0);
178 EVT LVT =
N->getOperand(0).getValueType();
179 unsigned Index =
N->getConstantOperandVal(1);
183 Res =
N->getOperand(0);
188 if (
N.getOpcode() != AArch64ISD::VLSHR)
191 EVT VT =
Op.getValueType();
192 unsigned ShtAmt =
N->getConstantOperandVal(1);
197 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
199 Op.getOperand(1).getConstantOperandVal(0)
200 <<
Op.getOperand(1).getConstantOperandVal(1));
201 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
204 Op.getOperand(1).getConstantOperandVal(0));
208 if (Imm != 1ULL << (ShtAmt - 1))
211 Res1 =
Op.getOperand(0);
212 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
216 bool SelectDupZeroOrUndef(
SDValue N) {
217 switch(
N->getOpcode()) {
220 case AArch64ISD::DUP:
222 auto Opnd0 =
N->getOperand(0);
236 bool SelectAny(
SDValue) {
return true; }
239 switch(
N->getOpcode()) {
240 case AArch64ISD::DUP:
242 auto Opnd0 =
N->getOperand(0);
254 template <MVT::SimpleValueType VT,
bool Negate>
256 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
259 template <MVT::SimpleValueType VT,
bool Negate>
261 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
264 template <MVT::SimpleValueType VT>
266 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
269 template <MVT::SimpleValueType VT,
bool Invert = false>
271 return SelectSVELogicalImm(
N, VT, Imm, Invert);
274 template <MVT::SimpleValueType VT>
276 return SelectSVEArithImm(
N, VT, Imm);
279 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
281 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
288 EVT EltVT =
N->getValueType(0).getVectorElementType();
289 return SelectSVEShiftImm(
N->getOperand(0), 1,
295 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
302 MulImm = 1LL << MulImm;
304 if ((MulImm % std::abs(Scale)) != 0)
308 if ((MulImm >= Min) && (MulImm <= Max)) {
309 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
316 template <
signed Max,
signed Scale>
323 if (MulImm >= 0 && MulImm <= Max) {
325 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
332 template <
unsigned BaseReg,
unsigned Max>
340 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
363 const unsigned SubRegs[]);
365 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
367 bool tryIndexedLoad(
SDNode *
N);
369 void SelectPtrauthAuth(
SDNode *
N);
370 void SelectPtrauthResign(
SDNode *
N);
371 void SelectPtrauthResignWithPC(
SDNode *
N);
373 bool trySelectStackSlotTagP(
SDNode *
N);
376 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
380 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
381 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
382 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
383 unsigned Opc_rr,
unsigned Opc_ri,
384 bool IsIntr =
false);
385 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
386 unsigned Scale,
unsigned Opc_ri,
388 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
389 bool IsZmMulti,
unsigned Opcode,
390 bool HasPred =
false);
392 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
393 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
395 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
396 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
397 bool IsTupleInput,
unsigned Opc);
398 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
400 template <
unsigned MaxIdx,
unsigned Scale>
401 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
403 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
404 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
405 unsigned BaseReg = 0);
407 template <
int64_t Min,
int64_t Max>
411 template <
unsigned Scale>
413 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
416 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti6LaneX4(
SDNode *
Node,
unsigned NumIndexVecs);
420 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc,
423 template <
unsigned MaxIdx,
unsigned Scale>
428 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
430 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
431 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
432 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
433 unsigned Opc_rr,
unsigned Opc_ri);
434 std::tuple<unsigned, SDValue, SDValue>
435 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
439 bool tryBitfieldExtractOp(
SDNode *
N);
440 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
441 bool tryBitfieldInsertOp(
SDNode *
N);
442 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
443 bool tryShiftAmountMod(
SDNode *
N);
445 bool tryReadRegister(
SDNode *
N);
446 bool tryWriteRegister(
SDNode *
N);
448 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
449 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
456#include "AArch64GenDAGISel.inc"
464 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
466 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
479 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
480 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
481 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
484 template<
unsigned RegW
idth>
486 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
488 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
490 template <
unsigned RegW
idth>
492 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
494 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
496 template<
unsigned RegW
idth>
498 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
504 template <
unsigned FloatW
idth>
506 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
512 bool SelectCMP_SWAP(
SDNode *
N);
531 bool AllowSaturation,
SDValue &Imm);
539 bool SelectAllActivePredicate(
SDValue N);
544 template <
bool MatchCBB>
554 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
558char AArch64DAGToDAGISelLegacy::ID = 0;
564 std::make_unique<AArch64DAGToDAGISel>(TM, TM.getOptLevel())) {}
570 auto getFloatVT = [&](
EVT VT) {
572 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
573 return VT.changeElementType(*(DAG.
getContext()),
574 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
579 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
580 auto bitcasted = DAG.
getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
584 EVT OrigVT =
N.getValueType(0);
593 Imm =
C->getZExtValue();
610 return N->getOpcode() ==
Opc &&
621 return Imm == ImmExpected;
626 assert(RegWidth == 32 || RegWidth == 64);
628 return APInt(RegWidth,
635 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
636 if (
N->getOpcode() == AArch64ISD::NVCAST)
637 N =
N->getOperand(0);
638 unsigned SplatWidth =
N.getScalarValueSizeInBits();
639 if (
N.getOpcode() == AArch64ISD::FMOV)
641 if (
N->getOpcode() == AArch64ISD::MOVI)
642 return APInt(SplatWidth,
N.getConstantOperandVal(0));
643 if (
N->getOpcode() == AArch64ISD::MOVIshift)
644 return APInt(SplatWidth,
N.getConstantOperandVal(0)
645 <<
N.getConstantOperandVal(1));
646 if (
N->getOpcode() == AArch64ISD::MVNIshift)
647 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
648 <<
N.getConstantOperandVal(1));
649 if (
N->getOpcode() == AArch64ISD::MOVIedit)
651 N.getConstantOperandVal(0)));
652 if (
N->getOpcode() == AArch64ISD::DUP)
654 return Const->getAPIntValue().trunc(SplatWidth);
663 unsigned SplatWidth =
N.getScalarValueSizeInBits();
665 if (SplatVal->getBitWidth() <= SplatWidth)
667 if (SplatVal->isSplat(SplatWidth))
668 return SplatVal->trunc(SplatWidth);
673bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
680 ImmVal->getZExtValue(), Encoding))
683 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
687bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
690 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
691 N.getValueType().getScalarType().getSimpleVT(),
697bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
700 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
704bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
706 std::vector<SDValue> &OutOps) {
707 switch(ConstraintID) {
710 case InlineAsm::ConstraintCode::m:
711 case InlineAsm::ConstraintCode::o:
712 case InlineAsm::ConstraintCode::Q:
718 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
720 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
721 dl,
Op.getValueType(),
723 OutOps.push_back(NewOp);
742 uint64_t Immed =
N.getNode()->getAsZExtVal();
752 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
753 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
770 uint64_t Immed =
N.getNode()->getAsZExtVal();
778 if (
N.getValueType() == MVT::i32)
779 Immed = ~((uint32_t)Immed) + 1;
781 Immed = ~Immed + 1ULL;
782 if (Immed & 0xFFFFFFFFFF000000ULL)
785 Immed &= 0xFFFFFFULL;
786 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
793 switch (
N.getOpcode()) {
819 unsigned ShiftVal = CSD->getZExtValue();
837bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
840 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
845 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
869 EVT VT =
N.getValueType();
870 if (VT != MVT::i32 && VT != MVT::i64)
873 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
879 unsigned LHSOpcode =
LHS->getOpcode();
893 unsigned LowZBits, MaskLen;
897 unsigned BitWidth =
N.getValueSizeInBits();
904 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
907 NewShiftC = LowZBits - ShiftAmtC;
908 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
914 NewShiftC = LowZBits + ShiftAmtC;
927 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
929 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
933 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
935 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
936 NewShiftAmt, BitWidthMinus1),
939 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
953 SrcVT =
N.getOperand(0).getValueType();
955 if (!IsLoadStore && SrcVT == MVT::i8)
957 else if (!IsLoadStore && SrcVT == MVT::i16)
959 else if (SrcVT == MVT::i32)
961 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
966 EVT SrcVT =
N.getOperand(0).getValueType();
967 if (!IsLoadStore && SrcVT == MVT::i8)
969 else if (!IsLoadStore && SrcVT == MVT::i16)
971 else if (SrcVT == MVT::i32)
973 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
1001bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
1004 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1009 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1010 V.getConstantOperandVal(1) <= 4 &&
1023bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
1025 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1035 unsigned BitSize =
N.getValueSizeInBits();
1036 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1039 Reg =
N.getOperand(0);
1040 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1041 return isWorthFoldingALU(
N,
true);
1052 if (
N.getValueType() == MVT::i32)
1060template<
signed Low,
signed High,
signed Scale>
1066 if ((MulImm % std::abs(Scale)) == 0) {
1067 int64_t RDVLImm = MulImm / Scale;
1068 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1069 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1078template <
signed Low,
signed High>
1079bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1084 if (MulImm >=
Low && MulImm <=
High) {
1085 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1096 unsigned ShiftVal = 0;
1111 Reg =
N.getOperand(0).getOperand(0);
1123 Op =
Op->getOperand(0);
1125 Op.getOperand(0).getValueType().isFixedLengthVector())
1129 Reg =
N.getOperand(0);
1134 unsigned Opc =
N.getOpcode();
1152 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1154 return isWorthFoldingALU(
N);
1161 unsigned ShiftVal = 0;
1175 Reg =
N.getOperand(0);
1176 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1178 return isWorthFoldingALU(
N);
1187 for (
auto *
User :
N->users()) {
1214bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1215 unsigned BW,
unsigned Size,
1219 const DataLayout &
DL = CurDAG->getDataLayout();
1220 const TargetLowering *TLI = getTargetLowering();
1224 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1230 if (CurDAG->isBaseWithConstantOffset(
N)) {
1233 int64_t RHSC =
RHS->getSExtValue();
1235 int64_t
Range = 0x1LL << (BW - 1);
1237 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1238 RHSC < (
Range << Scale)) {
1239 Base =
N.getOperand(0);
1244 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1249 uint64_t RHSC =
RHS->getZExtValue();
1251 uint64_t
Range = 0x1ULL << BW;
1253 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1254 Base =
N.getOperand(0);
1259 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1270 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1277bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1280 const DataLayout &
DL = CurDAG->getDataLayout();
1281 const TargetLowering *TLI = getTargetLowering();
1285 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1290 GlobalAddressSDNode *GAN =
1292 Base =
N.getOperand(0);
1302 if (CurDAG->isBaseWithConstantOffset(
N)) {
1304 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1307 Base =
N.getOperand(0);
1312 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1320 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1328 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1337bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1340 if (!CurDAG->isBaseWithConstantOffset(
N))
1343 int64_t RHSC =
RHS->getSExtValue();
1344 if (RHSC >= -256 && RHSC < 256) {
1345 Base =
N.getOperand(0);
1348 const TargetLowering *TLI = getTargetLowering();
1349 Base = CurDAG->getTargetFrameIndex(
1352 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1362 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1369bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1389 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1395 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1398 return isWorthFoldingAddr(
N,
Size);
1401bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1419 const SDNode *
Node =
N.getNode();
1420 for (SDNode *UI :
Node->users()) {
1426 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1429 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1432 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1437 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1440 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1445 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1449 if (IsExtendedRegisterWorthFolding &&
1456 if (isWorthFoldingAddr(
LHS,
Size))
1461 if (IsExtendedRegisterWorthFolding &&
1468 if (isWorthFoldingAddr(
RHS,
Size))
1480 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1483 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1485 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1486 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1490bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1503 const SDNode *
Node =
N.getNode();
1504 for (SDNode *UI :
Node->users()) {
1521 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1531 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1538 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1541 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1544 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1549 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1552 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1559 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1560 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1566 static const unsigned RegClassIDs[] = {
1567 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1568 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1569 AArch64::dsub2, AArch64::dsub3};
1575 static const unsigned RegClassIDs[] = {
1576 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1577 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1578 AArch64::qsub2, AArch64::qsub3};
1584 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1585 AArch64::ZPR3RegClassID,
1586 AArch64::ZPR4RegClassID};
1587 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1588 AArch64::zsub2, AArch64::zsub3};
1598 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1599 AArch64::ZPR4Mul4RegClassID};
1600 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1601 AArch64::zsub2, AArch64::zsub3};
1606 const unsigned RegClassIDs[],
1607 const unsigned SubRegs[]) {
1610 if (Regs.
size() == 1)
1621 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1624 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1625 Ops.push_back(Regs[i]);
1626 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1630 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1634void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1637 EVT VT =
N->getValueType(0);
1639 unsigned ExtOff = isExt;
1642 unsigned Vec0Off = ExtOff + 1;
1648 Ops.push_back(
N->getOperand(1));
1649 Ops.push_back(RegSeq);
1650 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1651 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1654static std::tuple<SDValue, SDValue>
1675 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1680 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1682 return std::make_tuple(
1687void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1692 SDValue AUTDisc =
N->getOperand(3);
1695 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1697 SDValue AUTAddrDisc, AUTConstDisc;
1698 std::tie(AUTConstDisc, AUTAddrDisc) =
1702 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1704 if (
N->getNumOperands() > 4)
1705 Ops.push_back(
N->getOperand(4));
1708 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1709 ReplaceNode(
N, AUT);
1711 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1712 AArch64::X16, Val,
SDValue());
1715 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1716 ReplaceNode(
N, AUT);
1720void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1730 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1735 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1736 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1738 SDValue AUTAddrDisc, AUTConstDisc;
1739 std::tie(AUTConstDisc, AUTAddrDisc) =
1742 SDValue PACAddrDisc, PACConstDisc;
1743 std::tie(PACConstDisc, PACAddrDisc) =
1746 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1747 AArch64::X16, Val,
SDValue());
1750 SDValue Addend =
N->getOperand(OffsetBase + 6);
1751 SDValue IncomingChain =
N->getOperand(0);
1752 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1753 PACKey, PACConstDisc, PACAddrDisc,
1754 Addend, IncomingChain, X16Copy.
getValue(1)};
1756 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1757 MVT::i64, MVT::Other,
Ops);
1758 ReplaceNode(
N, AUTRELLOADPAC);
1760 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1761 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1763 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1764 ReplaceNode(
N, AUTPAC);
1768void AArch64DAGToDAGISel::SelectPtrauthResignWithPC(SDNode *
N) {
1780 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1781 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1783 SDValue PACAddrDisc, PACConstDisc;
1784 std::tie(PACConstDisc, PACAddrDisc) =
1787 SDValue X17Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1788 AArch64::X17, Val,
SDValue());
1789 SDValue X16Copy = CurDAG->getCopyToReg(
1790 CurDAG->getEntryNode(),
DL, AArch64::X16, AUTDisc, X17Copy.
getValue(1));
1791 SDValue X15Copy = CurDAG->getCopyToReg(
1792 CurDAG->getEntryNode(),
DL, AArch64::X15, AUTPC, X16Copy.
getValue(1));
1794 SDValue Ops[] = {AUTKey, PACKey, PACConstDisc, PACAddrDisc,
1797 CurDAG->getMachineNode(AArch64::AUTPCPAC,
DL, MVT::i64,
Ops);
1798 ReplaceNode(
N, AUTPCPAC);
1801bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1803 if (
LD->isUnindexed())
1805 EVT VT =
LD->getMemoryVT();
1806 EVT DstVT =
N->getValueType(0);
1810 int OffsetVal = (int)
OffsetOp->getZExtValue();
1815 unsigned Opcode = 0;
1818 bool InsertTo64 =
false;
1820 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1821 else if (VT == MVT::i32) {
1823 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1825 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1827 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1833 }
else if (VT == MVT::i16) {
1835 if (DstVT == MVT::i64)
1836 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1838 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1840 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1841 InsertTo64 = DstVT == MVT::i64;
1846 }
else if (VT == MVT::i8) {
1848 if (DstVT == MVT::i64)
1849 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1851 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1853 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1854 InsertTo64 = DstVT == MVT::i64;
1859 }
else if (VT == MVT::f16) {
1860 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1861 }
else if (VT == MVT::bf16) {
1862 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1863 }
else if (VT == MVT::f32) {
1864 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1865 }
else if (VT == MVT::f64 ||
1867 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1869 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1871 if (IsPre || OffsetVal != 8)
1875 Opcode = AArch64::LD1Onev8b_POST;
1878 Opcode = AArch64::LD1Onev4h_POST;
1881 Opcode = AArch64::LD1Onev2s_POST;
1884 Opcode = AArch64::LD1Onev1d_POST;
1890 if (IsPre || OffsetVal != 16)
1894 Opcode = AArch64::LD1Onev16b_POST;
1897 Opcode = AArch64::LD1Onev8h_POST;
1900 Opcode = AArch64::LD1Onev4s_POST;
1903 Opcode = AArch64::LD1Onev2d_POST;
1915 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1916 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1918 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1928 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1929 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1930 MVT::i64, LoadedVal, SubReg),
1934 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1937 CurDAG->RemoveDeadNode(
N);
1941void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1942 unsigned SubRegIdx) {
1944 EVT VT =
N->getValueType(0);
1950 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1952 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1954 for (
unsigned i = 0; i < NumVecs; ++i)
1956 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1963 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1967 CurDAG->RemoveDeadNode(
N);
1970void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1971 unsigned Opc,
unsigned SubRegIdx) {
1973 EVT VT =
N->getValueType(0);
1980 const EVT ResTys[] = {MVT::i64,
1981 MVT::Untyped, MVT::Other};
1983 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1991 ReplaceUses(
SDValue(
N, 0), SuperReg);
1993 for (
unsigned i = 0; i < NumVecs; ++i)
1995 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
2003 CurDAG->RemoveDeadNode(
N);
2009std::tuple<unsigned, SDValue, SDValue>
2010AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
2016 SDValue NewOffset = OldOffset;
2018 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
2019 N, OldBase, NewBase, NewOffset);
2023 const bool IsRegReg =
2024 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
2027 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
2040template <SelectTypeKind Kind>
2052 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2057 if (EltVT != MVT::i1)
2061 if (EltVT == MVT::bf16)
2063 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2093void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2096 if (
Imm->getZExtValue() > 1)
2100 EVT VT =
N->getValueType(0);
2102 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2105 for (
unsigned I = 0;
I < 2; ++
I)
2106 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2107 AArch64::psub0 +
I,
DL, VT, SuperReg));
2109 CurDAG->RemoveDeadNode(
N);
2112void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2114 EVT VT =
N->getValueType(0);
2118 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2121 for (
unsigned I = 0;
I < 2; ++
I)
2122 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2123 AArch64::psub0 +
I,
DL, VT, SuperReg));
2125 CurDAG->RemoveDeadNode(
N);
2128void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2130 EVT VT =
N->getValueType(0);
2134 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2136 for (
unsigned i = 0; i < NumVecs; ++i)
2137 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2138 AArch64::zsub0 + i,
DL, VT, SuperReg));
2140 CurDAG->RemoveDeadNode(
N);
2143void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2146 EVT VT =
N->getValueType(0);
2148 Ops.push_back(
N->getOperand(0));
2151 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2154 for (
unsigned i = 0; i < NumVecs; ++i)
2155 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2156 AArch64::zsub0 + i,
DL, VT, SuperReg));
2159 unsigned ChainIdx = NumVecs;
2161 CurDAG->RemoveDeadNode(
N);
2164void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2169 assert(Opcode != 0 &&
"Unexpected opcode");
2172 EVT VT =
N->getValueType(0);
2173 SDUse *OpsIter =
N->op_begin() + 1;
2176 auto GetMultiVecOperand = [&]() {
2179 return createZMulTuple(Regs);
2183 Ops.push_back(*OpsIter++);
2185 Ops.push_back(GetMultiVecOperand());
2187 Ops.push_back(GetMultiVecOperand());
2189 Ops.push_back(*OpsIter++);
2192 Ops.append(OpsIter,
N->op_end());
2194 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2196 for (
unsigned i = 0; i < NumVecs; ++i)
2197 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2198 AArch64::zsub0 + i,
DL, VT, SuperReg));
2200 CurDAG->RemoveDeadNode(
N);
2203void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2204 unsigned Scale,
unsigned Opc_ri,
2205 unsigned Opc_rr,
bool IsIntr) {
2206 assert(Scale < 5 &&
"Invalid scaling value.");
2208 EVT VT =
N->getValueType(0);
2215 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2216 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2222 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2224 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2226 for (
unsigned i = 0; i < NumVecs; ++i)
2227 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2228 AArch64::zsub0 + i,
DL, VT, SuperReg));
2231 unsigned ChainIdx = NumVecs;
2233 CurDAG->RemoveDeadNode(
N);
2236void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2241 assert(Scale < 4 &&
"Invalid scaling value.");
2243 EVT VT =
N->getValueType(0);
2251 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2257 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2259 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2261 for (
unsigned i = 0; i < NumVecs; ++i)
2262 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2263 AArch64::zsub0 + i,
DL, VT, SuperReg));
2266 unsigned ChainIdx = NumVecs;
2268 CurDAG->RemoveDeadNode(
N);
2271void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2273 if (
N->getValueType(0) != MVT::nxv4f32)
2275 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2278void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2279 unsigned NumOutVecs,
2283 if (
Imm->getZExtValue() > MaxImm)
2287 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2293 EVT VT =
Node->getValueType(0);
2296 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2299 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2300 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2301 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2304 unsigned ChainIdx = NumOutVecs;
2306 CurDAG->RemoveDeadNode(Node);
2309void AArch64DAGToDAGISel::SelectMultiVectorLuti6LaneX4(SDNode *Node,
2310 unsigned NumIndexVecs) {
2311 assert((NumIndexVecs == 2 || NumIndexVecs == 3) &&
2312 "unexpected number of index vectors");
2314 constexpr unsigned FirstIndexOp = 3;
2315 unsigned ImmOp = FirstIndexOp + NumIndexVecs;
2317 if (!Imm ||
Imm->getZExtValue() > 1)
2323 unsigned Lane =
Imm->getZExtValue();
2324 unsigned IndexOp = FirstIndexOp;
2325 if (NumIndexVecs == 3)
2328 SDValue TableTuple = createZTuple({
Node->getOperand(1),
Node->getOperand(2)});
2330 createZTuple({
Node->getOperand(IndexOp),
Node->getOperand(IndexOp + 1)});
2331 SDValue Ops[] = {TableTuple, IndexTuple,
Node->getOperand(ImmOp)};
2334 EVT VT =
Node->getValueType(0);
2336 CurDAG->getMachineNode(AArch64::LUTI6_4Z2Z2ZI,
DL, MVT::Untyped,
Ops);
2339 for (
unsigned I = 0;
I < 4; ++
I)
2340 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2341 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2343 CurDAG->RemoveDeadNode(Node);
2346void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2347 unsigned NumOutVecs,
2349 unsigned NumInVecs) {
2350 assert((NumInVecs == 2 || NumInVecs == 3) &&
2351 "unexpected number of input vectors");
2354 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2358 SDValue ZTuple = NumInVecs == 3 ? createZTuple(Regs) : createZMulTuple(Regs);
2362 EVT VT =
Node->getValueType(0);
2365 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2368 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2369 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2370 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2373 CurDAG->RemoveDeadNode(Node);
2376void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2379 EVT VT =
N->getValueType(0);
2382 SDValue Zd = createZMulTuple(Regs);
2383 SDValue Zn =
N->getOperand(1 + NumVecs);
2384 SDValue Zm =
N->getOperand(2 + NumVecs);
2390 for (
unsigned i = 0; i < NumVecs; ++i)
2391 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2392 AArch64::zsub0 + i,
DL, VT, SuperReg));
2394 CurDAG->RemoveDeadNode(
N);
2424template <
unsigned MaxIdx,
unsigned Scale>
2425void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2426 unsigned BaseReg,
unsigned Op) {
2427 unsigned TileNum = 0;
2428 if (BaseReg != AArch64::ZA)
2429 TileNum =
N->getConstantOperandVal(2);
2435 if (BaseReg == AArch64::ZA)
2440 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2444 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2446 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2448 EVT VT =
N->getValueType(0);
2449 for (
unsigned I = 0;
I < NumVecs; ++
I)
2451 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2454 unsigned ChainIdx = NumVecs;
2456 CurDAG->RemoveDeadNode(
N);
2459void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2460 unsigned Op,
unsigned MaxIdx,
2461 unsigned Scale,
unsigned BaseReg) {
2466 if (BaseReg != AArch64::ZA)
2470 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2477 if (BaseReg != AArch64::ZA )
2478 Ops.push_back(
N->getOperand(2));
2481 Ops.push_back(
N->getOperand(0));
2482 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2484 EVT VT =
N->getValueType(0);
2485 for (
unsigned I = 0;
I < NumVecs; ++
I)
2487 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2491 unsigned ChainIdx = NumVecs;
2493 CurDAG->RemoveDeadNode(
N);
2496void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2497 unsigned NumOutVecs,
2501 EVT VT =
N->getValueType(0);
2502 unsigned NumInVecs =
N->getNumOperands() - 1;
2506 assert((NumInVecs == 2 || NumInVecs == 4) &&
2507 "Don't know how to handle multi-register input!");
2509 Ops.push_back(createZMulTuple(Regs));
2512 for (
unsigned I = 0;
I < NumInVecs;
I++)
2513 Ops.push_back(
N->getOperand(1 +
I));
2516 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2519 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2520 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2521 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2522 CurDAG->RemoveDeadNode(
N);
2525void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2528 EVT VT =
N->getOperand(2)->getValueType(0);
2536 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2545void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2546 unsigned Scale,
unsigned Opc_rr,
2552 SDValue RegSeq = createZTuple(Regs);
2558 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2559 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2565 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2570void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2573 EVT VT =
N->getOperand(2)->getValueType(0);
2574 const EVT ResTys[] = {MVT::i64,
2586 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2630void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2633 EVT VT =
N->getValueType(0);
2645 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2647 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2649 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2651 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2655 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2656 AArch64::qsub2, AArch64::qsub3 };
2657 for (
unsigned i = 0; i < NumVecs; ++i) {
2658 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2665 CurDAG->RemoveDeadNode(
N);
2668void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2671 EVT VT =
N->getValueType(0);
2683 const EVT ResTys[] = {MVT::i64,
2686 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2689 CurDAG->getTargetConstant(LaneNo, dl,
2694 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2706 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2707 AArch64::qsub2, AArch64::qsub3 };
2708 for (
unsigned i = 0; i < NumVecs; ++i) {
2709 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2719 CurDAG->RemoveDeadNode(
N);
2722void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2725 EVT VT =
N->getOperand(2)->getValueType(0);
2737 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2739 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2741 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2750void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2753 EVT VT =
N->getOperand(2)->getValueType(0);
2765 const EVT ResTys[] = {MVT::i64,
2768 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2770 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2774 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2785 unsigned &LSB,
unsigned &MSB,
2786 unsigned NumberOfIgnoredLowBits,
2787 bool BiggerPattern) {
2789 "N must be a AND operation to call this function");
2791 EVT VT =
N->getValueType(0);
2796 assert((VT == MVT::i32 || VT == MVT::i64) &&
2797 "Type checking must have been done before calling this function");
2811 const SDNode *Op0 =
N->getOperand(0).getNode();
2818 if (AndImm & (AndImm + 1))
2821 bool ClampMSB =
false;
2841 ClampMSB = (VT == MVT::i32);
2842 }
else if (BiggerPattern) {
2848 Opd0 =
N->getOperand(0);
2854 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2857 <<
": Found large shift immediate, this should not happen\n"));
2871 MSB = MSB > 31 ? 31 : MSB;
2873 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2878 SDValue &Opd0,
unsigned &Immr,
2882 EVT VT =
N->getValueType(0);
2884 assert((VT == MVT::i32 || VT == MVT::i64) &&
2885 "Type checking must have been done before calling this function");
2889 Op =
Op->getOperand(0);
2890 VT =
Op->getValueType(0);
2899 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2903 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2904 Opd0 =
Op.getOperand(0);
2906 Imms = ShiftImm + Width - 1;
2934 Opd0 =
N->getOperand(0).getOperand(0);
2944 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2951 unsigned &Immr,
unsigned &Imms,
2952 bool BiggerPattern) {
2954 "N must be a SHR/SRA operation to call this function");
2956 EVT VT =
N->getValueType(0);
2961 assert((VT == MVT::i32 || VT == MVT::i64) &&
2962 "Type checking must have been done before calling this function");
2972 Opd0 =
N->getOperand(0).getOperand(0);
2973 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2979 Opd0 =
N->getOperand(0).getOperand(0);
2982 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2983 }
else if (BiggerPattern) {
2987 Opd0 =
N->getOperand(0);
2996 <<
": Found large shift immediate, this should not happen\n"));
3005 "bad amount in shift node!");
3006 int immr = SrlImm - ShlImm;
3011 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
3013 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
3017bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
3020 EVT VT =
N->getValueType(0);
3021 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
3022 if (VT != MVT::i64 || NarrowVT != MVT::i32)
3033 unsigned Immr = ShiftImm;
3035 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3036 CurDAG->getTargetConstant(Imms, dl, VT)};
3037 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
3042 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
3043 unsigned NumberOfIgnoredLowBits = 0,
3044 bool BiggerPattern =
false) {
3045 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
3048 switch (
N->getOpcode()) {
3050 if (!
N->isMachineOpcode())
3055 NumberOfIgnoredLowBits, BiggerPattern);
3064 unsigned NOpc =
N->getMachineOpcode();
3068 case AArch64::SBFMWri:
3069 case AArch64::UBFMWri:
3070 case AArch64::SBFMXri:
3071 case AArch64::UBFMXri:
3073 Opd0 =
N->getOperand(0);
3074 Immr =
N->getConstantOperandVal(1);
3075 Imms =
N->getConstantOperandVal(2);
3082bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3083 unsigned Opc, Immr, Imms;
3088 EVT VT =
N->getValueType(0);
3093 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3094 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3095 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3097 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3098 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3104 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3105 CurDAG->getTargetConstant(Imms, dl, VT)};
3106 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3115 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3116 assert((VT == MVT::i32 || VT == MVT::i64) &&
3117 "i32 or i64 mask type expected!");
3121 APInt SignificantDstMask =
3125 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3126 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3159 APInt OpUsefulBits(UsefulBits);
3163 OpUsefulBits <<= MSB - Imm + 1;
3168 OpUsefulBits <<= Imm;
3170 OpUsefulBits <<= MSB + 1;
3173 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3179 UsefulBits &= OpUsefulBits;
3196 APInt Mask(UsefulBits);
3197 Mask.clearAllBits();
3205 Mask.lshrInPlace(ShiftAmt);
3211 Mask.lshrInPlace(ShiftAmt);
3227 APInt OpUsefulBits(UsefulBits);
3241 OpUsefulBits <<= Width;
3244 if (
Op.getOperand(1) == Orig) {
3246 Mask = ResultUsefulBits & OpUsefulBits;
3250 if (
Op.getOperand(0) == Orig)
3252 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3258 OpUsefulBits <<= Width;
3260 OpUsefulBits <<= LSB;
3262 if (
Op.getOperand(1) == Orig) {
3264 Mask = ResultUsefulBits & OpUsefulBits;
3265 Mask.lshrInPlace(LSB);
3268 if (
Op.getOperand(0) == Orig)
3269 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3286 case AArch64::ANDSWri:
3287 case AArch64::ANDSXri:
3288 case AArch64::ANDWri:
3289 case AArch64::ANDXri:
3293 case AArch64::UBFMWri:
3294 case AArch64::UBFMXri:
3297 case AArch64::ORRWrs:
3298 case AArch64::ORRXrs:
3303 case AArch64::BFMWri:
3304 case AArch64::BFMXri:
3307 case AArch64::STRBBui:
3308 case AArch64::STURBBi:
3314 case AArch64::STRHHui:
3315 case AArch64::STURHHi:
3328 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3330 UsefulBits =
APInt(Bitwidth, 0);
3339 UsersUsefulBits |= UsefulBitsForUse;
3344 UsefulBits &= UsersUsefulBits;
3354 EVT VT =
Op.getValueType();
3357 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3360 if (ShlAmount > 0) {
3363 UBFMOpc, dl, VT,
Op,
3368 assert(ShlAmount < 0 &&
"expected right shift");
3369 int ShrAmount = -ShlAmount;
3381 const uint64_t NonZeroBits,
3388 const uint64_t NonZeroBits,
3395 bool BiggerPattern,
SDValue &Src,
3396 int &DstLSB,
int &Width) {
3397 EVT VT =
Op.getValueType();
3410 switch (
Op.getOpcode()) {
3415 NonZeroBits, Src, DstLSB, Width);
3418 NonZeroBits, Src, DstLSB, Width);
3431 EVT VT =
Op.getValueType();
3432 assert((VT == MVT::i32 || VT == MVT::i64) &&
3433 "Caller guarantees VT is one of i32 or i64");
3446 assert((~AndImm & NonZeroBits) == 0 &&
3447 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3476 if (!BiggerPattern && !AndOp0.
hasOneUse())
3495 <<
"Found large Width in bit-field-positioning -- this indicates no "
3496 "proper combining / constant folding was performed\n");
3505 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3520 "Op.getNode() should be a SHL node to call this function");
3522 "Op.getNode() should shift ShlImm to call this function");
3529 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3553 EVT VT =
Op.getValueType();
3554 assert((VT == MVT::i32 || VT == MVT::i64) &&
3555 "Caller guarantees that type is i32 or i64");
3562 if (!BiggerPattern && !
Op.hasOneUse())
3571 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3579 assert(VT == MVT::i32 || VT == MVT::i64);
3590 EVT VT =
N->getValueType(0);
3591 if (VT != MVT::i32 && VT != MVT::i64)
3609 if (!
And.hasOneUse() ||
3626 if ((OrImm & NotKnownZero) != 0) {
3638 unsigned ImmS = Width - 1;
3644 bool IsBFI = LSB != 0;
3649 unsigned OrChunks = 0, BFIChunks = 0;
3650 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3651 if (((OrImm >> Shift) & 0xFFFF) != 0)
3653 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3656 if (BFIChunks > OrChunks)
3662 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3670 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3679 if (!Dst.hasOneUse())
3682 EVT VT = Dst.getValueType();
3683 assert((VT == MVT::i32 || VT == MVT::i64) &&
3684 "Caller should guarantee that VT is one of i32 or i64");
3712 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3713 unsigned MaskWidth =
3716 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3722 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3723 ShiftedOperand =
SDValue(UBFMNode, 0);
3752 const bool BiggerPattern) {
3753 EVT VT =
N->getValueType(0);
3754 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3755 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3756 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3757 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3758 assert((VT == MVT::i32 || VT == MVT::i64) &&
3759 "Expect result type to be i32 or i64 since N is combinable to BFM");
3766 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3769 if (BiggerPattern) {
3792 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3854 EVT VT =
N->getValueType(0);
3855 if (VT != MVT::i32 && VT != MVT::i64)
3863 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3864 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3884 for (
int I = 0;
I < 4; ++
I) {
3887 unsigned ImmR, ImmS;
3888 bool BiggerPattern =
I / 2;
3889 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3891 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3897 NumberOfIgnoredLowBits, BiggerPattern)) {
3900 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3901 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3906 Width = ImmS - ImmR + 1;
3917 Src, DstLSB, Width)) {
3925 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3935 APInt BitsToBeInserted =
3938 if ((BitsToBeInserted & ~
Known.Zero) != 0)
3962 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3995 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3997 if (Src->hasOneUse() &&
4000 Src = Src->getOperand(0);
4010 unsigned ImmS = Width - 1;
4016 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
4024bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
4033 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
4046bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
4050 EVT VT =
N->getValueType(0);
4051 if (VT != MVT::i32 && VT != MVT::i64)
4057 Op0, DstLSB, Width))
4063 unsigned ImmS = Width - 1;
4066 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4067 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4068 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4069 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4075bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4076 EVT VT =
N->getValueType(0);
4079 switch (
N->getOpcode()) {
4081 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4084 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4087 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4090 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4098 if (VT == MVT::i32) {
4101 }
else if (VT == MVT::i64) {
4107 SDValue ShiftAmt =
N->getOperand(1);
4127 (Add0Imm %
Size == 0)) {
4133 if (SubVT == MVT::i32) {
4134 NegOpc = AArch64::SUBWrr;
4135 ZeroReg = AArch64::WZR;
4137 assert(SubVT == MVT::i64);
4138 NegOpc = AArch64::SUBXrr;
4139 ZeroReg = AArch64::XZR;
4142 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4143 MachineSDNode *Neg =
4144 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4145 NewShiftAmt =
SDValue(Neg, 0);
4153 if (SubVT == MVT::i32) {
4154 NotOpc = AArch64::ORNWrr;
4155 ZeroReg = AArch64::WZR;
4157 assert(SubVT == MVT::i64);
4158 NotOpc = AArch64::ORNXrr;
4159 ZeroReg = AArch64::XZR;
4162 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4163 MachineSDNode *
Not =
4164 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4165 NewShiftAmt =
SDValue(Not, 0);
4186 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4187 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4188 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4189 NewShiftAmt, SubReg);
4190 NewShiftAmt =
SDValue(Ext, 0);
4194 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4201 bool isReciprocal) {
4204 FVal = CN->getValueAPF();
4207 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4217 if (
unsigned FBits =
4230 bool isReciprocal) {
4231 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4232 N.getValueType().getScalarSizeInBits() ==
4233 N.getOperand(0).getValueType().getScalarSizeInBits())
4234 N =
N.getOperand(0);
4236 auto ImmToFloat = [RegWidth](
APInt Imm) {
4250 switch (
N->getOpcode()) {
4251 case AArch64ISD::MOVIshift:
4252 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4253 <<
N.getConstantOperandVal(1)));
4255 case AArch64ISD::FMOV:
4256 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4258 case AArch64ISD::DUP:
4260 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4268 if (
unsigned FBits =
4277bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4278 unsigned RegWidth) {
4283bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4284 unsigned RegWidth) {
4286 CurDAG,
N, FixedPos, RegWidth,
false);
4289bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(
SDValue N,
4291 unsigned RegWidth) {
4293 CurDAG,
N, FixedPos, RegWidth,
true);
4296bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4298 unsigned RegWidth) {
4308 RegString.
split(Fields,
':');
4310 if (Fields.
size() == 1)
4314 &&
"Invalid number of fields in read register string");
4317 bool AllIntFields =
true;
4321 AllIntFields &= !
Field.getAsInteger(10, IntField);
4322 Ops.push_back(IntField);
4326 "Unexpected non-integer value in special register string.");
4331 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) | (
Ops[3] << 3) |
4339bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4341 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4344 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4346 unsigned Opcode64Bit = AArch64::MRS;
4351 const auto *TheReg =
4352 AArch64SysReg::lookupSysRegByName(RegString->getString());
4353 if (TheReg && TheReg->Readable &&
4354 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4355 Imm = TheReg->Encoding;
4361 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4362 Opcode64Bit = AArch64::ADR;
4371 RegString->getString());
4372 unsigned PseudoOp = 0;
4373 if (AArch64::GPR64RegClass.
contains(PReg))
4374 PseudoOp = AArch64::READ_REGISTER_GPR64;
4375 else if (AArch64::FPR64RegClass.
contains(PReg))
4376 PseudoOp = AArch64::READ_REGISTER_FPR64;
4377 if (!ReadIs128Bit && PseudoOp &&
N->getValueType(0) == MVT::i64) {
4378 CurDAG->SelectNodeTo(
N, PseudoOp, MVT::i64, MVT::Other,
4379 {CurDAG->getTargetConstant(PReg,
DL, MVT::i32),
4388 SDValue InChain =
N->getOperand(0);
4389 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4390 if (!ReadIs128Bit) {
4391 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4392 {SysRegImm, InChain});
4394 SDNode *MRRS = CurDAG->getMachineNode(
4396 {MVT::Untyped , MVT::Other },
4397 {SysRegImm, InChain});
4401 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4403 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4409 ReplaceUses(
SDValue(
N, 2), OutChain);
4418bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4420 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4423 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4425 if (!WriteIs128Bit) {
4431 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4434 "Expected a constant integer expression.");
4435 unsigned Reg = PMapper->Encoding;
4436 uint64_t Immed =
N->getConstantOperandVal(2);
4437 CurDAG->SelectNodeTo(
4438 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4439 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4445 if (trySelectPState(
4446 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4447 AArch64::MSRpstateImm4))
4449 if (trySelectPState(
4450 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4451 AArch64::MSRpstateImm1))
4460 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4461 if (TheReg && TheReg->Writeable &&
4462 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4463 Imm = TheReg->Encoding;
4473 RegString->getString());
4474 bool IsGPR = AArch64::GPR64RegClass.contains(PReg);
4475 bool IsFPR = AArch64::FPR64RegClass.contains(PReg);
4476 if (!WriteIs128Bit && (IsGPR || IsFPR) &&
4477 N->getOperand(2).getValueType() == MVT::i64) {
4479 CurDAG->getCopyToReg(
N->getOperand(0),
DL, PReg,
N->getOperand(2));
4480 SDValue RegOp = CurDAG->getRegister(PReg, MVT::i64);
4481 SDNode *FakeUse = CurDAG->getMachineNode(TargetOpcode::FAKE_USE,
DL,
4482 MVT::Other, {RegOp,
Copy});
4484 CurDAG->RemoveDeadNode(
N);
4492 if (!WriteIs128Bit) {
4493 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4494 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4495 N->getOperand(2), InChain);
4499 SDNode *Pair = CurDAG->getMachineNode(
4500 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4501 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4504 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4506 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4508 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4509 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4517bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4522 if (Subtarget->hasLSE())
return false;
4524 if (MemTy == MVT::i8)
4525 Opcode = AArch64::CMP_SWAP_8;
4526 else if (MemTy == MVT::i16)
4527 Opcode = AArch64::CMP_SWAP_16;
4528 else if (MemTy == MVT::i32)
4529 Opcode = AArch64::CMP_SWAP_32;
4530 else if (MemTy == MVT::i64)
4531 Opcode = AArch64::CMP_SWAP_64;
4535 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4536 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4538 SDNode *CmpSwap = CurDAG->getMachineNode(
4540 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4547 CurDAG->RemoveDeadNode(
N);
4552bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4553 SDValue &Shift,
bool Negate) {
4560 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4563bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4572 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4579 if ((Val & ~0xff) == 0) {
4580 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4585 if ((Val & ~0xff00) == 0) {
4586 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4598bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4622 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4623 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4630 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4631 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4635 if (Val <= 65280 && Val % 256 == 0) {
4636 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4637 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4648bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4658 int32_t ImmVal, ShiftVal;
4663 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4664 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4668bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4670 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4674bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4677 if (ImmVal >= -128 && ImmVal < 128) {
4678 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4684bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4686 uint64_t ImmVal = CNode->getZExtValue();
4696 ImmVal &= 0xFFFFFFFF;
4705 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4712bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4716 ImmVal = CI->getZExtValue();
4718 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4729 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4738bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4739 uint64_t
High,
bool AllowSaturation,
4742 uint64_t ImmVal = CN->getZExtValue();
4749 if (ImmVal >
High) {
4750 if (!AllowSaturation)
4755 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4762bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4776 const TargetLowering *TLI = getTargetLowering();
4779 SDValue FiOp = CurDAG->getTargetFrameIndex(
4781 int TagOffset =
N->getConstantOperandVal(3);
4783 SDNode *Out = CurDAG->getMachineNode(
4784 AArch64::TAGPstack,
DL, MVT::i64,
4785 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4786 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4787 ReplaceNode(
N, Out);
4791void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4793 "llvm.aarch64.tagp third argument must be an immediate");
4794 if (trySelectStackSlotTagP(
N))
4801 int TagOffset =
N->getConstantOperandVal(3);
4802 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4803 {
N->getOperand(1),
N->getOperand(2)});
4804 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4805 {
SDValue(N1, 0),
N->getOperand(2)});
4806 SDNode *N3 = CurDAG->getMachineNode(
4807 AArch64::ADDG,
DL, MVT::i64,
4808 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4809 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4813bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4817 if (
N->getConstantOperandVal(2) != 0)
4819 if (!
N->getOperand(0).isUndef())
4823 EVT VT =
N->getValueType(0);
4824 EVT InVT =
N->getOperand(1).getValueType();
4835 "Expected to insert into a packed scalable vector!");
4838 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4839 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4840 N->getOperand(1), RC));
4844bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4848 if (
N->getConstantOperandVal(1) != 0)
4852 EVT VT =
N->getValueType(0);
4853 EVT InVT =
N->getOperand(0).getValueType();
4864 "Expected to extract from a packed scalable vector!");
4867 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4868 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4869 N->getOperand(0), RC));
4873bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4879 EVT VT =
N->getValueType(0);
4892 (Subtarget->hasSVE2() ||
4893 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4894 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4897 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4901 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4902 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4903 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4910 bool IsXOROperand =
true;
4912 IsXOROperand =
false;
4918 APInt ShlAmt, ShrAmt;
4926 if (!IsXOROperand) {
4928 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4931 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4932 SDNode *SubRegToReg =
4933 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4944 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4945 AArch64::XAR_ZZZI_D})) {
4946 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4971 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4981 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4989 bool IsXOROperand =
true;
4991 IsXOROperand =
false;
4994 R1 =
XOR.getOperand(0);
4995 R2 =
XOR.getOperand(1);
5005 if (ShAmt + HsAmt != VTSizeInBits)
5008 if (!IsXOROperand) {
5011 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
5020 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
5026 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
5027 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5029 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5032 if (
R2.getValueType() == VT)
5033 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5038 SDValue SubReg = CurDAG->getTargetConstant(
5041 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
5046 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
5052 SDNode *XAR =
nullptr;
5056 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
5057 AArch64::XAR_ZZZI_D}))
5058 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
5060 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
5063 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
5069 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
5070 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
5073 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5074 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5077 SDValue SubReg = CurDAG->getTargetConstant(
5080 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5084 ReplaceNode(
N, XAR);
5091 assert(VT == MVT::i32 || VT == MVT::i64);
5093 VT == MVT::i32 ? AArch64::WZR : AArch64::XZR, VT);
5096void AArch64DAGToDAGISel::Select(SDNode *Node) {
5098 if (
Node->isMachineOpcode()) {
5100 Node->setNodeId(-1);
5105 EVT VT =
Node->getValueType(0);
5107 switch (
Node->getOpcode()) {
5112 if (SelectCMP_SWAP(Node))
5117 case AArch64ISD::MRRS:
5118 if (tryReadRegister(Node))
5123 case AArch64ISD::MSRR:
5124 if (tryWriteRegister(Node))
5131 if (tryIndexedLoad(Node))
5140 if (tryBitfieldExtractOp(Node))
5142 if (tryBitfieldInsertInZeroOp(Node))
5147 if (tryShiftAmountMod(Node))
5152 if (tryBitfieldExtractOpFromSExt(Node))
5157 if (tryBitfieldInsertOp(Node))
5159 if (trySelectXAR(Node))
5164 if (trySelectCastScalableToFixedLengthVector(Node))
5170 if (trySelectCastFixedLengthToScalableVector(Node))
5179 if (ConstNode->
isZero() && (VT == MVT::i32 || VT == MVT::i64)) {
5190 const TargetLowering *TLI = getTargetLowering();
5191 SDValue TFI = CurDAG->getTargetFrameIndex(
5194 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5195 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5196 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5200 unsigned IntNo =
Node->getConstantOperandVal(1);
5204 case Intrinsic::aarch64_gcsss: {
5208 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5210 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5211 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5212 MVT::Other, Zero,
SDValue(SS1, 0));
5213 ReplaceNode(Node, SS2);
5216 case Intrinsic::aarch64_ldaxp:
5217 case Intrinsic::aarch64_ldxp: {
5219 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5224 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5225 MVT::Other, MemAddr, Chain);
5228 MachineMemOperand *MemOp =
5231 ReplaceNode(Node, Ld);
5234 case Intrinsic::aarch64_stlxp:
5235 case Intrinsic::aarch64_stxp: {
5237 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5245 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5247 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5249 MachineMemOperand *MemOp =
5253 ReplaceNode(Node, St);
5256 case Intrinsic::aarch64_neon_ld1x2:
5257 if (VT == MVT::v8i8) {
5258 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5260 }
else if (VT == MVT::v16i8) {
5261 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5263 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5264 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5266 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5267 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5269 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5270 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5272 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5273 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5275 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5276 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5278 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5279 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5283 case Intrinsic::aarch64_neon_ld1x3:
5284 if (VT == MVT::v8i8) {
5285 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5287 }
else if (VT == MVT::v16i8) {
5288 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5290 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5291 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5293 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5294 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5296 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5297 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5299 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5300 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5302 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5303 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5305 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5306 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5310 case Intrinsic::aarch64_neon_ld1x4:
5311 if (VT == MVT::v8i8) {
5312 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5314 }
else if (VT == MVT::v16i8) {
5315 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5317 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5318 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5320 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5321 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5323 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5324 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5326 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5327 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5329 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5330 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5332 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5333 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5337 case Intrinsic::aarch64_neon_ld2:
5338 if (VT == MVT::v8i8) {
5339 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5341 }
else if (VT == MVT::v16i8) {
5342 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5344 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5345 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5347 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5348 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5350 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5351 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5353 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5354 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5356 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5357 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5359 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5360 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5364 case Intrinsic::aarch64_neon_ld3:
5365 if (VT == MVT::v8i8) {
5366 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5368 }
else if (VT == MVT::v16i8) {
5369 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5371 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5372 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5374 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5375 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5377 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5378 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5380 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5381 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5383 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5384 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5386 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5387 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5391 case Intrinsic::aarch64_neon_ld4:
5392 if (VT == MVT::v8i8) {
5393 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5395 }
else if (VT == MVT::v16i8) {
5396 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5398 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5399 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5401 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5402 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5404 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5405 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5407 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5408 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5410 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5411 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5413 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5414 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5418 case Intrinsic::aarch64_neon_ld2r:
5419 if (VT == MVT::v8i8) {
5420 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5422 }
else if (VT == MVT::v16i8) {
5423 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5425 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5426 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5428 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5429 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5431 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5432 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5434 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5435 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5437 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5438 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5440 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5441 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5445 case Intrinsic::aarch64_neon_ld3r:
5446 if (VT == MVT::v8i8) {
5447 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5449 }
else if (VT == MVT::v16i8) {
5450 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5452 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5453 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5455 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5456 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5458 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5459 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5461 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5462 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5464 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5465 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5467 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5468 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5472 case Intrinsic::aarch64_neon_ld4r:
5473 if (VT == MVT::v8i8) {
5474 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5476 }
else if (VT == MVT::v16i8) {
5477 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5479 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5480 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5482 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5483 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5485 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5486 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5488 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5489 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5491 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5492 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5494 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5495 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5499 case Intrinsic::aarch64_neon_ld2lane:
5500 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5501 SelectLoadLane(Node, 2, AArch64::LD2i8);
5503 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5504 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5505 SelectLoadLane(Node, 2, AArch64::LD2i16);
5507 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5509 SelectLoadLane(Node, 2, AArch64::LD2i32);
5511 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5513 SelectLoadLane(Node, 2, AArch64::LD2i64);
5517 case Intrinsic::aarch64_neon_ld3lane:
5518 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5519 SelectLoadLane(Node, 3, AArch64::LD3i8);
5521 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5522 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5523 SelectLoadLane(Node, 3, AArch64::LD3i16);
5525 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5527 SelectLoadLane(Node, 3, AArch64::LD3i32);
5529 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5531 SelectLoadLane(Node, 3, AArch64::LD3i64);
5535 case Intrinsic::aarch64_neon_ld4lane:
5536 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5537 SelectLoadLane(Node, 4, AArch64::LD4i8);
5539 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5540 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5541 SelectLoadLane(Node, 4, AArch64::LD4i16);
5543 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5545 SelectLoadLane(Node, 4, AArch64::LD4i32);
5547 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5549 SelectLoadLane(Node, 4, AArch64::LD4i64);
5553 case Intrinsic::aarch64_ld64b:
5554 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5556 case Intrinsic::aarch64_sve_ld2q_sret: {
5557 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5560 case Intrinsic::aarch64_sve_ld3q_sret: {
5561 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5564 case Intrinsic::aarch64_sve_ld4q_sret: {
5565 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5568 case Intrinsic::aarch64_sve_ld2_sret: {
5569 if (VT == MVT::nxv16i8) {
5570 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5573 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5574 VT == MVT::nxv8bf16) {
5575 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5578 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5579 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5582 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5583 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5589 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5590 if (VT == MVT::nxv16i8) {
5591 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5592 SelectContiguousMultiVectorLoad(
5593 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5594 else if (Subtarget->hasSVE2p1())
5595 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5600 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5601 VT == MVT::nxv8bf16) {
5602 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5603 SelectContiguousMultiVectorLoad(
5604 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5605 else if (Subtarget->hasSVE2p1())
5606 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5611 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5612 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5613 SelectContiguousMultiVectorLoad(
5614 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5615 else if (Subtarget->hasSVE2p1())
5616 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5621 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5622 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5623 SelectContiguousMultiVectorLoad(
5624 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5625 else if (Subtarget->hasSVE2p1())
5626 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5634 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5635 if (VT == MVT::nxv16i8) {
5636 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5637 SelectContiguousMultiVectorLoad(
5638 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5639 else if (Subtarget->hasSVE2p1())
5640 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5645 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5646 VT == MVT::nxv8bf16) {
5647 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5648 SelectContiguousMultiVectorLoad(
5649 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5650 else if (Subtarget->hasSVE2p1())
5651 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5656 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5657 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5658 SelectContiguousMultiVectorLoad(
5659 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5660 else if (Subtarget->hasSVE2p1())
5661 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5666 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5667 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5668 SelectContiguousMultiVectorLoad(
5669 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5670 else if (Subtarget->hasSVE2p1())
5671 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5679 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5680 if (VT == MVT::nxv16i8) {
5681 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5682 SelectContiguousMultiVectorLoad(Node, 2, 0,
5683 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5684 AArch64::LDNT1B_2Z_PSEUDO);
5685 else if (Subtarget->hasSVE2p1())
5686 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5687 AArch64::LDNT1B_2Z);
5691 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5692 VT == MVT::nxv8bf16) {
5693 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5694 SelectContiguousMultiVectorLoad(Node, 2, 1,
5695 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5696 AArch64::LDNT1H_2Z_PSEUDO);
5697 else if (Subtarget->hasSVE2p1())
5698 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5699 AArch64::LDNT1H_2Z);
5703 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5704 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5705 SelectContiguousMultiVectorLoad(Node, 2, 2,
5706 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5707 AArch64::LDNT1W_2Z_PSEUDO);
5708 else if (Subtarget->hasSVE2p1())
5709 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5710 AArch64::LDNT1W_2Z);
5714 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5715 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5716 SelectContiguousMultiVectorLoad(Node, 2, 3,
5717 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5718 AArch64::LDNT1D_2Z_PSEUDO);
5719 else if (Subtarget->hasSVE2p1())
5720 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5721 AArch64::LDNT1D_2Z);
5728 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5729 if (VT == MVT::nxv16i8) {
5730 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5731 SelectContiguousMultiVectorLoad(Node, 4, 0,
5732 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5733 AArch64::LDNT1B_4Z_PSEUDO);
5734 else if (Subtarget->hasSVE2p1())
5735 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5736 AArch64::LDNT1B_4Z);
5740 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5741 VT == MVT::nxv8bf16) {
5742 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5743 SelectContiguousMultiVectorLoad(Node, 4, 1,
5744 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5745 AArch64::LDNT1H_4Z_PSEUDO);
5746 else if (Subtarget->hasSVE2p1())
5747 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5748 AArch64::LDNT1H_4Z);
5752 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5753 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5754 SelectContiguousMultiVectorLoad(Node, 4, 2,
5755 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5756 AArch64::LDNT1W_4Z_PSEUDO);
5757 else if (Subtarget->hasSVE2p1())
5758 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5759 AArch64::LDNT1W_4Z);
5763 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5764 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5765 SelectContiguousMultiVectorLoad(Node, 4, 3,
5766 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5767 AArch64::LDNT1D_4Z_PSEUDO);
5768 else if (Subtarget->hasSVE2p1())
5769 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5770 AArch64::LDNT1D_4Z);
5777 case Intrinsic::aarch64_sve_ld3_sret: {
5778 if (VT == MVT::nxv16i8) {
5779 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5782 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5783 VT == MVT::nxv8bf16) {
5784 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5787 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5788 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5791 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5792 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5798 case Intrinsic::aarch64_sve_ld4_sret: {
5799 if (VT == MVT::nxv16i8) {
5800 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5803 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5804 VT == MVT::nxv8bf16) {
5805 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5808 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5809 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5812 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5813 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5819 case Intrinsic::aarch64_sme_read_hor_vg2: {
5820 if (VT == MVT::nxv16i8) {
5821 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5822 AArch64::MOVA_2ZMXI_H_B);
5824 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5825 VT == MVT::nxv8bf16) {
5826 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5827 AArch64::MOVA_2ZMXI_H_H);
5829 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5830 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5831 AArch64::MOVA_2ZMXI_H_S);
5833 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5834 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5835 AArch64::MOVA_2ZMXI_H_D);
5840 case Intrinsic::aarch64_sme_read_ver_vg2: {
5841 if (VT == MVT::nxv16i8) {
5842 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5843 AArch64::MOVA_2ZMXI_V_B);
5845 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5846 VT == MVT::nxv8bf16) {
5847 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5848 AArch64::MOVA_2ZMXI_V_H);
5850 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5851 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5852 AArch64::MOVA_2ZMXI_V_S);
5854 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5855 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5856 AArch64::MOVA_2ZMXI_V_D);
5861 case Intrinsic::aarch64_sme_read_hor_vg4: {
5862 if (VT == MVT::nxv16i8) {
5863 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5864 AArch64::MOVA_4ZMXI_H_B);
5866 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5867 VT == MVT::nxv8bf16) {
5868 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5869 AArch64::MOVA_4ZMXI_H_H);
5871 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5872 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5873 AArch64::MOVA_4ZMXI_H_S);
5875 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5876 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5877 AArch64::MOVA_4ZMXI_H_D);
5882 case Intrinsic::aarch64_sme_read_ver_vg4: {
5883 if (VT == MVT::nxv16i8) {
5884 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5885 AArch64::MOVA_4ZMXI_V_B);
5887 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5888 VT == MVT::nxv8bf16) {
5889 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5890 AArch64::MOVA_4ZMXI_V_H);
5892 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5893 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5894 AArch64::MOVA_4ZMXI_V_S);
5896 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5897 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5898 AArch64::MOVA_4ZMXI_V_D);
5903 case Intrinsic::aarch64_sme_read_vg1x2: {
5904 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5905 AArch64::MOVA_VG2_2ZMXI);
5908 case Intrinsic::aarch64_sme_read_vg1x4: {
5909 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5910 AArch64::MOVA_VG4_4ZMXI);
5913 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5914 if (VT == MVT::nxv16i8) {
5915 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5917 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5918 VT == MVT::nxv8bf16) {
5919 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5921 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5922 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5924 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5925 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5930 case Intrinsic::aarch64_sme_readz_vert_x2: {
5931 if (VT == MVT::nxv16i8) {
5932 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5934 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5935 VT == MVT::nxv8bf16) {
5936 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5938 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5939 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5941 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5942 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5947 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5948 if (VT == MVT::nxv16i8) {
5949 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5951 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5952 VT == MVT::nxv8bf16) {
5953 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5955 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5956 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5958 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5959 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5964 case Intrinsic::aarch64_sme_readz_vert_x4: {
5965 if (VT == MVT::nxv16i8) {
5966 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5968 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5969 VT == MVT::nxv8bf16) {
5970 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5972 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5973 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5975 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5976 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5981 case Intrinsic::aarch64_sme_readz_x2: {
5982 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5986 case Intrinsic::aarch64_sme_readz_x4: {
5987 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5991 case Intrinsic::swift_async_context_addr: {
5994 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5996 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5997 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5998 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
6000 ReplaceUses(
SDValue(Node, 0), Res);
6002 CurDAG->RemoveDeadNode(Node);
6004 auto &MF = CurDAG->getMachineFunction();
6005 MF.getFrameInfo().setFrameAddressIsTaken(
true);
6006 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
6009 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
6011 Node->getValueType(0),
6012 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
6013 AArch64::LUTI2_4ZTZI_S}))
6015 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
6018 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
6020 Node->getValueType(0),
6021 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
6023 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
6026 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
6028 Node->getValueType(0),
6029 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
6030 AArch64::LUTI2_2ZTZI_S}))
6032 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
6035 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
6037 Node->getValueType(0),
6038 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
6039 AArch64::LUTI4_2ZTZI_S}))
6041 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
6044 case Intrinsic::aarch64_sme_luti4_zt_x4: {
6045 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z, 2);
6048 case Intrinsic::aarch64_sme_luti6_zt_x4: {
6049 SelectMultiVectorLuti(Node, 4, AArch64::LUTI6_4ZT3Z, 3);
6052 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
6054 Node->getValueType(0),
6055 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
6056 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6058 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
6060 Node->getValueType(0),
6061 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
6062 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6064 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
6066 Node->getValueType(0),
6067 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
6068 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6070 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
6072 Node->getValueType(0),
6073 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
6074 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6076 case Intrinsic::ptrauth_resign_load_relative:
6077 SelectPtrauthResign(Node);
6082 unsigned IntNo =
Node->getConstantOperandVal(0);
6086 case Intrinsic::aarch64_tagp:
6090 case Intrinsic::ptrauth_auth:
6091 SelectPtrauthAuth(Node);
6094 case Intrinsic::ptrauth_resign:
6095 SelectPtrauthResign(Node);
6098 case Intrinsic::ptrauth_auth_with_pc_and_resign:
6099 SelectPtrauthResignWithPC(Node);
6102 case Intrinsic::aarch64_neon_tbl2:
6103 SelectTable(Node, 2,
6104 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
6107 case Intrinsic::aarch64_neon_tbl3:
6108 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
6109 : AArch64::TBLv16i8Three,
6112 case Intrinsic::aarch64_neon_tbl4:
6113 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6114 : AArch64::TBLv16i8Four,
6117 case Intrinsic::aarch64_neon_tbx2:
6118 SelectTable(Node, 2,
6119 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6122 case Intrinsic::aarch64_neon_tbx3:
6123 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6124 : AArch64::TBXv16i8Three,
6127 case Intrinsic::aarch64_neon_tbx4:
6128 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6129 : AArch64::TBXv16i8Four,
6132 case Intrinsic::aarch64_sve_srshl_single_x2:
6134 Node->getValueType(0),
6135 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6136 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6137 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6139 case Intrinsic::aarch64_sve_srshl_single_x4:
6141 Node->getValueType(0),
6142 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6143 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6144 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6146 case Intrinsic::aarch64_sme_luti6_lane_x4_x2:
6147 SelectMultiVectorLuti6LaneX4(Node, 2);
6149 case Intrinsic::aarch64_sme_luti6_lane_x4_x3:
6150 SelectMultiVectorLuti6LaneX4(Node, 3);
6152 case Intrinsic::aarch64_sve_urshl_single_x2:
6154 Node->getValueType(0),
6155 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6156 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6157 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6159 case Intrinsic::aarch64_sve_urshl_single_x4:
6161 Node->getValueType(0),
6162 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6163 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6164 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6166 case Intrinsic::aarch64_sve_srshl_x2:
6168 Node->getValueType(0),
6169 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6170 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6171 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6173 case Intrinsic::aarch64_sve_srshl_x4:
6175 Node->getValueType(0),
6176 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6177 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6178 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6180 case Intrinsic::aarch64_sve_urshl_x2:
6182 Node->getValueType(0),
6183 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6184 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6185 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6187 case Intrinsic::aarch64_sve_urshl_x4:
6189 Node->getValueType(0),
6190 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6191 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6192 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6194 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6196 Node->getValueType(0),
6197 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6198 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6199 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6201 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6203 Node->getValueType(0),
6204 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6205 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6206 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6208 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6210 Node->getValueType(0),
6211 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6212 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6213 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6215 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6217 Node->getValueType(0),
6218 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6219 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6220 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6222 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6224 Node->getValueType(0),
6225 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6226 AArch64::FSCALE_2ZZ_D}))
6227 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6229 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6231 Node->getValueType(0),
6232 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6233 AArch64::FSCALE_4ZZ_D}))
6234 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6236 case Intrinsic::aarch64_sme_fp8_scale_x2:
6238 Node->getValueType(0),
6239 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6240 AArch64::FSCALE_2Z2Z_D}))
6241 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6243 case Intrinsic::aarch64_sme_fp8_scale_x4:
6245 Node->getValueType(0),
6246 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6247 AArch64::FSCALE_4Z4Z_D}))
6248 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6250 case Intrinsic::aarch64_sve_whilege_x2:
6252 Node->getValueType(0),
6253 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6254 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6255 SelectWhilePair(Node,
Op);
6257 case Intrinsic::aarch64_sve_whilegt_x2:
6259 Node->getValueType(0),
6260 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6261 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6262 SelectWhilePair(Node,
Op);
6264 case Intrinsic::aarch64_sve_whilehi_x2:
6266 Node->getValueType(0),
6267 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6268 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6269 SelectWhilePair(Node,
Op);
6271 case Intrinsic::aarch64_sve_whilehs_x2:
6273 Node->getValueType(0),
6274 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6275 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6276 SelectWhilePair(Node,
Op);
6278 case Intrinsic::aarch64_sve_whilele_x2:
6280 Node->getValueType(0),
6281 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6282 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6283 SelectWhilePair(Node,
Op);
6285 case Intrinsic::aarch64_sve_whilelo_x2:
6287 Node->getValueType(0),
6288 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6289 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6290 SelectWhilePair(Node,
Op);
6292 case Intrinsic::aarch64_sve_whilels_x2:
6294 Node->getValueType(0),
6295 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6296 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6297 SelectWhilePair(Node,
Op);
6299 case Intrinsic::aarch64_sve_whilelt_x2:
6301 Node->getValueType(0),
6302 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6303 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6304 SelectWhilePair(Node,
Op);
6306 case Intrinsic::aarch64_sve_smax_single_x2:
6308 Node->getValueType(0),
6309 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6310 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6311 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6313 case Intrinsic::aarch64_sve_umax_single_x2:
6315 Node->getValueType(0),
6316 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6317 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6318 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6320 case Intrinsic::aarch64_sve_fmax_single_x2:
6322 Node->getValueType(0),
6323 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6324 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6325 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6327 case Intrinsic::aarch64_sve_smax_single_x4:
6329 Node->getValueType(0),
6330 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6331 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6332 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6334 case Intrinsic::aarch64_sve_umax_single_x4:
6336 Node->getValueType(0),
6337 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6338 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6339 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6341 case Intrinsic::aarch64_sve_fmax_single_x4:
6343 Node->getValueType(0),
6344 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6345 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6346 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6348 case Intrinsic::aarch64_sve_smin_single_x2:
6350 Node->getValueType(0),
6351 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6352 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6353 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6355 case Intrinsic::aarch64_sve_umin_single_x2:
6357 Node->getValueType(0),
6358 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6359 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6360 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6362 case Intrinsic::aarch64_sve_fmin_single_x2:
6364 Node->getValueType(0),
6365 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6366 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6367 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6369 case Intrinsic::aarch64_sve_smin_single_x4:
6371 Node->getValueType(0),
6372 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6373 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6374 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6376 case Intrinsic::aarch64_sve_umin_single_x4:
6378 Node->getValueType(0),
6379 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6380 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6381 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6383 case Intrinsic::aarch64_sve_fmin_single_x4:
6385 Node->getValueType(0),
6386 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6387 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6388 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6390 case Intrinsic::aarch64_sve_smax_x2:
6392 Node->getValueType(0),
6393 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6394 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6395 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6397 case Intrinsic::aarch64_sve_umax_x2:
6399 Node->getValueType(0),
6400 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6401 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6402 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6404 case Intrinsic::aarch64_sve_fmax_x2:
6406 Node->getValueType(0),
6407 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6408 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6409 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6411 case Intrinsic::aarch64_sve_smax_x4:
6413 Node->getValueType(0),
6414 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6415 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6416 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6418 case Intrinsic::aarch64_sve_umax_x4:
6420 Node->getValueType(0),
6421 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6422 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6423 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6425 case Intrinsic::aarch64_sve_fmax_x4:
6427 Node->getValueType(0),
6428 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6429 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6430 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6432 case Intrinsic::aarch64_sme_famax_x2:
6434 Node->getValueType(0),
6435 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6436 AArch64::FAMAX_2Z2Z_D}))
6437 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6439 case Intrinsic::aarch64_sme_famax_x4:
6441 Node->getValueType(0),
6442 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6443 AArch64::FAMAX_4Z4Z_D}))
6444 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6446 case Intrinsic::aarch64_sme_famin_x2:
6448 Node->getValueType(0),
6449 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6450 AArch64::FAMIN_2Z2Z_D}))
6451 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6453 case Intrinsic::aarch64_sme_famin_x4:
6455 Node->getValueType(0),
6456 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6457 AArch64::FAMIN_4Z4Z_D}))
6458 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6460 case Intrinsic::aarch64_sve_smin_x2:
6462 Node->getValueType(0),
6463 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6464 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6465 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6467 case Intrinsic::aarch64_sve_umin_x2:
6469 Node->getValueType(0),
6470 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6471 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6472 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6474 case Intrinsic::aarch64_sve_fmin_x2:
6476 Node->getValueType(0),
6477 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6478 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6479 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6481 case Intrinsic::aarch64_sve_smin_x4:
6483 Node->getValueType(0),
6484 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6485 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6486 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6488 case Intrinsic::aarch64_sve_umin_x4:
6490 Node->getValueType(0),
6491 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6492 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6493 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6495 case Intrinsic::aarch64_sve_fmin_x4:
6497 Node->getValueType(0),
6498 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6499 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6500 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6502 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6504 Node->getValueType(0),
6505 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6506 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6507 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6509 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6511 Node->getValueType(0),
6512 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6513 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6514 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6516 case Intrinsic::aarch64_sve_fminnm_single_x2:
6518 Node->getValueType(0),
6519 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6520 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6521 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6523 case Intrinsic::aarch64_sve_fminnm_single_x4:
6525 Node->getValueType(0),
6526 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6527 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6528 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6530 case Intrinsic::aarch64_sve_fscale_single_x4:
6531 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6533 case Intrinsic::aarch64_sve_fscale_single_x2:
6534 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6536 case Intrinsic::aarch64_sve_fmul_single_x4:
6538 Node->getValueType(0),
6539 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6540 AArch64::FMUL_4ZZ_D}))
6541 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6543 case Intrinsic::aarch64_sve_fmul_single_x2:
6545 Node->getValueType(0),
6546 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6547 AArch64::FMUL_2ZZ_D}))
6548 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6550 case Intrinsic::aarch64_sve_fmaxnm_x2:
6552 Node->getValueType(0),
6553 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6554 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6555 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6557 case Intrinsic::aarch64_sve_fmaxnm_x4:
6559 Node->getValueType(0),
6560 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6561 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6562 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6564 case Intrinsic::aarch64_sve_fminnm_x2:
6566 Node->getValueType(0),
6567 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6568 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6569 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6571 case Intrinsic::aarch64_sve_fminnm_x4:
6573 Node->getValueType(0),
6574 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6575 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6576 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6578 case Intrinsic::aarch64_sve_aese_lane_x2:
6579 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6581 case Intrinsic::aarch64_sve_aesd_lane_x2:
6582 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6584 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6585 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6587 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6588 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6590 case Intrinsic::aarch64_sve_aese_lane_x4:
6591 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6593 case Intrinsic::aarch64_sve_aesd_lane_x4:
6594 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6596 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6597 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6599 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6600 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6602 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6603 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6605 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6609 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6611 for (
unsigned I = 0;
I < 2;
I++)
6613 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6615 CurDAG->RemoveDeadNode(Node);
6618 case Intrinsic::aarch64_sve_fscale_x4:
6619 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6621 case Intrinsic::aarch64_sve_fscale_x2:
6622 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6624 case Intrinsic::aarch64_sve_fmul_x4:
6626 Node->getValueType(0),
6627 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6628 AArch64::FMUL_4Z4Z_D}))
6629 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6631 case Intrinsic::aarch64_sve_fmul_x2:
6633 Node->getValueType(0),
6634 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6635 AArch64::FMUL_2Z2Z_D}))
6636 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6638 case Intrinsic::aarch64_sve_fcvtzs_x2:
6639 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6641 case Intrinsic::aarch64_sve_scvtf_x2:
6642 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6644 case Intrinsic::aarch64_sve_fcvtzu_x2:
6645 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6647 case Intrinsic::aarch64_sve_ucvtf_x2:
6648 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6650 case Intrinsic::aarch64_sve_fcvtzs_x4:
6651 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6653 case Intrinsic::aarch64_sve_scvtf_x4:
6654 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6656 case Intrinsic::aarch64_sve_fcvtzu_x4:
6657 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6659 case Intrinsic::aarch64_sve_ucvtf_x4:
6660 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6662 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6663 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6665 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6666 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6668 case Intrinsic::aarch64_sve_sclamp_single_x2:
6670 Node->getValueType(0),
6671 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6672 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6673 SelectClamp(Node, 2,
Op);
6675 case Intrinsic::aarch64_sve_uclamp_single_x2:
6677 Node->getValueType(0),
6678 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6679 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6680 SelectClamp(Node, 2,
Op);
6682 case Intrinsic::aarch64_sve_fclamp_single_x2:
6684 Node->getValueType(0),
6685 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6686 AArch64::FCLAMP_VG2_2Z2Z_D}))
6687 SelectClamp(Node, 2,
Op);
6689 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6690 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6692 case Intrinsic::aarch64_sve_sclamp_single_x4:
6694 Node->getValueType(0),
6695 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6696 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6697 SelectClamp(Node, 4,
Op);
6699 case Intrinsic::aarch64_sve_uclamp_single_x4:
6701 Node->getValueType(0),
6702 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6703 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6704 SelectClamp(Node, 4,
Op);
6706 case Intrinsic::aarch64_sve_fclamp_single_x4:
6708 Node->getValueType(0),
6709 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6710 AArch64::FCLAMP_VG4_4Z4Z_D}))
6711 SelectClamp(Node, 4,
Op);
6713 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6714 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6716 case Intrinsic::aarch64_sve_add_single_x2:
6718 Node->getValueType(0),
6719 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6720 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6721 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6723 case Intrinsic::aarch64_sve_add_single_x4:
6725 Node->getValueType(0),
6726 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6727 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6728 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6730 case Intrinsic::aarch64_sve_zip_x2:
6732 Node->getValueType(0),
6733 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6734 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6735 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6737 case Intrinsic::aarch64_sve_zipq_x2:
6738 SelectUnaryMultiIntrinsic(Node, 2,
false,
6739 AArch64::ZIP_VG2_2ZZZ_Q);
6741 case Intrinsic::aarch64_sve_zip_x4:
6743 Node->getValueType(0),
6744 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6745 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6746 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6748 case Intrinsic::aarch64_sve_zipq_x4:
6749 SelectUnaryMultiIntrinsic(Node, 4,
true,
6750 AArch64::ZIP_VG4_4Z4Z_Q);
6752 case Intrinsic::aarch64_sve_uzp_x2:
6754 Node->getValueType(0),
6755 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6756 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6757 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6759 case Intrinsic::aarch64_sve_uzpq_x2:
6760 SelectUnaryMultiIntrinsic(Node, 2,
false,
6761 AArch64::UZP_VG2_2ZZZ_Q);
6763 case Intrinsic::aarch64_sve_uzp_x4:
6765 Node->getValueType(0),
6766 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6767 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6768 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6770 case Intrinsic::aarch64_sve_uzpq_x4:
6771 SelectUnaryMultiIntrinsic(Node, 4,
true,
6772 AArch64::UZP_VG4_4Z4Z_Q);
6774 case Intrinsic::aarch64_sve_sel_x2:
6776 Node->getValueType(0),
6777 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6778 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6779 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6781 case Intrinsic::aarch64_sve_sel_x4:
6783 Node->getValueType(0),
6784 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6785 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6786 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6788 case Intrinsic::aarch64_sve_frinta_x2:
6789 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6791 case Intrinsic::aarch64_sve_frinta_x4:
6792 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6794 case Intrinsic::aarch64_sve_frintm_x2:
6795 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6797 case Intrinsic::aarch64_sve_frintm_x4:
6798 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6800 case Intrinsic::aarch64_sve_frintn_x2:
6801 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6803 case Intrinsic::aarch64_sve_frintn_x4:
6804 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6806 case Intrinsic::aarch64_sve_frintp_x2:
6807 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6809 case Intrinsic::aarch64_sve_frintp_x4:
6810 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6812 case Intrinsic::aarch64_sve_sunpk_x2:
6814 Node->getValueType(0),
6815 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6816 AArch64::SUNPK_VG2_2ZZ_D}))
6817 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6819 case Intrinsic::aarch64_sve_uunpk_x2:
6821 Node->getValueType(0),
6822 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6823 AArch64::UUNPK_VG2_2ZZ_D}))
6824 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6826 case Intrinsic::aarch64_sve_sunpk_x4:
6828 Node->getValueType(0),
6829 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6830 AArch64::SUNPK_VG4_4Z2Z_D}))
6831 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6833 case Intrinsic::aarch64_sve_uunpk_x4:
6835 Node->getValueType(0),
6836 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6837 AArch64::UUNPK_VG4_4Z2Z_D}))
6838 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6840 case Intrinsic::aarch64_sve_pext_x2: {
6842 Node->getValueType(0),
6843 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6844 AArch64::PEXT_2PCI_D}))
6845 SelectPExtPair(Node,
Op);
6852 unsigned IntNo =
Node->getConstantOperandVal(1);
6853 if (
Node->getNumOperands() >= 3)
6854 VT =
Node->getOperand(2)->getValueType(0);
6858 case Intrinsic::aarch64_neon_st1x2: {
6859 if (VT == MVT::v8i8) {
6860 SelectStore(Node, 2, AArch64::ST1Twov8b);
6862 }
else if (VT == MVT::v16i8) {
6863 SelectStore(Node, 2, AArch64::ST1Twov16b);
6865 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6866 VT == MVT::v4bf16) {
6867 SelectStore(Node, 2, AArch64::ST1Twov4h);
6869 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6870 VT == MVT::v8bf16) {
6871 SelectStore(Node, 2, AArch64::ST1Twov8h);
6873 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6874 SelectStore(Node, 2, AArch64::ST1Twov2s);
6876 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6877 SelectStore(Node, 2, AArch64::ST1Twov4s);
6879 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6880 SelectStore(Node, 2, AArch64::ST1Twov2d);
6882 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6883 SelectStore(Node, 2, AArch64::ST1Twov1d);
6888 case Intrinsic::aarch64_neon_st1x3: {
6889 if (VT == MVT::v8i8) {
6890 SelectStore(Node, 3, AArch64::ST1Threev8b);
6892 }
else if (VT == MVT::v16i8) {
6893 SelectStore(Node, 3, AArch64::ST1Threev16b);
6895 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6896 VT == MVT::v4bf16) {
6897 SelectStore(Node, 3, AArch64::ST1Threev4h);
6899 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6900 VT == MVT::v8bf16) {
6901 SelectStore(Node, 3, AArch64::ST1Threev8h);
6903 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6904 SelectStore(Node, 3, AArch64::ST1Threev2s);
6906 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6907 SelectStore(Node, 3, AArch64::ST1Threev4s);
6909 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6910 SelectStore(Node, 3, AArch64::ST1Threev2d);
6912 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6913 SelectStore(Node, 3, AArch64::ST1Threev1d);
6918 case Intrinsic::aarch64_neon_st1x4: {
6919 if (VT == MVT::v8i8) {
6920 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6922 }
else if (VT == MVT::v16i8) {
6923 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6925 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6926 VT == MVT::v4bf16) {
6927 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6929 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6930 VT == MVT::v8bf16) {
6931 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6933 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6934 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6936 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6937 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6939 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6940 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6942 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6943 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6948 case Intrinsic::aarch64_neon_st2: {
6949 if (VT == MVT::v8i8) {
6950 SelectStore(Node, 2, AArch64::ST2Twov8b);
6952 }
else if (VT == MVT::v16i8) {
6953 SelectStore(Node, 2, AArch64::ST2Twov16b);
6955 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6956 VT == MVT::v4bf16) {
6957 SelectStore(Node, 2, AArch64::ST2Twov4h);
6959 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6960 VT == MVT::v8bf16) {
6961 SelectStore(Node, 2, AArch64::ST2Twov8h);
6963 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6964 SelectStore(Node, 2, AArch64::ST2Twov2s);
6966 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6967 SelectStore(Node, 2, AArch64::ST2Twov4s);
6969 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6970 SelectStore(Node, 2, AArch64::ST2Twov2d);
6972 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6973 SelectStore(Node, 2, AArch64::ST1Twov1d);
6978 case Intrinsic::aarch64_neon_st3: {
6979 if (VT == MVT::v8i8) {
6980 SelectStore(Node, 3, AArch64::ST3Threev8b);
6982 }
else if (VT == MVT::v16i8) {
6983 SelectStore(Node, 3, AArch64::ST3Threev16b);
6985 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6986 VT == MVT::v4bf16) {
6987 SelectStore(Node, 3, AArch64::ST3Threev4h);
6989 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6990 VT == MVT::v8bf16) {
6991 SelectStore(Node, 3, AArch64::ST3Threev8h);
6993 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6994 SelectStore(Node, 3, AArch64::ST3Threev2s);
6996 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6997 SelectStore(Node, 3, AArch64::ST3Threev4s);
6999 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7000 SelectStore(Node, 3, AArch64::ST3Threev2d);
7002 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7003 SelectStore(Node, 3, AArch64::ST1Threev1d);
7008 case Intrinsic::aarch64_neon_st4: {
7009 if (VT == MVT::v8i8) {
7010 SelectStore(Node, 4, AArch64::ST4Fourv8b);
7012 }
else if (VT == MVT::v16i8) {
7013 SelectStore(Node, 4, AArch64::ST4Fourv16b);
7015 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7016 VT == MVT::v4bf16) {
7017 SelectStore(Node, 4, AArch64::ST4Fourv4h);
7019 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7020 VT == MVT::v8bf16) {
7021 SelectStore(Node, 4, AArch64::ST4Fourv8h);
7023 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7024 SelectStore(Node, 4, AArch64::ST4Fourv2s);
7026 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7027 SelectStore(Node, 4, AArch64::ST4Fourv4s);
7029 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7030 SelectStore(Node, 4, AArch64::ST4Fourv2d);
7032 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7033 SelectStore(Node, 4, AArch64::ST1Fourv1d);
7038 case Intrinsic::aarch64_neon_st2lane: {
7039 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7040 SelectStoreLane(Node, 2, AArch64::ST2i8);
7042 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7043 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7044 SelectStoreLane(Node, 2, AArch64::ST2i16);
7046 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7048 SelectStoreLane(Node, 2, AArch64::ST2i32);
7050 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7052 SelectStoreLane(Node, 2, AArch64::ST2i64);
7057 case Intrinsic::aarch64_neon_st3lane: {
7058 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7059 SelectStoreLane(Node, 3, AArch64::ST3i8);
7061 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7062 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7063 SelectStoreLane(Node, 3, AArch64::ST3i16);
7065 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7067 SelectStoreLane(Node, 3, AArch64::ST3i32);
7069 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7071 SelectStoreLane(Node, 3, AArch64::ST3i64);
7076 case Intrinsic::aarch64_neon_st4lane: {
7077 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7078 SelectStoreLane(Node, 4, AArch64::ST4i8);
7080 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7081 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7082 SelectStoreLane(Node, 4, AArch64::ST4i16);
7084 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7086 SelectStoreLane(Node, 4, AArch64::ST4i32);
7088 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7090 SelectStoreLane(Node, 4, AArch64::ST4i64);
7095 case Intrinsic::aarch64_sve_st2q: {
7096 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
7099 case Intrinsic::aarch64_sve_st3q: {
7100 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
7103 case Intrinsic::aarch64_sve_st4q: {
7104 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
7107 case Intrinsic::aarch64_sve_st2: {
7108 if (VT == MVT::nxv16i8) {
7109 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
7111 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7112 VT == MVT::nxv8bf16) {
7113 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
7115 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7116 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7118 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7119 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7124 case Intrinsic::aarch64_sve_st3: {
7125 if (VT == MVT::nxv16i8) {
7126 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7128 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7129 VT == MVT::nxv8bf16) {
7130 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7132 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7133 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7135 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7136 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7141 case Intrinsic::aarch64_sve_st4: {
7142 if (VT == MVT::nxv16i8) {
7143 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7145 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7146 VT == MVT::nxv8bf16) {
7147 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7149 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7150 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7152 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7153 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7161 case AArch64ISD::LD2post: {
7162 if (VT == MVT::v8i8) {
7163 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7165 }
else if (VT == MVT::v16i8) {
7166 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7168 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7169 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7171 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7172 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7174 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7175 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7177 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7178 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7180 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7181 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7183 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7184 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7189 case AArch64ISD::LD3post: {
7190 if (VT == MVT::v8i8) {
7191 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7193 }
else if (VT == MVT::v16i8) {
7194 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7196 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7197 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7199 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7200 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7202 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7203 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7205 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7206 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7208 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7209 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7211 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7212 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7217 case AArch64ISD::LD4post: {
7218 if (VT == MVT::v8i8) {
7219 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7221 }
else if (VT == MVT::v16i8) {
7222 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7224 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7225 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7227 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7228 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7230 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7231 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7233 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7234 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7236 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7237 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7239 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7240 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7245 case AArch64ISD::LD1x2post: {
7246 if (VT == MVT::v8i8) {
7247 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7249 }
else if (VT == MVT::v16i8) {
7250 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7252 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7253 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7255 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7256 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7258 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7259 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7261 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7262 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7264 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7265 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7267 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7268 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7273 case AArch64ISD::LD1x3post: {
7274 if (VT == MVT::v8i8) {
7275 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7277 }
else if (VT == MVT::v16i8) {
7278 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7280 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7281 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7283 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7284 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7286 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7287 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7289 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7290 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7292 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7293 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7295 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7296 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7301 case AArch64ISD::LD1x4post: {
7302 if (VT == MVT::v8i8) {
7303 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7305 }
else if (VT == MVT::v16i8) {
7306 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7308 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7309 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7311 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7312 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7314 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7315 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7317 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7318 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7320 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7321 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7323 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7324 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7329 case AArch64ISD::LD1DUPpost: {
7330 if (VT == MVT::v8i8) {
7331 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7333 }
else if (VT == MVT::v16i8) {
7334 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7336 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7337 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7339 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7340 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7342 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7343 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7345 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7346 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7348 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7349 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7351 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7352 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7357 case AArch64ISD::LD2DUPpost: {
7358 if (VT == MVT::v8i8) {
7359 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7361 }
else if (VT == MVT::v16i8) {
7362 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7364 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7365 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7367 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7368 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7370 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7371 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7373 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7374 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7376 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7377 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7379 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7380 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7385 case AArch64ISD::LD3DUPpost: {
7386 if (VT == MVT::v8i8) {
7387 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7389 }
else if (VT == MVT::v16i8) {
7390 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7392 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7393 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7395 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7396 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7398 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7399 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7401 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7402 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7404 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7405 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7407 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7408 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7413 case AArch64ISD::LD4DUPpost: {
7414 if (VT == MVT::v8i8) {
7415 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7417 }
else if (VT == MVT::v16i8) {
7418 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7420 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7421 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7423 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7424 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7426 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7427 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7429 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7430 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7432 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7433 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7435 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7436 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7441 case AArch64ISD::LD1LANEpost: {
7442 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7443 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7445 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7446 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7447 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7449 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7451 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7453 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7455 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7460 case AArch64ISD::LD2LANEpost: {
7461 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7462 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7464 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7465 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7466 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7468 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7470 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7472 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7474 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7479 case AArch64ISD::LD3LANEpost: {
7480 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7481 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7483 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7484 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7485 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7487 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7489 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7491 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7493 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7498 case AArch64ISD::LD4LANEpost: {
7499 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7500 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7502 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7503 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7504 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7506 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7508 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7510 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7512 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7517 case AArch64ISD::ST2post: {
7518 VT =
Node->getOperand(1).getValueType();
7519 if (VT == MVT::v8i8) {
7520 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7522 }
else if (VT == MVT::v16i8) {
7523 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7525 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7526 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7528 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7529 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7531 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7532 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7534 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7535 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7537 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7538 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7540 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7541 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7546 case AArch64ISD::ST3post: {
7547 VT =
Node->getOperand(1).getValueType();
7548 if (VT == MVT::v8i8) {
7549 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7551 }
else if (VT == MVT::v16i8) {
7552 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7554 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7555 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7557 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7558 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7560 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7561 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7563 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7564 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7566 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7567 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7569 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7570 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7575 case AArch64ISD::ST4post: {
7576 VT =
Node->getOperand(1).getValueType();
7577 if (VT == MVT::v8i8) {
7578 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7580 }
else if (VT == MVT::v16i8) {
7581 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7583 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7584 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7586 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7587 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7589 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7590 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7592 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7593 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7595 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7596 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7598 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7599 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7604 case AArch64ISD::ST1x2post: {
7605 VT =
Node->getOperand(1).getValueType();
7606 if (VT == MVT::v8i8) {
7607 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7609 }
else if (VT == MVT::v16i8) {
7610 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7612 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7613 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7615 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7616 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7618 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7619 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7621 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7622 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7624 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7625 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7627 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7628 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7633 case AArch64ISD::ST1x3post: {
7634 VT =
Node->getOperand(1).getValueType();
7635 if (VT == MVT::v8i8) {
7636 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7638 }
else if (VT == MVT::v16i8) {
7639 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7641 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7642 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7644 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7645 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7647 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7648 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7650 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7651 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7653 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7654 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7656 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7657 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7662 case AArch64ISD::ST1x4post: {
7663 VT =
Node->getOperand(1).getValueType();
7664 if (VT == MVT::v8i8) {
7665 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7667 }
else if (VT == MVT::v16i8) {
7668 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7670 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7671 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7673 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7674 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7676 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7677 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7679 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7680 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7682 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7683 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7685 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7686 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7691 case AArch64ISD::ST2LANEpost: {
7692 VT =
Node->getOperand(1).getValueType();
7693 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7694 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7696 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7697 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7698 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7700 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7702 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7704 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7706 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7711 case AArch64ISD::ST3LANEpost: {
7712 VT =
Node->getOperand(1).getValueType();
7713 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7714 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7716 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7717 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7718 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7720 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7722 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7724 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7726 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7731 case AArch64ISD::ST4LANEpost: {
7732 VT =
Node->getOperand(1).getValueType();
7733 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7734 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7736 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7737 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7738 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7740 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7742 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7744 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7746 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7761 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7773 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7777 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7778 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7800 return MemIntr->getMemoryVT();
7807 DataVT = Load->getValueType(0);
7809 DataVT = Load->getValueType(0);
7811 DataVT = Store->getValue().getValueType();
7813 DataVT = Store->getValue().getValueType();
7820 const unsigned Opcode = Root->
getOpcode();
7824 case AArch64ISD::LD1_MERGE_ZERO:
7825 case AArch64ISD::LD1S_MERGE_ZERO:
7826 case AArch64ISD::LDNF1_MERGE_ZERO:
7827 case AArch64ISD::LDNF1S_MERGE_ZERO:
7829 case AArch64ISD::ST1_PRED:
7841 case Intrinsic::aarch64_sme_ldr:
7842 case Intrinsic::aarch64_sme_str:
7843 return MVT::nxv16i8;
7844 case Intrinsic::aarch64_sve_prf:
7849 case Intrinsic::aarch64_sve_ld2_sret:
7850 case Intrinsic::aarch64_sve_ld2q_sret:
7853 case Intrinsic::aarch64_sve_st2q:
7856 case Intrinsic::aarch64_sve_ld3_sret:
7857 case Intrinsic::aarch64_sve_ld3q_sret:
7860 case Intrinsic::aarch64_sve_st3q:
7863 case Intrinsic::aarch64_sve_ld4_sret:
7864 case Intrinsic::aarch64_sve_ld4q_sret:
7867 case Intrinsic::aarch64_sve_st4q:
7870 case Intrinsic::aarch64_sve_ld1_pn_x2:
7871 case Intrinsic::aarch64_sve_ldnt1_pn_x2:
7874 case Intrinsic::aarch64_sve_ld1_pn_x4:
7875 case Intrinsic::aarch64_sve_ldnt1_pn_x4:
7878 case Intrinsic::aarch64_sve_st1_pn_x2:
7879 case Intrinsic::aarch64_sve_stnt1_pn_x2:
7882 case Intrinsic::aarch64_sve_st1_pn_x4:
7883 case Intrinsic::aarch64_sve_stnt1_pn_x4:
7886 case Intrinsic::aarch64_sve_ld1udq:
7887 case Intrinsic::aarch64_sve_st1dq:
7888 return EVT(MVT::nxv1i64);
7889 case Intrinsic::aarch64_sve_ld1uwq:
7890 case Intrinsic::aarch64_sve_st1wq:
7891 return EVT(MVT::nxv1i32);
7898template <
int64_t Min,
int64_t Max>
7899bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7903 const DataLayout &
DL = CurDAG->getDataLayout();
7904 const MachineFrameInfo &MFI = MF->getFrameInfo();
7912 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7926 int64_t MulImm = std::numeric_limits<int64_t>::max();
7930 int64_t ByteOffset =
C->getSExtValue();
7931 const auto KnownVScale =
7934 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7937 MulImm = ByteOffset / KnownVScale;
7944 if ((MulImm % MemWidthBytes) != 0)
7947 int64_t
Offset = MulImm / MemWidthBytes;
7951 Base =
N.getOperand(0);
7960 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7966bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7985 int64_t ImmOff =
C->getSExtValue();
7986 unsigned Size = 1 << Scale;
7995 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7997 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
8008 if (
C->getZExtValue() == Scale) {
8017bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
8018 const AArch64TargetLowering *TLI =
8019 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
8024bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
8025 return N.getValueType().isScalableVectorOf(MVT::i1);
8028bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
8033 int64_t ImmOff =
C->getSExtValue();
8034 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
8035 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
8040 if (
SDValue C = MatchConstantOffset(
N)) {
8047 if (CurDAG->isBaseWithConstantOffset(
N)) {
8048 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
8049 Base =
N.getOperand(0);
8057 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
8061bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
8081 uint64_t LowerBound = 0, UpperBound = 64;
8099 if (CN->getAPIntValue().uge(LowerBound) &&
8100 CN->getAPIntValue().ult(UpperBound)) {
8102 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
8110template <
bool MatchCBB>
8117 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
8119 Reg =
N.getOperand(0);
8121 SDLoc(
N), MVT::i32);
8129 Reg =
N.getOperand(0);
8149SDValue AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode &
N) {
8150 EVT VT =
N.getValueType(0);
8161 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8170 unsigned CondCode = CC->getZExtValue();
8173 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8175 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8176 else if (VT == MVT::f32)
8177 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8178 else if (VT == MVT::f64)
8179 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8187 if (TVal == CmpLHS && FVal == CmpRHS)
8192 if (TVal == CmpLHS && FVal == CmpRHS)
8201 unsigned Opc = getOpc(VT, isMax);
8207 if (!CFP || CFP->getValueAPF().isNaN())
8212 if (CFP->isZero() && !
N.getFlags().hasNoSignedZeros())
8218 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8224 return SDValue(CurDAG->getMachineNode(
Opc,
DL, VT, CmpLHS, CmpRHS), 0);
8227void AArch64DAGToDAGISel::PreprocessISelDAG() {
8228 bool MadeChange =
false;
8234 switch (
N.getOpcode()) {
8236 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8237 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8238 ScalarTy ==
N.getOperand(0).getValueType())
8243 case AArch64ISD::CSEL:
8244 Result = tryFoldCselToFMaxMin(
N);
8251 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8257 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8263 CurDAG->RemoveDeadNodes();
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static std::optional< APInt > GetNEONSplatValue(SDValue N)
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static SDValue addBitcastHints(SelectionDAG &DAG, SDNode &N)
addBitcastHints - This method adds bitcast hints to the operands of a node to help instruction select...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static std::optional< APInt > DecodeNEONSplat(SDValue N)
static bool checkCVTFixedPointOperandWithFBitsForVectors(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static SDValue getZeroRegister(SelectionDAG &DAG, SDLoc DL, EVT VT)
Returns a copy from WZR or XZR.
static bool isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static APInt DecodeFMOVImm(uint64_t Imm, unsigned RegWidth)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static EVT getMultipleVectorType(LLVMContext &Ctx, EVT VecVT, unsigned NumVec)
Builds an integer vector type large enough to hold NumVec instances of VecVT.
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
AArch64DAGToDAGISelPass(AArch64TargetMachine &TM)
const AArch64RegisterInfo * getRegisterInfo() const override
const AArch64TargetLowering * getTargetLowering() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(const SelectionDAG &DAG, SDValue N) const
Register matchRegisterName(StringRef RegName) const
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static const fltSemantics & IEEEhalf()
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
unsigned getID() const
getID() - Return the register class ID number.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
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
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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...
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
constexpr bool isLegalArithImmed(const uint64_t C)
isLegalArithImmed -
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
constexpr unsigned getArithImmedShift(const uint64_t C)
getArithImmedShift - assumes C is a legal immediate for arithmetic instructions and
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
static constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Known
Known to have no common set bits.
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isScalableVectorOf(EVT EltVT) const
Return true if this is a scalable vector with matching element type.
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.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.