22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
64 void PreprocessISelDAG()
override;
68 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
70 std::vector<SDValue> &OutOps)
override;
72 template <
signed Low,
signed High,
signed Scale>
75 template <
signed Low,
signed High>
83 return SelectShiftedRegister(
N,
false,
Reg, Shift);
86 return SelectShiftedRegister(
N,
true,
Reg, Shift);
89 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
95 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
98 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
101 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
104 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
107 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
116 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
119 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
122 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
131 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
134 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
137 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
139 template <
unsigned Size,
unsigned Max>
143 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
146 int64_t
C = CI->getSExtValue();
154 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
161 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
167 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
172 N =
N->getOperand(0);
176 EVT VT =
N->getValueType(0);
177 EVT LVT =
N->getOperand(0).getValueType();
178 unsigned Index =
N->getConstantOperandVal(1);
182 Res =
N->getOperand(0);
187 if (
N.getOpcode() != AArch64ISD::VLSHR)
190 EVT VT =
Op.getValueType();
191 unsigned ShtAmt =
N->getConstantOperandVal(1);
196 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
198 Op.getOperand(1).getConstantOperandVal(0)
199 <<
Op.getOperand(1).getConstantOperandVal(1));
200 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
203 Op.getOperand(1).getConstantOperandVal(0));
207 if (Imm != 1ULL << (ShtAmt - 1))
210 Res1 =
Op.getOperand(0);
211 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
215 bool SelectDupZeroOrUndef(
SDValue N) {
216 switch(
N->getOpcode()) {
219 case AArch64ISD::DUP:
221 auto Opnd0 =
N->getOperand(0);
235 bool SelectAny(
SDValue) {
return true; }
238 switch(
N->getOpcode()) {
239 case AArch64ISD::DUP:
241 auto Opnd0 =
N->getOperand(0);
253 template <MVT::SimpleValueType VT,
bool Negate>
255 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT>
265 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
268 template <MVT::SimpleValueType VT,
bool Invert = false>
270 return SelectSVELogicalImm(
N, VT, Imm, Invert);
273 template <MVT::SimpleValueType VT>
275 return SelectSVEArithImm(
N, VT, Imm);
278 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
280 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
287 EVT EltVT =
N->getValueType(0).getVectorElementType();
288 return SelectSVEShiftImm(
N->getOperand(0), 1,
294 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
301 MulImm = 1LL << MulImm;
303 if ((MulImm % std::abs(Scale)) != 0)
307 if ((MulImm >= Min) && (MulImm <= Max)) {
308 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
315 template <
signed Max,
signed Scale>
322 if (MulImm >= 0 && MulImm <= Max) {
324 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
331 template <
unsigned BaseReg,
unsigned Max>
339 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
362 const unsigned SubRegs[]);
364 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
366 bool tryIndexedLoad(
SDNode *
N);
368 void SelectPtrauthAuth(
SDNode *
N);
369 void SelectPtrauthResign(
SDNode *
N);
371 bool trySelectStackSlotTagP(
SDNode *
N);
374 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
376 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
380 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
381 unsigned Opc_rr,
unsigned Opc_ri,
382 bool IsIntr =
false);
383 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
384 unsigned Scale,
unsigned Opc_ri,
386 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
387 bool IsZmMulti,
unsigned Opcode,
388 bool HasPred =
false);
390 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
391 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
395 bool IsTupleInput,
unsigned Opc);
396 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 template <
unsigned MaxIdx,
unsigned Scale>
399 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
401 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
402 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
403 unsigned BaseReg = 0);
406 template <
int64_t Min,
int64_t Max>
410 template <
unsigned Scale>
412 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
415 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
420 template <
unsigned MaxIdx,
unsigned Scale>
425 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
430 unsigned Opc_rr,
unsigned Opc_ri);
431 std::tuple<unsigned, SDValue, SDValue>
432 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
436 bool tryBitfieldExtractOp(
SDNode *
N);
437 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
438 bool tryBitfieldInsertOp(
SDNode *
N);
439 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
440 bool tryShiftAmountMod(
SDNode *
N);
442 bool tryReadRegister(
SDNode *
N);
443 bool tryWriteRegister(
SDNode *
N);
445 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
446 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
451#include "AArch64GenDAGISel.inc"
459 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
461 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
474 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
475 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
476 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
479 template<
unsigned RegW
idth>
481 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
483 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
485 template <
unsigned RegW
idth>
487 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
489 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
491 template<
unsigned RegW
idth>
493 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
499 bool SelectCMP_SWAP(
SDNode *
N);
518 bool AllowSaturation,
SDValue &Imm);
526 bool SelectAllActivePredicate(
SDValue N);
531 template <
bool MatchCBB>
541 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
545char AArch64DAGToDAGISelLegacy::ID = 0;
553 auto getFloatVT = [&](
EVT VT) {
555 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
556 return VT.changeElementType(*(DAG.getContext()),
557 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
562 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
563 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
567 EVT OrigVT =
N.getValueType(0);
569 return DAG.getBitcast(OrigVT, OpNode);
576 Imm =
C->getZExtValue();
593 return N->getOpcode() ==
Opc &&
604 return Imm == ImmExpected;
609 assert(RegWidth == 32 || RegWidth == 64);
611 return APInt(RegWidth,
618 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
619 unsigned SplatWidth =
N.getScalarValueSizeInBits();
620 if (
N->getOpcode() == AArch64ISD::NVCAST) {
622 if (
Op.getOpcode() != AArch64ISD::FMOV ||
623 Op.getScalarValueSizeInBits() !=
N.getScalarValueSizeInBits())
627 if (
N->getOpcode() == AArch64ISD::MOVI)
628 return APInt(SplatWidth,
N.getConstantOperandVal(0));
629 if (
N->getOpcode() == AArch64ISD::MOVIshift)
630 return APInt(SplatWidth,
N.getConstantOperandVal(0)
631 <<
N.getConstantOperandVal(1));
632 if (
N->getOpcode() == AArch64ISD::MVNIshift)
633 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
634 <<
N.getConstantOperandVal(1));
635 if (
N->getOpcode() == AArch64ISD::DUP)
637 return Const->getAPIntValue().trunc(SplatWidth);
643bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
650 ImmVal->getZExtValue(), Encoding))
653 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
657bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
660 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
661 N.getValueType().getScalarType().getSimpleVT(),
667bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
670 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
674bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
676 std::vector<SDValue> &OutOps) {
677 switch(ConstraintID) {
680 case InlineAsm::ConstraintCode::m:
681 case InlineAsm::ConstraintCode::o:
682 case InlineAsm::ConstraintCode::Q:
686 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
688 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
690 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
691 dl,
Op.getValueType(),
693 OutOps.push_back(NewOp);
712 uint64_t Immed =
N.getNode()->getAsZExtVal();
715 if (Immed >> 12 == 0) {
717 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
725 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
726 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
743 uint64_t Immed =
N.getNode()->getAsZExtVal();
751 if (
N.getValueType() == MVT::i32)
752 Immed = ~((uint32_t)Immed) + 1;
754 Immed = ~Immed + 1ULL;
755 if (Immed & 0xFFFFFFFFFF000000ULL)
758 Immed &= 0xFFFFFFULL;
759 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
766 switch (
N.getOpcode()) {
792 unsigned ShiftVal = CSD->getZExtValue();
810bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
813 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
818 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
842 EVT VT =
N.getValueType();
843 if (VT != MVT::i32 && VT != MVT::i64)
846 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
852 unsigned LHSOpcode =
LHS->getOpcode();
866 unsigned LowZBits, MaskLen;
870 unsigned BitWidth =
N.getValueSizeInBits();
877 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
880 NewShiftC = LowZBits - ShiftAmtC;
881 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
887 NewShiftC = LowZBits + ShiftAmtC;
900 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
902 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
906 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
908 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
909 NewShiftAmt, BitWidthMinus1),
912 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
926 SrcVT =
N.getOperand(0).getValueType();
928 if (!IsLoadStore && SrcVT == MVT::i8)
930 else if (!IsLoadStore && SrcVT == MVT::i16)
932 else if (SrcVT == MVT::i32)
934 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
939 EVT SrcVT =
N.getOperand(0).getValueType();
940 if (!IsLoadStore && SrcVT == MVT::i8)
942 else if (!IsLoadStore && SrcVT == MVT::i16)
944 else if (SrcVT == MVT::i32)
946 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
974bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
977 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
982 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
983 V.getConstantOperandVal(1) <= 4 &&
996bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
998 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1008 unsigned BitSize =
N.getValueSizeInBits();
1009 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1012 Reg =
N.getOperand(0);
1013 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1014 return isWorthFoldingALU(
N,
true);
1025 if (
N.getValueType() == MVT::i32)
1033template<
signed Low,
signed High,
signed Scale>
1039 if ((MulImm % std::abs(Scale)) == 0) {
1040 int64_t RDVLImm = MulImm / Scale;
1041 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1042 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1051template <
signed Low,
signed High>
1052bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1057 if (MulImm >=
Low && MulImm <=
High) {
1058 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1069 unsigned ShiftVal = 0;
1084 Reg =
N.getOperand(0).getOperand(0);
1096 Op =
Op->getOperand(0);
1098 Op.getOperand(0).getValueType().isFixedLengthVector())
1102 Reg =
N.getOperand(0);
1107 unsigned Opc =
N.getOpcode();
1125 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1127 return isWorthFoldingALU(
N);
1134 unsigned ShiftVal = 0;
1148 Reg =
N.getOperand(0);
1149 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1151 return isWorthFoldingALU(
N);
1160 for (
auto *
User :
N->users()) {
1187bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1188 unsigned BW,
unsigned Size,
1192 const DataLayout &
DL = CurDAG->getDataLayout();
1193 const TargetLowering *TLI = getTargetLowering();
1197 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1203 if (CurDAG->isBaseWithConstantOffset(
N)) {
1206 int64_t RHSC =
RHS->getSExtValue();
1208 int64_t
Range = 0x1LL << (BW - 1);
1210 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1211 RHSC < (
Range << Scale)) {
1212 Base =
N.getOperand(0);
1217 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1222 uint64_t RHSC =
RHS->getZExtValue();
1224 uint64_t
Range = 0x1ULL << BW;
1226 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1227 Base =
N.getOperand(0);
1232 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1243 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1250bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1253 const DataLayout &
DL = CurDAG->getDataLayout();
1254 const TargetLowering *TLI = getTargetLowering();
1258 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1263 GlobalAddressSDNode *GAN =
1265 Base =
N.getOperand(0);
1275 if (CurDAG->isBaseWithConstantOffset(
N)) {
1277 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1280 Base =
N.getOperand(0);
1285 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1293 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1301 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1310bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1313 if (!CurDAG->isBaseWithConstantOffset(
N))
1316 int64_t RHSC =
RHS->getSExtValue();
1317 if (RHSC >= -256 && RHSC < 256) {
1318 Base =
N.getOperand(0);
1321 const TargetLowering *TLI = getTargetLowering();
1322 Base = CurDAG->getTargetFrameIndex(
1325 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1335 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1342bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1362 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1368 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1371 return isWorthFoldingAddr(
N,
Size);
1374bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1392 const SDNode *
Node =
N.getNode();
1393 for (SDNode *UI :
Node->users()) {
1399 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1402 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1405 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1410 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1413 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1418 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1422 if (IsExtendedRegisterWorthFolding &&
1429 if (isWorthFoldingAddr(
LHS,
Size))
1434 if (IsExtendedRegisterWorthFolding &&
1441 if (isWorthFoldingAddr(
RHS,
Size))
1453 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1456 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1458 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1459 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1463bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1476 const SDNode *
Node =
N.getNode();
1477 for (SDNode *UI :
Node->users()) {
1494 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1504 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1511 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1514 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1517 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1522 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1525 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1532 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1533 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1539 static const unsigned RegClassIDs[] = {
1540 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1541 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1542 AArch64::dsub2, AArch64::dsub3};
1548 static const unsigned RegClassIDs[] = {
1549 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1550 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1551 AArch64::qsub2, AArch64::qsub3};
1557 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1558 AArch64::ZPR3RegClassID,
1559 AArch64::ZPR4RegClassID};
1560 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1561 AArch64::zsub2, AArch64::zsub3};
1571 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1572 AArch64::ZPR4Mul4RegClassID};
1573 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1574 AArch64::zsub2, AArch64::zsub3};
1579 const unsigned RegClassIDs[],
1580 const unsigned SubRegs[]) {
1583 if (Regs.
size() == 1)
1594 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1597 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1598 Ops.push_back(Regs[i]);
1599 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1603 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1607void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1610 EVT VT =
N->getValueType(0);
1612 unsigned ExtOff = isExt;
1615 unsigned Vec0Off = ExtOff + 1;
1621 Ops.push_back(
N->getOperand(1));
1622 Ops.push_back(RegSeq);
1623 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1624 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1627static std::tuple<SDValue, SDValue>
1648 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1653 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1655 return std::make_tuple(
1660void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1665 SDValue AUTDisc =
N->getOperand(3);
1668 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1670 SDValue AUTAddrDisc, AUTConstDisc;
1671 std::tie(AUTConstDisc, AUTAddrDisc) =
1675 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1677 if (
N->getNumOperands() > 4)
1678 Ops.push_back(
N->getOperand(4));
1681 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1682 ReplaceNode(
N, AUT);
1684 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1685 AArch64::X16, Val,
SDValue());
1688 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1689 ReplaceNode(
N, AUT);
1693void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1703 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1708 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1709 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1711 SDValue AUTAddrDisc, AUTConstDisc;
1712 std::tie(AUTConstDisc, AUTAddrDisc) =
1715 SDValue PACAddrDisc, PACConstDisc;
1716 std::tie(PACConstDisc, PACAddrDisc) =
1719 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1720 AArch64::X16, Val,
SDValue());
1723 SDValue Addend =
N->getOperand(OffsetBase + 6);
1724 SDValue IncomingChain =
N->getOperand(0);
1725 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1726 PACKey, PACConstDisc, PACAddrDisc,
1727 Addend, IncomingChain, X16Copy.
getValue(1)};
1729 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1730 MVT::i64, MVT::Other,
Ops);
1731 ReplaceNode(
N, AUTRELLOADPAC);
1733 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1734 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1736 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1737 ReplaceNode(
N, AUTPAC);
1741bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1743 if (
LD->isUnindexed())
1745 EVT VT =
LD->getMemoryVT();
1746 EVT DstVT =
N->getValueType(0);
1750 int OffsetVal = (int)
OffsetOp->getZExtValue();
1755 unsigned Opcode = 0;
1758 bool InsertTo64 =
false;
1760 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1761 else if (VT == MVT::i32) {
1763 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1765 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1767 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1773 }
else if (VT == MVT::i16) {
1775 if (DstVT == MVT::i64)
1776 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1778 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1780 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1781 InsertTo64 = DstVT == MVT::i64;
1786 }
else if (VT == MVT::i8) {
1788 if (DstVT == MVT::i64)
1789 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1791 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1793 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1794 InsertTo64 = DstVT == MVT::i64;
1799 }
else if (VT == MVT::f16) {
1800 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1801 }
else if (VT == MVT::bf16) {
1802 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1803 }
else if (VT == MVT::f32) {
1804 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1805 }
else if (VT == MVT::f64 ||
1807 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1809 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1811 if (IsPre || OffsetVal != 8)
1815 Opcode = AArch64::LD1Onev8b_POST;
1818 Opcode = AArch64::LD1Onev4h_POST;
1821 Opcode = AArch64::LD1Onev2s_POST;
1824 Opcode = AArch64::LD1Onev1d_POST;
1830 if (IsPre || OffsetVal != 16)
1834 Opcode = AArch64::LD1Onev16b_POST;
1837 Opcode = AArch64::LD1Onev8h_POST;
1840 Opcode = AArch64::LD1Onev4s_POST;
1843 Opcode = AArch64::LD1Onev2d_POST;
1855 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1856 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1858 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1868 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1869 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1870 MVT::i64, LoadedVal, SubReg),
1874 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1877 CurDAG->RemoveDeadNode(
N);
1881void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1882 unsigned SubRegIdx) {
1884 EVT VT =
N->getValueType(0);
1890 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1892 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1894 for (
unsigned i = 0; i < NumVecs; ++i)
1896 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1903 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1907 CurDAG->RemoveDeadNode(
N);
1910void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1911 unsigned Opc,
unsigned SubRegIdx) {
1913 EVT VT =
N->getValueType(0);
1920 const EVT ResTys[] = {MVT::i64,
1921 MVT::Untyped, MVT::Other};
1923 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1931 ReplaceUses(
SDValue(
N, 0), SuperReg);
1933 for (
unsigned i = 0; i < NumVecs; ++i)
1935 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1939 CurDAG->RemoveDeadNode(
N);
1945std::tuple<unsigned, SDValue, SDValue>
1946AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1952 SDValue NewOffset = OldOffset;
1954 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1955 N, OldBase, NewBase, NewOffset);
1959 const bool IsRegReg =
1960 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1963 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1976template <SelectTypeKind Kind>
1988 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1993 if (EltVT != MVT::i1)
1997 if (EltVT == MVT::bf16)
1999 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2029void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2032 if (
Imm->getZExtValue() > 1)
2036 EVT VT =
N->getValueType(0);
2038 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2041 for (
unsigned I = 0;
I < 2; ++
I)
2042 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2043 AArch64::psub0 +
I,
DL, VT, SuperReg));
2045 CurDAG->RemoveDeadNode(
N);
2048void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2050 EVT VT =
N->getValueType(0);
2054 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2057 for (
unsigned I = 0;
I < 2; ++
I)
2058 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2059 AArch64::psub0 +
I,
DL, VT, SuperReg));
2061 CurDAG->RemoveDeadNode(
N);
2064void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2066 EVT VT =
N->getValueType(0);
2070 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2072 for (
unsigned i = 0; i < NumVecs; ++i)
2073 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2074 AArch64::zsub0 + i,
DL, VT, SuperReg));
2076 CurDAG->RemoveDeadNode(
N);
2079void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2082 EVT VT =
N->getValueType(0);
2084 Ops.push_back(
N->getOperand(0));
2087 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2090 for (
unsigned i = 0; i < NumVecs; ++i)
2091 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2092 AArch64::zsub0 + i,
DL, VT, SuperReg));
2095 unsigned ChainIdx = NumVecs;
2097 CurDAG->RemoveDeadNode(
N);
2100void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2105 assert(Opcode != 0 &&
"Unexpected opcode");
2108 EVT VT =
N->getValueType(0);
2109 SDUse *OpsIter =
N->op_begin() + 1;
2112 auto GetMultiVecOperand = [&]() {
2115 return createZMulTuple(Regs);
2119 Ops.push_back(*OpsIter++);
2121 Ops.push_back(GetMultiVecOperand());
2123 Ops.push_back(GetMultiVecOperand());
2125 Ops.push_back(*OpsIter++);
2128 Ops.append(OpsIter,
N->op_end());
2130 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2132 for (
unsigned i = 0; i < NumVecs; ++i)
2133 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2134 AArch64::zsub0 + i,
DL, VT, SuperReg));
2136 CurDAG->RemoveDeadNode(
N);
2139void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2140 unsigned Scale,
unsigned Opc_ri,
2141 unsigned Opc_rr,
bool IsIntr) {
2142 assert(Scale < 5 &&
"Invalid scaling value.");
2144 EVT VT =
N->getValueType(0);
2151 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2152 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2158 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2160 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2162 for (
unsigned i = 0; i < NumVecs; ++i)
2163 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2164 AArch64::zsub0 + i,
DL, VT, SuperReg));
2167 unsigned ChainIdx = NumVecs;
2169 CurDAG->RemoveDeadNode(
N);
2172void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2177 assert(Scale < 4 &&
"Invalid scaling value.");
2179 EVT VT =
N->getValueType(0);
2187 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2193 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2195 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2197 for (
unsigned i = 0; i < NumVecs; ++i)
2198 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2199 AArch64::zsub0 + i,
DL, VT, SuperReg));
2202 unsigned ChainIdx = NumVecs;
2204 CurDAG->RemoveDeadNode(
N);
2207void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2209 if (
N->getValueType(0) != MVT::nxv4f32)
2211 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2214void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2215 unsigned NumOutVecs,
2219 if (
Imm->getZExtValue() > MaxImm)
2223 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2229 EVT VT =
Node->getValueType(0);
2232 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2235 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2236 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2237 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2240 unsigned ChainIdx = NumOutVecs;
2242 CurDAG->RemoveDeadNode(Node);
2245void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2246 unsigned NumOutVecs,
2249 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2254 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2258 EVT VT =
Node->getValueType(0);
2261 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2264 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2265 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2266 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2269 unsigned ChainIdx = NumOutVecs;
2271 CurDAG->RemoveDeadNode(Node);
2274void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2277 EVT VT =
N->getValueType(0);
2280 SDValue Zd = createZMulTuple(Regs);
2281 SDValue Zn =
N->getOperand(1 + NumVecs);
2282 SDValue Zm =
N->getOperand(2 + NumVecs);
2288 for (
unsigned i = 0; i < NumVecs; ++i)
2289 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2290 AArch64::zsub0 + i,
DL, VT, SuperReg));
2292 CurDAG->RemoveDeadNode(
N);
2322template <
unsigned MaxIdx,
unsigned Scale>
2323void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2324 unsigned BaseReg,
unsigned Op) {
2325 unsigned TileNum = 0;
2326 if (BaseReg != AArch64::ZA)
2327 TileNum =
N->getConstantOperandVal(2);
2333 if (BaseReg == AArch64::ZA)
2338 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2342 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2344 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2346 EVT VT =
N->getValueType(0);
2347 for (
unsigned I = 0;
I < NumVecs; ++
I)
2349 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2352 unsigned ChainIdx = NumVecs;
2354 CurDAG->RemoveDeadNode(
N);
2357void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2358 unsigned Op,
unsigned MaxIdx,
2359 unsigned Scale,
unsigned BaseReg) {
2364 if (BaseReg != AArch64::ZA)
2368 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2375 if (BaseReg != AArch64::ZA )
2376 Ops.push_back(
N->getOperand(2));
2379 Ops.push_back(
N->getOperand(0));
2380 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2382 EVT VT =
N->getValueType(0);
2383 for (
unsigned I = 0;
I < NumVecs; ++
I)
2385 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2389 unsigned ChainIdx = NumVecs;
2391 CurDAG->RemoveDeadNode(
N);
2394void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2395 unsigned NumOutVecs,
2399 EVT VT =
N->getValueType(0);
2400 unsigned NumInVecs =
N->getNumOperands() - 1;
2404 assert((NumInVecs == 2 || NumInVecs == 4) &&
2405 "Don't know how to handle multi-register input!");
2407 Ops.push_back(createZMulTuple(Regs));
2410 for (
unsigned I = 0;
I < NumInVecs;
I++)
2411 Ops.push_back(
N->getOperand(1 +
I));
2414 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2417 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2418 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2419 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2420 CurDAG->RemoveDeadNode(
N);
2423void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2426 EVT VT =
N->getOperand(2)->getValueType(0);
2434 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2443void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2444 unsigned Scale,
unsigned Opc_rr,
2450 SDValue RegSeq = createZTuple(Regs);
2456 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2457 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2463 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2471 const DataLayout &
DL = CurDAG->getDataLayout();
2472 const TargetLowering *TLI = getTargetLowering();
2476 int FI = FINode->getIndex();
2478 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2485void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2488 EVT VT =
N->getOperand(2)->getValueType(0);
2489 const EVT ResTys[] = {MVT::i64,
2501 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2541void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2544 EVT VT =
N->getValueType(0);
2556 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2558 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2560 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2562 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2566 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2567 AArch64::qsub2, AArch64::qsub3 };
2568 for (
unsigned i = 0; i < NumVecs; ++i) {
2569 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2576 CurDAG->RemoveDeadNode(
N);
2579void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2582 EVT VT =
N->getValueType(0);
2594 const EVT ResTys[] = {MVT::i64,
2597 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2600 CurDAG->getTargetConstant(LaneNo, dl,
2605 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2617 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2618 AArch64::qsub2, AArch64::qsub3 };
2619 for (
unsigned i = 0; i < NumVecs; ++i) {
2620 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2630 CurDAG->RemoveDeadNode(
N);
2633void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2636 EVT VT =
N->getOperand(2)->getValueType(0);
2648 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2650 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2652 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2661void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2664 EVT VT =
N->getOperand(2)->getValueType(0);
2676 const EVT ResTys[] = {MVT::i64,
2679 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2681 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2685 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2696 unsigned &LSB,
unsigned &MSB,
2697 unsigned NumberOfIgnoredLowBits,
2698 bool BiggerPattern) {
2700 "N must be a AND operation to call this function");
2702 EVT VT =
N->getValueType(0);
2707 assert((VT == MVT::i32 || VT == MVT::i64) &&
2708 "Type checking must have been done before calling this function");
2722 const SDNode *Op0 =
N->getOperand(0).getNode();
2729 if (AndImm & (AndImm + 1))
2732 bool ClampMSB =
false;
2752 ClampMSB = (VT == MVT::i32);
2753 }
else if (BiggerPattern) {
2759 Opd0 =
N->getOperand(0);
2765 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2768 <<
": Found large shift immediate, this should not happen\n"));
2782 MSB = MSB > 31 ? 31 : MSB;
2784 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2789 SDValue &Opd0,
unsigned &Immr,
2793 EVT VT =
N->getValueType(0);
2795 assert((VT == MVT::i32 || VT == MVT::i64) &&
2796 "Type checking must have been done before calling this function");
2800 Op =
Op->getOperand(0);
2801 VT =
Op->getValueType(0);
2810 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2814 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2815 Opd0 =
Op.getOperand(0);
2817 Imms = ShiftImm + Width - 1;
2845 Opd0 =
N->getOperand(0).getOperand(0);
2855 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2862 unsigned &Immr,
unsigned &Imms,
2863 bool BiggerPattern) {
2865 "N must be a SHR/SRA operation to call this function");
2867 EVT VT =
N->getValueType(0);
2872 assert((VT == MVT::i32 || VT == MVT::i64) &&
2873 "Type checking must have been done before calling this function");
2883 Opd0 =
N->getOperand(0).getOperand(0);
2884 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2890 Opd0 =
N->getOperand(0).getOperand(0);
2893 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2894 }
else if (BiggerPattern) {
2898 Opd0 =
N->getOperand(0);
2907 <<
": Found large shift immediate, this should not happen\n"));
2916 "bad amount in shift node!");
2917 int immr = SrlImm - ShlImm;
2922 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2924 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2928bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2931 EVT VT =
N->getValueType(0);
2932 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2933 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2944 unsigned Immr = ShiftImm;
2946 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2947 CurDAG->getTargetConstant(Imms, dl, VT)};
2948 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2953 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2954 unsigned NumberOfIgnoredLowBits = 0,
2955 bool BiggerPattern =
false) {
2956 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2959 switch (
N->getOpcode()) {
2961 if (!
N->isMachineOpcode())
2966 NumberOfIgnoredLowBits, BiggerPattern);
2975 unsigned NOpc =
N->getMachineOpcode();
2979 case AArch64::SBFMWri:
2980 case AArch64::UBFMWri:
2981 case AArch64::SBFMXri:
2982 case AArch64::UBFMXri:
2984 Opd0 =
N->getOperand(0);
2985 Immr =
N->getConstantOperandVal(1);
2986 Imms =
N->getConstantOperandVal(2);
2993bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
2994 unsigned Opc, Immr, Imms;
2999 EVT VT =
N->getValueType(0);
3004 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3005 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3006 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3008 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3009 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3015 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3016 CurDAG->getTargetConstant(Imms, dl, VT)};
3017 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3026 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3027 assert((VT == MVT::i32 || VT == MVT::i64) &&
3028 "i32 or i64 mask type expected!");
3032 APInt SignificantDstMask =
3036 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3037 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3070 APInt OpUsefulBits(UsefulBits);
3074 OpUsefulBits <<= MSB - Imm + 1;
3079 OpUsefulBits <<= Imm;
3081 OpUsefulBits <<= MSB + 1;
3084 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3090 UsefulBits &= OpUsefulBits;
3107 APInt Mask(UsefulBits);
3108 Mask.clearAllBits();
3116 Mask.lshrInPlace(ShiftAmt);
3122 Mask.lshrInPlace(ShiftAmt);
3138 APInt OpUsefulBits(UsefulBits);
3152 OpUsefulBits <<= Width;
3155 if (
Op.getOperand(1) == Orig) {
3157 Mask = ResultUsefulBits & OpUsefulBits;
3161 if (
Op.getOperand(0) == Orig)
3163 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3169 OpUsefulBits <<= Width;
3171 OpUsefulBits <<= LSB;
3173 if (
Op.getOperand(1) == Orig) {
3175 Mask = ResultUsefulBits & OpUsefulBits;
3176 Mask.lshrInPlace(LSB);
3179 if (
Op.getOperand(0) == Orig)
3180 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3197 case AArch64::ANDSWri:
3198 case AArch64::ANDSXri:
3199 case AArch64::ANDWri:
3200 case AArch64::ANDXri:
3204 case AArch64::UBFMWri:
3205 case AArch64::UBFMXri:
3208 case AArch64::ORRWrs:
3209 case AArch64::ORRXrs:
3214 case AArch64::BFMWri:
3215 case AArch64::BFMXri:
3218 case AArch64::STRBBui:
3219 case AArch64::STURBBi:
3225 case AArch64::STRHHui:
3226 case AArch64::STURHHi:
3239 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3241 UsefulBits =
APInt(Bitwidth, 0);
3250 UsersUsefulBits |= UsefulBitsForUse;
3255 UsefulBits &= UsersUsefulBits;
3265 EVT VT =
Op.getValueType();
3268 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3271 if (ShlAmount > 0) {
3274 UBFMOpc, dl, VT,
Op,
3279 assert(ShlAmount < 0 &&
"expected right shift");
3280 int ShrAmount = -ShlAmount;
3292 const uint64_t NonZeroBits,
3299 const uint64_t NonZeroBits,
3306 bool BiggerPattern,
SDValue &Src,
3307 int &DstLSB,
int &Width) {
3308 EVT VT =
Op.getValueType();
3317 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3321 switch (
Op.getOpcode()) {
3326 NonZeroBits, Src, DstLSB, Width);
3329 NonZeroBits, Src, DstLSB, Width);
3342 EVT VT =
Op.getValueType();
3343 assert((VT == MVT::i32 || VT == MVT::i64) &&
3344 "Caller guarantees VT is one of i32 or i64");
3357 assert((~AndImm & NonZeroBits) == 0 &&
3358 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3387 if (!BiggerPattern && !AndOp0.
hasOneUse())
3406 <<
"Found large Width in bit-field-positioning -- this indicates no "
3407 "proper combining / constant folding was performed\n");
3416 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3431 "Op.getNode() should be a SHL node to call this function");
3433 "Op.getNode() should shift ShlImm to call this function");
3440 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3464 EVT VT =
Op.getValueType();
3465 assert((VT == MVT::i32 || VT == MVT::i64) &&
3466 "Caller guarantees that type is i32 or i64");
3473 if (!BiggerPattern && !
Op.hasOneUse())
3482 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3490 assert(VT == MVT::i32 || VT == MVT::i64);
3501 EVT VT =
N->getValueType(0);
3502 if (VT != MVT::i32 && VT != MVT::i64)
3520 if (!
And.hasOneUse() ||
3530 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3537 if ((OrImm & NotKnownZero) != 0) {
3549 unsigned ImmS = Width - 1;
3555 bool IsBFI = LSB != 0;
3560 unsigned OrChunks = 0, BFIChunks = 0;
3561 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3562 if (((OrImm >> Shift) & 0xFFFF) != 0)
3564 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3567 if (BFIChunks > OrChunks)
3573 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3581 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3590 if (!Dst.hasOneUse())
3593 EVT VT = Dst.getValueType();
3594 assert((VT == MVT::i32 || VT == MVT::i64) &&
3595 "Caller should guarantee that VT is one of i32 or i64");
3623 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3624 unsigned MaskWidth =
3627 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3633 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3634 ShiftedOperand =
SDValue(UBFMNode, 0);
3663 const bool BiggerPattern) {
3664 EVT VT =
N->getValueType(0);
3665 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3666 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3667 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3668 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3669 assert((VT == MVT::i32 || VT == MVT::i64) &&
3670 "Expect result type to be i32 or i64 since N is combinable to BFM");
3677 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3680 if (BiggerPattern) {
3703 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3765 EVT VT =
N->getValueType(0);
3766 if (VT != MVT::i32 && VT != MVT::i64)
3774 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3775 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3795 for (
int I = 0;
I < 4; ++
I) {
3798 unsigned ImmR, ImmS;
3799 bool BiggerPattern =
I / 2;
3800 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3802 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3808 NumberOfIgnoredLowBits, BiggerPattern)) {
3811 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3812 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3817 Width = ImmS - ImmR + 1;
3828 Src, DstLSB, Width)) {
3836 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3846 APInt BitsToBeInserted =
3849 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3873 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3906 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3908 if (Src->hasOneUse() &&
3911 Src = Src->getOperand(0);
3921 unsigned ImmS = Width - 1;
3927 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3935bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3944 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3957bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3961 EVT VT =
N->getValueType(0);
3962 if (VT != MVT::i32 && VT != MVT::i64)
3968 Op0, DstLSB, Width))
3974 unsigned ImmS = Width - 1;
3977 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3978 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3979 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3980 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3986bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
3987 EVT VT =
N->getValueType(0);
3990 switch (
N->getOpcode()) {
3992 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3995 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3998 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4001 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4009 if (VT == MVT::i32) {
4012 }
else if (VT == MVT::i64) {
4018 SDValue ShiftAmt =
N->getOperand(1);
4038 (Add0Imm %
Size == 0)) {
4044 if (SubVT == MVT::i32) {
4045 NegOpc = AArch64::SUBWrr;
4046 ZeroReg = AArch64::WZR;
4048 assert(SubVT == MVT::i64);
4049 NegOpc = AArch64::SUBXrr;
4050 ZeroReg = AArch64::XZR;
4053 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4054 MachineSDNode *Neg =
4055 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4056 NewShiftAmt =
SDValue(Neg, 0);
4064 if (SubVT == MVT::i32) {
4065 NotOpc = AArch64::ORNWrr;
4066 ZeroReg = AArch64::WZR;
4068 assert(SubVT == MVT::i64);
4069 NotOpc = AArch64::ORNXrr;
4070 ZeroReg = AArch64::XZR;
4073 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4074 MachineSDNode *
Not =
4075 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4076 NewShiftAmt =
SDValue(Not, 0);
4097 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4098 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4099 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4100 NewShiftAmt, SubReg);
4101 NewShiftAmt =
SDValue(Ext, 0);
4105 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4112 bool isReciprocal) {
4115 FVal = CN->getValueAPF();
4118 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4128 if (
unsigned FBits =
4137bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4138 unsigned RegWidth) {
4143bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4144 unsigned RegWidth) {
4145 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4146 N.getValueType().getScalarSizeInBits() ==
4147 N.getOperand(0).getValueType().getScalarSizeInBits())
4148 N =
N.getOperand(0);
4150 auto ImmToFloat = [RegWidth](APInt
Imm) {
4153 return APFloat(APFloat::IEEEhalf(), Imm);
4155 return APFloat(APFloat::IEEEsingle(), Imm);
4157 return APFloat(APFloat::IEEEdouble(), Imm);
4164 switch (
N->getOpcode()) {
4165 case AArch64ISD::MOVIshift:
4166 FVal = ImmToFloat(APInt(RegWidth,
N.getConstantOperandVal(0)
4167 <<
N.getConstantOperandVal(1)));
4169 case AArch64ISD::FMOV:
4170 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4172 case AArch64ISD::DUP:
4174 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4184 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(
N), MVT::i32);
4191bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4193 unsigned RegWidth) {
4203 RegString.
split(Fields,
':');
4205 if (Fields.
size() == 1)
4209 &&
"Invalid number of fields in read register string");
4212 bool AllIntFields =
true;
4216 AllIntFields &= !
Field.getAsInteger(10, IntField);
4217 Ops.push_back(IntField);
4221 "Unexpected non-integer value in special register string.");
4226 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4227 (
Ops[3] << 3) | (
Ops[4]);
4234bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4236 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4239 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4241 unsigned Opcode64Bit = AArch64::MRS;
4246 const auto *TheReg =
4247 AArch64SysReg::lookupSysRegByName(RegString->getString());
4248 if (TheReg && TheReg->Readable &&
4249 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4250 Imm = TheReg->Encoding;
4256 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4257 Opcode64Bit = AArch64::ADR;
4265 SDValue InChain =
N->getOperand(0);
4266 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4267 if (!ReadIs128Bit) {
4268 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4269 {SysRegImm, InChain});
4271 SDNode *MRRS = CurDAG->getMachineNode(
4273 {MVT::Untyped , MVT::Other },
4274 {SysRegImm, InChain});
4278 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4280 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4286 ReplaceUses(
SDValue(
N, 2), OutChain);
4295bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4297 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4300 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4302 if (!WriteIs128Bit) {
4308 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4311 "Expected a constant integer expression.");
4312 unsigned Reg = PMapper->Encoding;
4313 uint64_t Immed =
N->getConstantOperandVal(2);
4314 CurDAG->SelectNodeTo(
4315 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4316 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4322 if (trySelectPState(
4323 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4324 AArch64::MSRpstateImm4))
4326 if (trySelectPState(
4327 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4328 AArch64::MSRpstateImm1))
4337 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4338 if (TheReg && TheReg->Writeable &&
4339 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4340 Imm = TheReg->Encoding;
4349 if (!WriteIs128Bit) {
4350 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4351 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4352 N->getOperand(2), InChain);
4356 SDNode *Pair = CurDAG->getMachineNode(
4357 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4358 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4361 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4363 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4365 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4366 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4374bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4379 if (Subtarget->hasLSE())
return false;
4381 if (MemTy == MVT::i8)
4382 Opcode = AArch64::CMP_SWAP_8;
4383 else if (MemTy == MVT::i16)
4384 Opcode = AArch64::CMP_SWAP_16;
4385 else if (MemTy == MVT::i32)
4386 Opcode = AArch64::CMP_SWAP_32;
4387 else if (MemTy == MVT::i64)
4388 Opcode = AArch64::CMP_SWAP_64;
4392 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4393 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4395 SDNode *CmpSwap = CurDAG->getMachineNode(
4397 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4404 CurDAG->RemoveDeadNode(
N);
4409bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4410 SDValue &Shift,
bool Negate) {
4417 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4420bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4429 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4436 if ((Val & ~0xff) == 0) {
4437 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4442 if ((Val & ~0xff00) == 0) {
4443 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4455bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4479 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4480 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4487 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4488 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4492 if (Val <= 65280 && Val % 256 == 0) {
4493 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4494 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4505bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4515 int32_t ImmVal, ShiftVal;
4520 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4521 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4525bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4527 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4531bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4534 if (ImmVal >= -128 && ImmVal < 128) {
4535 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4541bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4543 uint64_t ImmVal = CNode->getZExtValue();
4553 ImmVal &= 0xFFFFFFFF;
4562 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4569bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4573 ImmVal = CI->getZExtValue();
4575 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4586 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4595bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4596 uint64_t
High,
bool AllowSaturation,
4599 uint64_t ImmVal = CN->getZExtValue();
4606 if (ImmVal >
High) {
4607 if (!AllowSaturation)
4612 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4619bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4633 const TargetLowering *TLI = getTargetLowering();
4636 SDValue FiOp = CurDAG->getTargetFrameIndex(
4638 int TagOffset =
N->getConstantOperandVal(3);
4640 SDNode *Out = CurDAG->getMachineNode(
4641 AArch64::TAGPstack,
DL, MVT::i64,
4642 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4643 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4644 ReplaceNode(
N, Out);
4648void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4650 "llvm.aarch64.tagp third argument must be an immediate");
4651 if (trySelectStackSlotTagP(
N))
4658 int TagOffset =
N->getConstantOperandVal(3);
4659 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4660 {
N->getOperand(1),
N->getOperand(2)});
4661 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4662 {
SDValue(N1, 0),
N->getOperand(2)});
4663 SDNode *N3 = CurDAG->getMachineNode(
4664 AArch64::ADDG,
DL, MVT::i64,
4665 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4666 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4670bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4674 if (
N->getConstantOperandVal(2) != 0)
4676 if (!
N->getOperand(0).isUndef())
4680 EVT VT =
N->getValueType(0);
4681 EVT InVT =
N->getOperand(1).getValueType();
4692 "Expected to insert into a packed scalable vector!");
4695 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4696 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4697 N->getOperand(1), RC));
4701bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4705 if (
N->getConstantOperandVal(1) != 0)
4709 EVT VT =
N->getValueType(0);
4710 EVT InVT =
N->getOperand(0).getValueType();
4721 "Expected to extract from a packed scalable vector!");
4724 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4725 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4726 N->getOperand(0), RC));
4730bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4736 EVT VT =
N->getValueType(0);
4749 (Subtarget->hasSVE2() ||
4750 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4751 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4754 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4758 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4759 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4760 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4767 bool IsXOROperand =
true;
4769 IsXOROperand =
false;
4775 APInt ShlAmt, ShrAmt;
4783 if (!IsXOROperand) {
4785 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4788 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4789 SDNode *SubRegToReg =
4790 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4801 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4802 AArch64::XAR_ZZZI_D})) {
4803 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4828 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4838 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4846 bool IsXOROperand =
true;
4848 IsXOROperand =
false;
4851 R1 =
XOR.getOperand(0);
4852 R2 =
XOR.getOperand(1);
4862 if (ShAmt + HsAmt != VTSizeInBits)
4865 if (!IsXOROperand) {
4868 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4877 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4883 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4884 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4886 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4889 if (
R2.getValueType() == VT)
4890 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4895 SDValue SubReg = CurDAG->getTargetConstant(
4898 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4903 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4909 SDNode *XAR =
nullptr;
4913 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4914 AArch64::XAR_ZZZI_D}))
4915 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4917 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4920 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4926 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4927 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4930 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4931 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4934 SDValue SubReg = CurDAG->getTargetConstant(
4937 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4941 ReplaceNode(
N, XAR);
4945void AArch64DAGToDAGISel::Select(SDNode *Node) {
4947 if (
Node->isMachineOpcode()) {
4949 Node->setNodeId(-1);
4954 EVT VT =
Node->getValueType(0);
4956 switch (
Node->getOpcode()) {
4961 if (SelectCMP_SWAP(Node))
4966 case AArch64ISD::MRRS:
4967 if (tryReadRegister(Node))
4972 case AArch64ISD::MSRR:
4973 if (tryWriteRegister(Node))
4980 if (tryIndexedLoad(Node))
4989 if (tryBitfieldExtractOp(Node))
4991 if (tryBitfieldInsertInZeroOp(Node))
4996 if (tryShiftAmountMod(Node))
5001 if (tryBitfieldExtractOpFromSExt(Node))
5006 if (tryBitfieldInsertOp(Node))
5008 if (trySelectXAR(Node))
5013 if (trySelectCastScalableToFixedLengthVector(Node))
5019 if (trySelectCastFixedLengthToScalableVector(Node))
5028 if (ConstNode->
isZero()) {
5029 if (VT == MVT::i32) {
5031 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5032 ReplaceNode(Node,
New.getNode());
5034 }
else if (VT == MVT::i64) {
5036 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5037 ReplaceNode(Node,
New.getNode());
5048 const TargetLowering *TLI = getTargetLowering();
5049 SDValue TFI = CurDAG->getTargetFrameIndex(
5052 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5053 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5054 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5058 unsigned IntNo =
Node->getConstantOperandVal(1);
5062 case Intrinsic::aarch64_gcsss: {
5066 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5068 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5069 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5070 MVT::Other, Zero,
SDValue(SS1, 0));
5071 ReplaceNode(Node, SS2);
5074 case Intrinsic::aarch64_ldaxp:
5075 case Intrinsic::aarch64_ldxp: {
5077 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5082 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5083 MVT::Other, MemAddr, Chain);
5086 MachineMemOperand *MemOp =
5089 ReplaceNode(Node, Ld);
5092 case Intrinsic::aarch64_stlxp:
5093 case Intrinsic::aarch64_stxp: {
5095 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5103 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5105 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5107 MachineMemOperand *MemOp =
5111 ReplaceNode(Node, St);
5114 case Intrinsic::aarch64_neon_ld1x2:
5115 if (VT == MVT::v8i8) {
5116 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5118 }
else if (VT == MVT::v16i8) {
5119 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5121 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5122 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5124 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5125 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5127 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5128 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5130 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5131 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5133 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5134 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5136 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5137 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5141 case Intrinsic::aarch64_neon_ld1x3:
5142 if (VT == MVT::v8i8) {
5143 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5145 }
else if (VT == MVT::v16i8) {
5146 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5148 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5149 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5151 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5152 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5154 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5155 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5157 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5158 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5160 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5161 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5163 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5164 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5168 case Intrinsic::aarch64_neon_ld1x4:
5169 if (VT == MVT::v8i8) {
5170 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5172 }
else if (VT == MVT::v16i8) {
5173 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5175 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5176 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5178 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5179 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5181 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5182 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5184 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5185 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5187 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5188 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5190 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5191 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5195 case Intrinsic::aarch64_neon_ld2:
5196 if (VT == MVT::v8i8) {
5197 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5199 }
else if (VT == MVT::v16i8) {
5200 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5202 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5203 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5205 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5206 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5208 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5209 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5211 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5212 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5214 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5215 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5217 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5218 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5222 case Intrinsic::aarch64_neon_ld3:
5223 if (VT == MVT::v8i8) {
5224 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5226 }
else if (VT == MVT::v16i8) {
5227 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5229 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5230 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5232 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5233 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5235 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5236 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5238 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5239 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5241 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5242 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5244 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5245 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5249 case Intrinsic::aarch64_neon_ld4:
5250 if (VT == MVT::v8i8) {
5251 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5253 }
else if (VT == MVT::v16i8) {
5254 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5256 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5257 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5259 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5260 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5262 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5263 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5265 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5266 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5268 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5269 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5271 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5272 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5276 case Intrinsic::aarch64_neon_ld2r:
5277 if (VT == MVT::v8i8) {
5278 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5280 }
else if (VT == MVT::v16i8) {
5281 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5283 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5284 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5286 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5287 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5289 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5290 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5292 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5293 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5295 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5296 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5298 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5299 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5303 case Intrinsic::aarch64_neon_ld3r:
5304 if (VT == MVT::v8i8) {
5305 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5307 }
else if (VT == MVT::v16i8) {
5308 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5310 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5311 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5313 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5314 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5316 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5317 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5319 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5320 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5322 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5323 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5325 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5326 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5330 case Intrinsic::aarch64_neon_ld4r:
5331 if (VT == MVT::v8i8) {
5332 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5334 }
else if (VT == MVT::v16i8) {
5335 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5337 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5338 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5340 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5341 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5343 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5344 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5346 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5347 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5349 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5350 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5352 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5353 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5357 case Intrinsic::aarch64_neon_ld2lane:
5358 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5359 SelectLoadLane(Node, 2, AArch64::LD2i8);
5361 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5362 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5363 SelectLoadLane(Node, 2, AArch64::LD2i16);
5365 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5367 SelectLoadLane(Node, 2, AArch64::LD2i32);
5369 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5371 SelectLoadLane(Node, 2, AArch64::LD2i64);
5375 case Intrinsic::aarch64_neon_ld3lane:
5376 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5377 SelectLoadLane(Node, 3, AArch64::LD3i8);
5379 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5380 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5381 SelectLoadLane(Node, 3, AArch64::LD3i16);
5383 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5385 SelectLoadLane(Node, 3, AArch64::LD3i32);
5387 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5389 SelectLoadLane(Node, 3, AArch64::LD3i64);
5393 case Intrinsic::aarch64_neon_ld4lane:
5394 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5395 SelectLoadLane(Node, 4, AArch64::LD4i8);
5397 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5398 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5399 SelectLoadLane(Node, 4, AArch64::LD4i16);
5401 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5403 SelectLoadLane(Node, 4, AArch64::LD4i32);
5405 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5407 SelectLoadLane(Node, 4, AArch64::LD4i64);
5411 case Intrinsic::aarch64_ld64b:
5412 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5414 case Intrinsic::aarch64_sve_ld2q_sret: {
5415 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5418 case Intrinsic::aarch64_sve_ld3q_sret: {
5419 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5422 case Intrinsic::aarch64_sve_ld4q_sret: {
5423 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5426 case Intrinsic::aarch64_sve_ld2_sret: {
5427 if (VT == MVT::nxv16i8) {
5428 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5431 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5432 VT == MVT::nxv8bf16) {
5433 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5436 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5437 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5440 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5441 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5447 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5448 if (VT == MVT::nxv16i8) {
5449 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5450 SelectContiguousMultiVectorLoad(
5451 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5452 else if (Subtarget->hasSVE2p1())
5453 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5458 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5459 VT == MVT::nxv8bf16) {
5460 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5461 SelectContiguousMultiVectorLoad(
5462 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5463 else if (Subtarget->hasSVE2p1())
5464 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5469 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5470 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5471 SelectContiguousMultiVectorLoad(
5472 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5473 else if (Subtarget->hasSVE2p1())
5474 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5479 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5480 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5481 SelectContiguousMultiVectorLoad(
5482 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5483 else if (Subtarget->hasSVE2p1())
5484 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5492 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5493 if (VT == MVT::nxv16i8) {
5494 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5495 SelectContiguousMultiVectorLoad(
5496 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5497 else if (Subtarget->hasSVE2p1())
5498 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5503 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5504 VT == MVT::nxv8bf16) {
5505 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5506 SelectContiguousMultiVectorLoad(
5507 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5508 else if (Subtarget->hasSVE2p1())
5509 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5514 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5515 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5516 SelectContiguousMultiVectorLoad(
5517 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5518 else if (Subtarget->hasSVE2p1())
5519 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5524 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5525 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5526 SelectContiguousMultiVectorLoad(
5527 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5528 else if (Subtarget->hasSVE2p1())
5529 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5537 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5538 if (VT == MVT::nxv16i8) {
5539 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5540 SelectContiguousMultiVectorLoad(Node, 2, 0,
5541 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5542 AArch64::LDNT1B_2Z_PSEUDO);
5543 else if (Subtarget->hasSVE2p1())
5544 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5545 AArch64::LDNT1B_2Z);
5549 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5550 VT == MVT::nxv8bf16) {
5551 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5552 SelectContiguousMultiVectorLoad(Node, 2, 1,
5553 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5554 AArch64::LDNT1H_2Z_PSEUDO);
5555 else if (Subtarget->hasSVE2p1())
5556 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5557 AArch64::LDNT1H_2Z);
5561 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5562 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5563 SelectContiguousMultiVectorLoad(Node, 2, 2,
5564 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5565 AArch64::LDNT1W_2Z_PSEUDO);
5566 else if (Subtarget->hasSVE2p1())
5567 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5568 AArch64::LDNT1W_2Z);
5572 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5573 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5574 SelectContiguousMultiVectorLoad(Node, 2, 3,
5575 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5576 AArch64::LDNT1D_2Z_PSEUDO);
5577 else if (Subtarget->hasSVE2p1())
5578 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5579 AArch64::LDNT1D_2Z);
5586 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5587 if (VT == MVT::nxv16i8) {
5588 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5589 SelectContiguousMultiVectorLoad(Node, 4, 0,
5590 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5591 AArch64::LDNT1B_4Z_PSEUDO);
5592 else if (Subtarget->hasSVE2p1())
5593 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5594 AArch64::LDNT1B_4Z);
5598 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5599 VT == MVT::nxv8bf16) {
5600 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5601 SelectContiguousMultiVectorLoad(Node, 4, 1,
5602 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5603 AArch64::LDNT1H_4Z_PSEUDO);
5604 else if (Subtarget->hasSVE2p1())
5605 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5606 AArch64::LDNT1H_4Z);
5610 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5611 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5612 SelectContiguousMultiVectorLoad(Node, 4, 2,
5613 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5614 AArch64::LDNT1W_4Z_PSEUDO);
5615 else if (Subtarget->hasSVE2p1())
5616 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5617 AArch64::LDNT1W_4Z);
5621 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5622 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5623 SelectContiguousMultiVectorLoad(Node, 4, 3,
5624 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5625 AArch64::LDNT1D_4Z_PSEUDO);
5626 else if (Subtarget->hasSVE2p1())
5627 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5628 AArch64::LDNT1D_4Z);
5635 case Intrinsic::aarch64_sve_ld3_sret: {
5636 if (VT == MVT::nxv16i8) {
5637 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5640 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5641 VT == MVT::nxv8bf16) {
5642 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5645 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5646 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5649 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5650 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5656 case Intrinsic::aarch64_sve_ld4_sret: {
5657 if (VT == MVT::nxv16i8) {
5658 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5661 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5662 VT == MVT::nxv8bf16) {
5663 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5666 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5667 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5670 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5671 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5677 case Intrinsic::aarch64_sme_read_hor_vg2: {
5678 if (VT == MVT::nxv16i8) {
5679 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5680 AArch64::MOVA_2ZMXI_H_B);
5682 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5683 VT == MVT::nxv8bf16) {
5684 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5685 AArch64::MOVA_2ZMXI_H_H);
5687 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5688 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5689 AArch64::MOVA_2ZMXI_H_S);
5691 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5692 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5693 AArch64::MOVA_2ZMXI_H_D);
5698 case Intrinsic::aarch64_sme_read_ver_vg2: {
5699 if (VT == MVT::nxv16i8) {
5700 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5701 AArch64::MOVA_2ZMXI_V_B);
5703 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5704 VT == MVT::nxv8bf16) {
5705 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5706 AArch64::MOVA_2ZMXI_V_H);
5708 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5709 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5710 AArch64::MOVA_2ZMXI_V_S);
5712 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5713 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5714 AArch64::MOVA_2ZMXI_V_D);
5719 case Intrinsic::aarch64_sme_read_hor_vg4: {
5720 if (VT == MVT::nxv16i8) {
5721 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5722 AArch64::MOVA_4ZMXI_H_B);
5724 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5725 VT == MVT::nxv8bf16) {
5726 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5727 AArch64::MOVA_4ZMXI_H_H);
5729 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5730 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5731 AArch64::MOVA_4ZMXI_H_S);
5733 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5734 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5735 AArch64::MOVA_4ZMXI_H_D);
5740 case Intrinsic::aarch64_sme_read_ver_vg4: {
5741 if (VT == MVT::nxv16i8) {
5742 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5743 AArch64::MOVA_4ZMXI_V_B);
5745 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5746 VT == MVT::nxv8bf16) {
5747 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5748 AArch64::MOVA_4ZMXI_V_H);
5750 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5751 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5752 AArch64::MOVA_4ZMXI_V_S);
5754 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5755 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5756 AArch64::MOVA_4ZMXI_V_D);
5761 case Intrinsic::aarch64_sme_read_vg1x2: {
5762 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5763 AArch64::MOVA_VG2_2ZMXI);
5766 case Intrinsic::aarch64_sme_read_vg1x4: {
5767 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5768 AArch64::MOVA_VG4_4ZMXI);
5771 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5772 if (VT == MVT::nxv16i8) {
5773 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5775 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5776 VT == MVT::nxv8bf16) {
5777 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5779 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5780 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5782 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5783 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5788 case Intrinsic::aarch64_sme_readz_vert_x2: {
5789 if (VT == MVT::nxv16i8) {
5790 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5792 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5793 VT == MVT::nxv8bf16) {
5794 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5796 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5797 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5799 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5800 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5805 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5806 if (VT == MVT::nxv16i8) {
5807 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5809 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5810 VT == MVT::nxv8bf16) {
5811 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5813 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5814 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5816 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5817 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5822 case Intrinsic::aarch64_sme_readz_vert_x4: {
5823 if (VT == MVT::nxv16i8) {
5824 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5826 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5827 VT == MVT::nxv8bf16) {
5828 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5830 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5831 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5833 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5834 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5839 case Intrinsic::aarch64_sme_readz_x2: {
5840 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5844 case Intrinsic::aarch64_sme_readz_x4: {
5845 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5849 case Intrinsic::swift_async_context_addr: {
5852 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5854 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5855 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5856 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5858 ReplaceUses(
SDValue(Node, 0), Res);
5860 CurDAG->RemoveDeadNode(Node);
5862 auto &MF = CurDAG->getMachineFunction();
5863 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5864 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5867 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5869 Node->getValueType(0),
5870 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5871 AArch64::LUTI2_4ZTZI_S}))
5873 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5876 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5878 Node->getValueType(0),
5879 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5881 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5884 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5886 Node->getValueType(0),
5887 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5888 AArch64::LUTI2_2ZTZI_S}))
5890 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5893 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5895 Node->getValueType(0),
5896 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5897 AArch64::LUTI4_2ZTZI_S}))
5899 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5902 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5903 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5906 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5908 Node->getValueType(0),
5909 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5910 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5912 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5914 Node->getValueType(0),
5915 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5916 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5918 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5920 Node->getValueType(0),
5921 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5922 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5924 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5926 Node->getValueType(0),
5927 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5928 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5930 case Intrinsic::ptrauth_resign_load_relative:
5931 SelectPtrauthResign(Node);
5936 unsigned IntNo =
Node->getConstantOperandVal(0);
5940 case Intrinsic::aarch64_tagp:
5944 case Intrinsic::ptrauth_auth:
5945 SelectPtrauthAuth(Node);
5948 case Intrinsic::ptrauth_resign:
5949 SelectPtrauthResign(Node);
5952 case Intrinsic::aarch64_neon_tbl2:
5953 SelectTable(Node, 2,
5954 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5957 case Intrinsic::aarch64_neon_tbl3:
5958 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5959 : AArch64::TBLv16i8Three,
5962 case Intrinsic::aarch64_neon_tbl4:
5963 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5964 : AArch64::TBLv16i8Four,
5967 case Intrinsic::aarch64_neon_tbx2:
5968 SelectTable(Node, 2,
5969 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5972 case Intrinsic::aarch64_neon_tbx3:
5973 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5974 : AArch64::TBXv16i8Three,
5977 case Intrinsic::aarch64_neon_tbx4:
5978 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5979 : AArch64::TBXv16i8Four,
5982 case Intrinsic::aarch64_sve_srshl_single_x2:
5984 Node->getValueType(0),
5985 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5986 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5987 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5989 case Intrinsic::aarch64_sve_srshl_single_x4:
5991 Node->getValueType(0),
5992 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5993 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5994 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5996 case Intrinsic::aarch64_sve_urshl_single_x2:
5998 Node->getValueType(0),
5999 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6000 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6001 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6003 case Intrinsic::aarch64_sve_urshl_single_x4:
6005 Node->getValueType(0),
6006 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6007 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6008 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6010 case Intrinsic::aarch64_sve_srshl_x2:
6012 Node->getValueType(0),
6013 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6014 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6015 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6017 case Intrinsic::aarch64_sve_srshl_x4:
6019 Node->getValueType(0),
6020 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6021 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6022 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6024 case Intrinsic::aarch64_sve_urshl_x2:
6026 Node->getValueType(0),
6027 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6028 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6029 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6031 case Intrinsic::aarch64_sve_urshl_x4:
6033 Node->getValueType(0),
6034 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6035 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6036 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6038 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6040 Node->getValueType(0),
6041 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6042 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6043 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6045 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6047 Node->getValueType(0),
6048 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6049 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6050 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6052 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6054 Node->getValueType(0),
6055 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6056 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6057 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6059 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6061 Node->getValueType(0),
6062 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6063 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6064 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6066 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6068 Node->getValueType(0),
6069 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6070 AArch64::FSCALE_2ZZ_D}))
6071 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6073 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6075 Node->getValueType(0),
6076 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6077 AArch64::FSCALE_4ZZ_D}))
6078 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6080 case Intrinsic::aarch64_sme_fp8_scale_x2:
6082 Node->getValueType(0),
6083 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6084 AArch64::FSCALE_2Z2Z_D}))
6085 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6087 case Intrinsic::aarch64_sme_fp8_scale_x4:
6089 Node->getValueType(0),
6090 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6091 AArch64::FSCALE_4Z4Z_D}))
6092 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6094 case Intrinsic::aarch64_sve_whilege_x2:
6096 Node->getValueType(0),
6097 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6098 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6099 SelectWhilePair(Node,
Op);
6101 case Intrinsic::aarch64_sve_whilegt_x2:
6103 Node->getValueType(0),
6104 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6105 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6106 SelectWhilePair(Node,
Op);
6108 case Intrinsic::aarch64_sve_whilehi_x2:
6110 Node->getValueType(0),
6111 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6112 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6113 SelectWhilePair(Node,
Op);
6115 case Intrinsic::aarch64_sve_whilehs_x2:
6117 Node->getValueType(0),
6118 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6119 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6120 SelectWhilePair(Node,
Op);
6122 case Intrinsic::aarch64_sve_whilele_x2:
6124 Node->getValueType(0),
6125 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6126 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6127 SelectWhilePair(Node,
Op);
6129 case Intrinsic::aarch64_sve_whilelo_x2:
6131 Node->getValueType(0),
6132 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6133 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6134 SelectWhilePair(Node,
Op);
6136 case Intrinsic::aarch64_sve_whilels_x2:
6138 Node->getValueType(0),
6139 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6140 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6141 SelectWhilePair(Node,
Op);
6143 case Intrinsic::aarch64_sve_whilelt_x2:
6145 Node->getValueType(0),
6146 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6147 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6148 SelectWhilePair(Node,
Op);
6150 case Intrinsic::aarch64_sve_smax_single_x2:
6152 Node->getValueType(0),
6153 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6154 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6155 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6157 case Intrinsic::aarch64_sve_umax_single_x2:
6159 Node->getValueType(0),
6160 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6161 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6162 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6164 case Intrinsic::aarch64_sve_fmax_single_x2:
6166 Node->getValueType(0),
6167 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6168 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6169 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6171 case Intrinsic::aarch64_sve_smax_single_x4:
6173 Node->getValueType(0),
6174 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6175 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6176 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6178 case Intrinsic::aarch64_sve_umax_single_x4:
6180 Node->getValueType(0),
6181 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6182 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6183 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6185 case Intrinsic::aarch64_sve_fmax_single_x4:
6187 Node->getValueType(0),
6188 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6189 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6190 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6192 case Intrinsic::aarch64_sve_smin_single_x2:
6194 Node->getValueType(0),
6195 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6196 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6197 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6199 case Intrinsic::aarch64_sve_umin_single_x2:
6201 Node->getValueType(0),
6202 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6203 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6204 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6206 case Intrinsic::aarch64_sve_fmin_single_x2:
6208 Node->getValueType(0),
6209 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6210 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6211 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6213 case Intrinsic::aarch64_sve_smin_single_x4:
6215 Node->getValueType(0),
6216 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6217 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6218 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6220 case Intrinsic::aarch64_sve_umin_single_x4:
6222 Node->getValueType(0),
6223 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6224 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6225 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6227 case Intrinsic::aarch64_sve_fmin_single_x4:
6229 Node->getValueType(0),
6230 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6231 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6232 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6234 case Intrinsic::aarch64_sve_smax_x2:
6236 Node->getValueType(0),
6237 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6238 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6239 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6241 case Intrinsic::aarch64_sve_umax_x2:
6243 Node->getValueType(0),
6244 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6245 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6246 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6248 case Intrinsic::aarch64_sve_fmax_x2:
6250 Node->getValueType(0),
6251 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6252 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6253 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6255 case Intrinsic::aarch64_sve_smax_x4:
6257 Node->getValueType(0),
6258 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6259 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6260 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6262 case Intrinsic::aarch64_sve_umax_x4:
6264 Node->getValueType(0),
6265 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6266 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6267 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6269 case Intrinsic::aarch64_sve_fmax_x4:
6271 Node->getValueType(0),
6272 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6273 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6274 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6276 case Intrinsic::aarch64_sme_famax_x2:
6278 Node->getValueType(0),
6279 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6280 AArch64::FAMAX_2Z2Z_D}))
6281 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6283 case Intrinsic::aarch64_sme_famax_x4:
6285 Node->getValueType(0),
6286 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6287 AArch64::FAMAX_4Z4Z_D}))
6288 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6290 case Intrinsic::aarch64_sme_famin_x2:
6292 Node->getValueType(0),
6293 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6294 AArch64::FAMIN_2Z2Z_D}))
6295 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6297 case Intrinsic::aarch64_sme_famin_x4:
6299 Node->getValueType(0),
6300 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6301 AArch64::FAMIN_4Z4Z_D}))
6302 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6304 case Intrinsic::aarch64_sve_smin_x2:
6306 Node->getValueType(0),
6307 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6308 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6309 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6311 case Intrinsic::aarch64_sve_umin_x2:
6313 Node->getValueType(0),
6314 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6315 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6316 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6318 case Intrinsic::aarch64_sve_fmin_x2:
6320 Node->getValueType(0),
6321 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6322 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6323 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6325 case Intrinsic::aarch64_sve_smin_x4:
6327 Node->getValueType(0),
6328 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6329 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6330 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6332 case Intrinsic::aarch64_sve_umin_x4:
6334 Node->getValueType(0),
6335 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6336 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6337 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6339 case Intrinsic::aarch64_sve_fmin_x4:
6341 Node->getValueType(0),
6342 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6343 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6344 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6346 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6348 Node->getValueType(0),
6349 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6350 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6351 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6353 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6355 Node->getValueType(0),
6356 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6357 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6358 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6360 case Intrinsic::aarch64_sve_fminnm_single_x2:
6362 Node->getValueType(0),
6363 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6364 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6365 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6367 case Intrinsic::aarch64_sve_fminnm_single_x4:
6369 Node->getValueType(0),
6370 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6371 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6372 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6374 case Intrinsic::aarch64_sve_fscale_single_x4:
6375 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6377 case Intrinsic::aarch64_sve_fscale_single_x2:
6378 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6380 case Intrinsic::aarch64_sve_fmul_single_x4:
6382 Node->getValueType(0),
6383 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6384 AArch64::FMUL_4ZZ_D}))
6385 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6387 case Intrinsic::aarch64_sve_fmul_single_x2:
6389 Node->getValueType(0),
6390 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6391 AArch64::FMUL_2ZZ_D}))
6392 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6394 case Intrinsic::aarch64_sve_fmaxnm_x2:
6396 Node->getValueType(0),
6397 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6398 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6399 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6401 case Intrinsic::aarch64_sve_fmaxnm_x4:
6403 Node->getValueType(0),
6404 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6405 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6406 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6408 case Intrinsic::aarch64_sve_fminnm_x2:
6410 Node->getValueType(0),
6411 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6412 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6413 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6415 case Intrinsic::aarch64_sve_fminnm_x4:
6417 Node->getValueType(0),
6418 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6419 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6420 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6422 case Intrinsic::aarch64_sve_aese_lane_x2:
6423 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6425 case Intrinsic::aarch64_sve_aesd_lane_x2:
6426 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6428 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6429 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6431 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6432 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6434 case Intrinsic::aarch64_sve_aese_lane_x4:
6435 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6437 case Intrinsic::aarch64_sve_aesd_lane_x4:
6438 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6440 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6441 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6443 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6444 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6446 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6447 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6449 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6453 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6455 for (
unsigned I = 0;
I < 2;
I++)
6457 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6459 CurDAG->RemoveDeadNode(Node);
6462 case Intrinsic::aarch64_sve_fscale_x4:
6463 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6465 case Intrinsic::aarch64_sve_fscale_x2:
6466 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6468 case Intrinsic::aarch64_sve_fmul_x4:
6470 Node->getValueType(0),
6471 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6472 AArch64::FMUL_4Z4Z_D}))
6473 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6475 case Intrinsic::aarch64_sve_fmul_x2:
6477 Node->getValueType(0),
6478 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6479 AArch64::FMUL_2Z2Z_D}))
6480 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6482 case Intrinsic::aarch64_sve_fcvtzs_x2:
6483 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6485 case Intrinsic::aarch64_sve_scvtf_x2:
6486 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6488 case Intrinsic::aarch64_sve_fcvtzu_x2:
6489 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6491 case Intrinsic::aarch64_sve_ucvtf_x2:
6492 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6494 case Intrinsic::aarch64_sve_fcvtzs_x4:
6495 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6497 case Intrinsic::aarch64_sve_scvtf_x4:
6498 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6500 case Intrinsic::aarch64_sve_fcvtzu_x4:
6501 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6503 case Intrinsic::aarch64_sve_ucvtf_x4:
6504 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6506 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6507 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6509 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6510 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6512 case Intrinsic::aarch64_sve_sclamp_single_x2:
6514 Node->getValueType(0),
6515 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6516 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6517 SelectClamp(Node, 2,
Op);
6519 case Intrinsic::aarch64_sve_uclamp_single_x2:
6521 Node->getValueType(0),
6522 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6523 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6524 SelectClamp(Node, 2,
Op);
6526 case Intrinsic::aarch64_sve_fclamp_single_x2:
6528 Node->getValueType(0),
6529 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6530 AArch64::FCLAMP_VG2_2Z2Z_D}))
6531 SelectClamp(Node, 2,
Op);
6533 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6534 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6536 case Intrinsic::aarch64_sve_sclamp_single_x4:
6538 Node->getValueType(0),
6539 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6540 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6541 SelectClamp(Node, 4,
Op);
6543 case Intrinsic::aarch64_sve_uclamp_single_x4:
6545 Node->getValueType(0),
6546 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6547 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6548 SelectClamp(Node, 4,
Op);
6550 case Intrinsic::aarch64_sve_fclamp_single_x4:
6552 Node->getValueType(0),
6553 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6554 AArch64::FCLAMP_VG4_4Z4Z_D}))
6555 SelectClamp(Node, 4,
Op);
6557 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6558 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6560 case Intrinsic::aarch64_sve_add_single_x2:
6562 Node->getValueType(0),
6563 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6564 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6565 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6567 case Intrinsic::aarch64_sve_add_single_x4:
6569 Node->getValueType(0),
6570 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6571 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6572 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6574 case Intrinsic::aarch64_sve_zip_x2:
6576 Node->getValueType(0),
6577 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6578 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6579 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6581 case Intrinsic::aarch64_sve_zipq_x2:
6582 SelectUnaryMultiIntrinsic(Node, 2,
false,
6583 AArch64::ZIP_VG2_2ZZZ_Q);
6585 case Intrinsic::aarch64_sve_zip_x4:
6587 Node->getValueType(0),
6588 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6589 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6590 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6592 case Intrinsic::aarch64_sve_zipq_x4:
6593 SelectUnaryMultiIntrinsic(Node, 4,
true,
6594 AArch64::ZIP_VG4_4Z4Z_Q);
6596 case Intrinsic::aarch64_sve_uzp_x2:
6598 Node->getValueType(0),
6599 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6600 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6601 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6603 case Intrinsic::aarch64_sve_uzpq_x2:
6604 SelectUnaryMultiIntrinsic(Node, 2,
false,
6605 AArch64::UZP_VG2_2ZZZ_Q);
6607 case Intrinsic::aarch64_sve_uzp_x4:
6609 Node->getValueType(0),
6610 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6611 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6612 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6614 case Intrinsic::aarch64_sve_uzpq_x4:
6615 SelectUnaryMultiIntrinsic(Node, 4,
true,
6616 AArch64::UZP_VG4_4Z4Z_Q);
6618 case Intrinsic::aarch64_sve_sel_x2:
6620 Node->getValueType(0),
6621 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6622 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6623 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6625 case Intrinsic::aarch64_sve_sel_x4:
6627 Node->getValueType(0),
6628 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6629 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6630 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6632 case Intrinsic::aarch64_sve_frinta_x2:
6633 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6635 case Intrinsic::aarch64_sve_frinta_x4:
6636 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6638 case Intrinsic::aarch64_sve_frintm_x2:
6639 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6641 case Intrinsic::aarch64_sve_frintm_x4:
6642 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6644 case Intrinsic::aarch64_sve_frintn_x2:
6645 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6647 case Intrinsic::aarch64_sve_frintn_x4:
6648 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6650 case Intrinsic::aarch64_sve_frintp_x2:
6651 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6653 case Intrinsic::aarch64_sve_frintp_x4:
6654 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6656 case Intrinsic::aarch64_sve_sunpk_x2:
6658 Node->getValueType(0),
6659 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6660 AArch64::SUNPK_VG2_2ZZ_D}))
6661 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6663 case Intrinsic::aarch64_sve_uunpk_x2:
6665 Node->getValueType(0),
6666 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6667 AArch64::UUNPK_VG2_2ZZ_D}))
6668 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6670 case Intrinsic::aarch64_sve_sunpk_x4:
6672 Node->getValueType(0),
6673 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6674 AArch64::SUNPK_VG4_4Z2Z_D}))
6675 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6677 case Intrinsic::aarch64_sve_uunpk_x4:
6679 Node->getValueType(0),
6680 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6681 AArch64::UUNPK_VG4_4Z2Z_D}))
6682 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6684 case Intrinsic::aarch64_sve_pext_x2: {
6686 Node->getValueType(0),
6687 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6688 AArch64::PEXT_2PCI_D}))
6689 SelectPExtPair(Node,
Op);
6696 unsigned IntNo =
Node->getConstantOperandVal(1);
6697 if (
Node->getNumOperands() >= 3)
6698 VT =
Node->getOperand(2)->getValueType(0);
6702 case Intrinsic::aarch64_neon_st1x2: {
6703 if (VT == MVT::v8i8) {
6704 SelectStore(Node, 2, AArch64::ST1Twov8b);
6706 }
else if (VT == MVT::v16i8) {
6707 SelectStore(Node, 2, AArch64::ST1Twov16b);
6709 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6710 VT == MVT::v4bf16) {
6711 SelectStore(Node, 2, AArch64::ST1Twov4h);
6713 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6714 VT == MVT::v8bf16) {
6715 SelectStore(Node, 2, AArch64::ST1Twov8h);
6717 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6718 SelectStore(Node, 2, AArch64::ST1Twov2s);
6720 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6721 SelectStore(Node, 2, AArch64::ST1Twov4s);
6723 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6724 SelectStore(Node, 2, AArch64::ST1Twov2d);
6726 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6727 SelectStore(Node, 2, AArch64::ST1Twov1d);
6732 case Intrinsic::aarch64_neon_st1x3: {
6733 if (VT == MVT::v8i8) {
6734 SelectStore(Node, 3, AArch64::ST1Threev8b);
6736 }
else if (VT == MVT::v16i8) {
6737 SelectStore(Node, 3, AArch64::ST1Threev16b);
6739 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6740 VT == MVT::v4bf16) {
6741 SelectStore(Node, 3, AArch64::ST1Threev4h);
6743 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6744 VT == MVT::v8bf16) {
6745 SelectStore(Node, 3, AArch64::ST1Threev8h);
6747 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6748 SelectStore(Node, 3, AArch64::ST1Threev2s);
6750 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6751 SelectStore(Node, 3, AArch64::ST1Threev4s);
6753 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6754 SelectStore(Node, 3, AArch64::ST1Threev2d);
6756 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6757 SelectStore(Node, 3, AArch64::ST1Threev1d);
6762 case Intrinsic::aarch64_neon_st1x4: {
6763 if (VT == MVT::v8i8) {
6764 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6766 }
else if (VT == MVT::v16i8) {
6767 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6769 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6770 VT == MVT::v4bf16) {
6771 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6773 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6774 VT == MVT::v8bf16) {
6775 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6777 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6778 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6780 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6781 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6783 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6784 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6786 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6787 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6792 case Intrinsic::aarch64_neon_st2: {
6793 if (VT == MVT::v8i8) {
6794 SelectStore(Node, 2, AArch64::ST2Twov8b);
6796 }
else if (VT == MVT::v16i8) {
6797 SelectStore(Node, 2, AArch64::ST2Twov16b);
6799 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6800 VT == MVT::v4bf16) {
6801 SelectStore(Node, 2, AArch64::ST2Twov4h);
6803 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6804 VT == MVT::v8bf16) {
6805 SelectStore(Node, 2, AArch64::ST2Twov8h);
6807 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6808 SelectStore(Node, 2, AArch64::ST2Twov2s);
6810 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6811 SelectStore(Node, 2, AArch64::ST2Twov4s);
6813 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6814 SelectStore(Node, 2, AArch64::ST2Twov2d);
6816 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6817 SelectStore(Node, 2, AArch64::ST1Twov1d);
6822 case Intrinsic::aarch64_neon_st3: {
6823 if (VT == MVT::v8i8) {
6824 SelectStore(Node, 3, AArch64::ST3Threev8b);
6826 }
else if (VT == MVT::v16i8) {
6827 SelectStore(Node, 3, AArch64::ST3Threev16b);
6829 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6830 VT == MVT::v4bf16) {
6831 SelectStore(Node, 3, AArch64::ST3Threev4h);
6833 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6834 VT == MVT::v8bf16) {
6835 SelectStore(Node, 3, AArch64::ST3Threev8h);
6837 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6838 SelectStore(Node, 3, AArch64::ST3Threev2s);
6840 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6841 SelectStore(Node, 3, AArch64::ST3Threev4s);
6843 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6844 SelectStore(Node, 3, AArch64::ST3Threev2d);
6846 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6847 SelectStore(Node, 3, AArch64::ST1Threev1d);
6852 case Intrinsic::aarch64_neon_st4: {
6853 if (VT == MVT::v8i8) {
6854 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6856 }
else if (VT == MVT::v16i8) {
6857 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6859 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6860 VT == MVT::v4bf16) {
6861 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6863 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6864 VT == MVT::v8bf16) {
6865 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6867 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6868 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6870 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6871 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6873 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6874 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6876 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6877 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6882 case Intrinsic::aarch64_neon_st2lane: {
6883 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6884 SelectStoreLane(Node, 2, AArch64::ST2i8);
6886 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6887 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6888 SelectStoreLane(Node, 2, AArch64::ST2i16);
6890 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6892 SelectStoreLane(Node, 2, AArch64::ST2i32);
6894 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6896 SelectStoreLane(Node, 2, AArch64::ST2i64);
6901 case Intrinsic::aarch64_neon_st3lane: {
6902 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6903 SelectStoreLane(Node, 3, AArch64::ST3i8);
6905 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6906 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6907 SelectStoreLane(Node, 3, AArch64::ST3i16);
6909 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6911 SelectStoreLane(Node, 3, AArch64::ST3i32);
6913 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6915 SelectStoreLane(Node, 3, AArch64::ST3i64);
6920 case Intrinsic::aarch64_neon_st4lane: {
6921 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6922 SelectStoreLane(Node, 4, AArch64::ST4i8);
6924 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6925 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6926 SelectStoreLane(Node, 4, AArch64::ST4i16);
6928 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6930 SelectStoreLane(Node, 4, AArch64::ST4i32);
6932 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6934 SelectStoreLane(Node, 4, AArch64::ST4i64);
6939 case Intrinsic::aarch64_sve_st2q: {
6940 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6943 case Intrinsic::aarch64_sve_st3q: {
6944 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6947 case Intrinsic::aarch64_sve_st4q: {
6948 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6951 case Intrinsic::aarch64_sve_st2: {
6952 if (VT == MVT::nxv16i8) {
6953 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6955 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6956 VT == MVT::nxv8bf16) {
6957 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6959 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6960 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6962 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6963 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6968 case Intrinsic::aarch64_sve_st3: {
6969 if (VT == MVT::nxv16i8) {
6970 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6972 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6973 VT == MVT::nxv8bf16) {
6974 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6976 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6977 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6979 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6980 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6985 case Intrinsic::aarch64_sve_st4: {
6986 if (VT == MVT::nxv16i8) {
6987 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6989 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6990 VT == MVT::nxv8bf16) {
6991 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6993 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6994 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6996 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6997 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7005 case AArch64ISD::LD2post: {
7006 if (VT == MVT::v8i8) {
7007 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7009 }
else if (VT == MVT::v16i8) {
7010 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7012 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7013 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7015 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7016 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7018 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7019 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7021 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7022 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7024 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7025 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7027 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7028 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7033 case AArch64ISD::LD3post: {
7034 if (VT == MVT::v8i8) {
7035 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7037 }
else if (VT == MVT::v16i8) {
7038 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7040 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7041 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7043 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7044 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7046 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7047 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7049 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7050 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7052 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7053 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7055 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7056 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7061 case AArch64ISD::LD4post: {
7062 if (VT == MVT::v8i8) {
7063 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7065 }
else if (VT == MVT::v16i8) {
7066 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7068 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7069 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7071 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7072 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7074 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7075 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7077 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7078 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7080 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7081 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7083 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7084 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7089 case AArch64ISD::LD1x2post: {
7090 if (VT == MVT::v8i8) {
7091 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7093 }
else if (VT == MVT::v16i8) {
7094 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7096 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7097 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7099 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7100 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7102 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7103 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7105 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7106 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7108 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7109 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7111 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7112 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7117 case AArch64ISD::LD1x3post: {
7118 if (VT == MVT::v8i8) {
7119 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7121 }
else if (VT == MVT::v16i8) {
7122 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7124 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7125 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7127 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7128 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7130 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7131 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7133 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7134 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7136 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7137 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7139 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7140 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7145 case AArch64ISD::LD1x4post: {
7146 if (VT == MVT::v8i8) {
7147 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7149 }
else if (VT == MVT::v16i8) {
7150 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7152 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7153 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7155 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7156 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7158 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7159 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7161 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7162 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7164 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7165 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7167 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7168 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7173 case AArch64ISD::LD1DUPpost: {
7174 if (VT == MVT::v8i8) {
7175 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7177 }
else if (VT == MVT::v16i8) {
7178 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7180 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7181 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7183 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7184 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7186 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7187 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7189 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7190 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7192 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7193 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7195 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7196 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7201 case AArch64ISD::LD2DUPpost: {
7202 if (VT == MVT::v8i8) {
7203 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7205 }
else if (VT == MVT::v16i8) {
7206 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7208 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7209 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7211 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7212 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7214 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7215 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7217 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7218 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7220 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7221 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7223 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7224 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7229 case AArch64ISD::LD3DUPpost: {
7230 if (VT == MVT::v8i8) {
7231 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7233 }
else if (VT == MVT::v16i8) {
7234 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7236 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7237 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7239 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7240 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7242 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7243 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7245 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7246 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7248 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7249 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7251 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7252 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7257 case AArch64ISD::LD4DUPpost: {
7258 if (VT == MVT::v8i8) {
7259 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7261 }
else if (VT == MVT::v16i8) {
7262 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7264 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7265 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7267 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7268 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7270 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7271 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7273 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7274 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7276 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7277 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7279 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7280 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7285 case AArch64ISD::LD1LANEpost: {
7286 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7287 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7289 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7290 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7291 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7293 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7295 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7297 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7299 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7304 case AArch64ISD::LD2LANEpost: {
7305 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7306 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7308 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7309 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7310 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7312 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7314 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7316 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7318 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7323 case AArch64ISD::LD3LANEpost: {
7324 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7325 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7327 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7328 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7329 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7331 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7333 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7335 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7337 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7342 case AArch64ISD::LD4LANEpost: {
7343 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7344 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7346 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7347 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7348 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7350 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7352 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7354 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7356 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7361 case AArch64ISD::ST2post: {
7362 VT =
Node->getOperand(1).getValueType();
7363 if (VT == MVT::v8i8) {
7364 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7366 }
else if (VT == MVT::v16i8) {
7367 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7369 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7370 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7372 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7373 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7375 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7376 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7378 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7379 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7381 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7382 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7384 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7385 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7390 case AArch64ISD::ST3post: {
7391 VT =
Node->getOperand(1).getValueType();
7392 if (VT == MVT::v8i8) {
7393 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7395 }
else if (VT == MVT::v16i8) {
7396 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7398 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7399 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7401 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7402 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7404 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7405 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7407 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7408 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7410 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7411 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7413 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7414 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7419 case AArch64ISD::ST4post: {
7420 VT =
Node->getOperand(1).getValueType();
7421 if (VT == MVT::v8i8) {
7422 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7424 }
else if (VT == MVT::v16i8) {
7425 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7427 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7428 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7430 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7431 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7433 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7434 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7436 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7437 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7439 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7440 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7442 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7443 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7448 case AArch64ISD::ST1x2post: {
7449 VT =
Node->getOperand(1).getValueType();
7450 if (VT == MVT::v8i8) {
7451 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7453 }
else if (VT == MVT::v16i8) {
7454 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7456 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7457 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7459 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7460 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7462 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7463 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7465 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7466 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7468 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7469 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7471 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7472 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7477 case AArch64ISD::ST1x3post: {
7478 VT =
Node->getOperand(1).getValueType();
7479 if (VT == MVT::v8i8) {
7480 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7482 }
else if (VT == MVT::v16i8) {
7483 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7485 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7486 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7488 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7489 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7491 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7492 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7494 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7495 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7497 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7498 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7500 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7501 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7506 case AArch64ISD::ST1x4post: {
7507 VT =
Node->getOperand(1).getValueType();
7508 if (VT == MVT::v8i8) {
7509 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7511 }
else if (VT == MVT::v16i8) {
7512 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7514 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7515 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7517 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7518 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7520 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7521 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7523 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7524 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7526 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7527 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7529 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7530 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7535 case AArch64ISD::ST2LANEpost: {
7536 VT =
Node->getOperand(1).getValueType();
7537 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7538 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7540 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7541 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7542 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7544 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7546 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7548 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7550 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7555 case AArch64ISD::ST3LANEpost: {
7556 VT =
Node->getOperand(1).getValueType();
7557 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7558 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7560 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7561 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7562 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7564 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7566 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7568 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7570 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7575 case AArch64ISD::ST4LANEpost: {
7576 VT =
Node->getOperand(1).getValueType();
7577 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7578 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7580 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7581 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7582 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7584 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7586 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7588 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7590 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7605 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7617 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7621 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7622 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7637 return MemIntr->getMemoryVT();
7644 DataVT = Load->getValueType(0);
7646 DataVT = Load->getValueType(0);
7648 DataVT = Store->getValue().getValueType();
7650 DataVT = Store->getValue().getValueType();
7657 const unsigned Opcode = Root->
getOpcode();
7661 case AArch64ISD::LD1_MERGE_ZERO:
7662 case AArch64ISD::LD1S_MERGE_ZERO:
7663 case AArch64ISD::LDNF1_MERGE_ZERO:
7664 case AArch64ISD::LDNF1S_MERGE_ZERO:
7666 case AArch64ISD::ST1_PRED:
7678 case Intrinsic::aarch64_sme_ldr:
7679 case Intrinsic::aarch64_sme_str:
7680 return MVT::nxv16i8;
7681 case Intrinsic::aarch64_sve_prf:
7686 case Intrinsic::aarch64_sve_ld2_sret:
7687 case Intrinsic::aarch64_sve_ld2q_sret:
7690 case Intrinsic::aarch64_sve_st2q:
7693 case Intrinsic::aarch64_sve_ld3_sret:
7694 case Intrinsic::aarch64_sve_ld3q_sret:
7697 case Intrinsic::aarch64_sve_st3q:
7700 case Intrinsic::aarch64_sve_ld4_sret:
7701 case Intrinsic::aarch64_sve_ld4q_sret:
7704 case Intrinsic::aarch64_sve_st4q:
7707 case Intrinsic::aarch64_sve_ld1udq:
7708 case Intrinsic::aarch64_sve_st1dq:
7709 return EVT(MVT::nxv1i64);
7710 case Intrinsic::aarch64_sve_ld1uwq:
7711 case Intrinsic::aarch64_sve_st1wq:
7712 return EVT(MVT::nxv1i32);
7719template <
int64_t Min,
int64_t Max>
7720bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7724 const DataLayout &
DL = CurDAG->getDataLayout();
7725 const MachineFrameInfo &MFI = MF->getFrameInfo();
7733 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7747 int64_t MulImm = std::numeric_limits<int64_t>::max();
7751 int64_t ByteOffset =
C->getSExtValue();
7752 const auto KnownVScale =
7755 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7758 MulImm = ByteOffset / KnownVScale;
7765 if ((MulImm % MemWidthBytes) != 0)
7768 int64_t
Offset = MulImm / MemWidthBytes;
7772 Base =
N.getOperand(0);
7781 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7787bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7806 int64_t ImmOff =
C->getSExtValue();
7807 unsigned Size = 1 << Scale;
7816 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7818 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7829 if (
C->getZExtValue() == Scale) {
7838bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7839 const AArch64TargetLowering *TLI =
7840 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7845bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7846 EVT VT =
N.getValueType();
7850bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7855 int64_t ImmOff =
C->getSExtValue();
7856 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7857 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7862 if (
SDValue C = MatchConstantOffset(
N)) {
7863 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7869 if (CurDAG->isBaseWithConstantOffset(
N)) {
7870 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7871 Base =
N.getOperand(0);
7879 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7883bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7903 uint64_t LowerBound = 0, UpperBound = 64;
7921 if (CN->getAPIntValue().uge(LowerBound) &&
7922 CN->getAPIntValue().ult(UpperBound)) {
7924 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7932template <
bool MatchCBB>
7939 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7941 Reg =
N.getOperand(0);
7943 SDLoc(
N), MVT::i32);
7951 Reg =
N.getOperand(0);
7960void AArch64DAGToDAGISel::PreprocessISelDAG() {
7961 bool MadeChange =
false;
7967 switch (
N.getOpcode()) {
7969 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
7970 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
7971 ScalarTy ==
N.getOperand(0).getValueType())
7981 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
7987 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
7993 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 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 isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static APInt DecodeFMOVImm(uint64_t Imm, unsigned RegWidth)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const AArch64RegisterInfo * getRegisterInfo() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
static constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.