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);
453#include "AArch64GenDAGISel.inc"
461 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
463 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
476 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
477 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
478 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
481 template<
unsigned RegW
idth>
483 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
485 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
487 template <
unsigned RegW
idth>
489 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
491 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
493 template<
unsigned RegW
idth>
495 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
501 template <
unsigned FloatW
idth>
503 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
509 bool SelectCMP_SWAP(
SDNode *
N);
528 bool AllowSaturation,
SDValue &Imm);
536 bool SelectAllActivePredicate(
SDValue N);
541 template <
bool MatchCBB>
551 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
555char AArch64DAGToDAGISelLegacy::ID = 0;
563 auto getFloatVT = [&](
EVT VT) {
565 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
566 return VT.changeElementType(*(DAG.getContext()),
567 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
572 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
573 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
577 EVT OrigVT =
N.getValueType(0);
579 return DAG.getBitcast(OrigVT, OpNode);
586 Imm =
C->getZExtValue();
603 return N->getOpcode() ==
Opc &&
614 return Imm == ImmExpected;
619 assert(RegWidth == 32 || RegWidth == 64);
621 return APInt(RegWidth,
628 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
629 if (
N->getOpcode() == AArch64ISD::NVCAST)
630 N =
N->getOperand(0);
631 unsigned SplatWidth =
N.getScalarValueSizeInBits();
632 if (
N.getOpcode() == AArch64ISD::FMOV)
634 if (
N->getOpcode() == AArch64ISD::MOVI)
635 return APInt(SplatWidth,
N.getConstantOperandVal(0));
636 if (
N->getOpcode() == AArch64ISD::MOVIshift)
637 return APInt(SplatWidth,
N.getConstantOperandVal(0)
638 <<
N.getConstantOperandVal(1));
639 if (
N->getOpcode() == AArch64ISD::MVNIshift)
640 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
641 <<
N.getConstantOperandVal(1));
642 if (
N->getOpcode() == AArch64ISD::MOVIedit)
644 N.getConstantOperandVal(0)));
645 if (
N->getOpcode() == AArch64ISD::DUP)
647 return Const->getAPIntValue().trunc(SplatWidth);
656 unsigned SplatWidth =
N.getScalarValueSizeInBits();
658 if (SplatVal->getBitWidth() <= SplatWidth)
660 if (SplatVal->isSplat(SplatWidth))
661 return SplatVal->trunc(SplatWidth);
666bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
673 ImmVal->getZExtValue(), Encoding))
676 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
680bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
683 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
684 N.getValueType().getScalarType().getSimpleVT(),
690bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
693 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
697bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
699 std::vector<SDValue> &OutOps) {
700 switch(ConstraintID) {
703 case InlineAsm::ConstraintCode::m:
704 case InlineAsm::ConstraintCode::o:
705 case InlineAsm::ConstraintCode::Q:
709 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
711 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
713 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
714 dl,
Op.getValueType(),
716 OutOps.push_back(NewOp);
735 uint64_t Immed =
N.getNode()->getAsZExtVal();
738 if (Immed >> 12 == 0) {
740 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
748 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
749 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
766 uint64_t Immed =
N.getNode()->getAsZExtVal();
774 if (
N.getValueType() == MVT::i32)
775 Immed = ~((uint32_t)Immed) + 1;
777 Immed = ~Immed + 1ULL;
778 if (Immed & 0xFFFFFFFFFF000000ULL)
781 Immed &= 0xFFFFFFULL;
782 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
789 switch (
N.getOpcode()) {
815 unsigned ShiftVal = CSD->getZExtValue();
833bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
836 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
841 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
865 EVT VT =
N.getValueType();
866 if (VT != MVT::i32 && VT != MVT::i64)
869 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
875 unsigned LHSOpcode =
LHS->getOpcode();
889 unsigned LowZBits, MaskLen;
893 unsigned BitWidth =
N.getValueSizeInBits();
900 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
903 NewShiftC = LowZBits - ShiftAmtC;
904 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
910 NewShiftC = LowZBits + ShiftAmtC;
923 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
925 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
929 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
931 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
932 NewShiftAmt, BitWidthMinus1),
935 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
949 SrcVT =
N.getOperand(0).getValueType();
951 if (!IsLoadStore && SrcVT == MVT::i8)
953 else if (!IsLoadStore && SrcVT == MVT::i16)
955 else if (SrcVT == MVT::i32)
957 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
962 EVT SrcVT =
N.getOperand(0).getValueType();
963 if (!IsLoadStore && SrcVT == MVT::i8)
965 else if (!IsLoadStore && SrcVT == MVT::i16)
967 else if (SrcVT == MVT::i32)
969 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
997bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
1000 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1005 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1006 V.getConstantOperandVal(1) <= 4 &&
1019bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
1021 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1031 unsigned BitSize =
N.getValueSizeInBits();
1032 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1035 Reg =
N.getOperand(0);
1036 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1037 return isWorthFoldingALU(
N,
true);
1048 if (
N.getValueType() == MVT::i32)
1056template<
signed Low,
signed High,
signed Scale>
1062 if ((MulImm % std::abs(Scale)) == 0) {
1063 int64_t RDVLImm = MulImm / Scale;
1064 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1065 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1074template <
signed Low,
signed High>
1075bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1080 if (MulImm >=
Low && MulImm <=
High) {
1081 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1092 unsigned ShiftVal = 0;
1107 Reg =
N.getOperand(0).getOperand(0);
1119 Op =
Op->getOperand(0);
1121 Op.getOperand(0).getValueType().isFixedLengthVector())
1125 Reg =
N.getOperand(0);
1130 unsigned Opc =
N.getOpcode();
1148 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1150 return isWorthFoldingALU(
N);
1157 unsigned ShiftVal = 0;
1171 Reg =
N.getOperand(0);
1172 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1174 return isWorthFoldingALU(
N);
1183 for (
auto *
User :
N->users()) {
1210bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1211 unsigned BW,
unsigned Size,
1215 const DataLayout &
DL = CurDAG->getDataLayout();
1216 const TargetLowering *TLI = getTargetLowering();
1220 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1226 if (CurDAG->isBaseWithConstantOffset(
N)) {
1229 int64_t RHSC =
RHS->getSExtValue();
1231 int64_t
Range = 0x1LL << (BW - 1);
1233 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1234 RHSC < (
Range << Scale)) {
1235 Base =
N.getOperand(0);
1240 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1245 uint64_t RHSC =
RHS->getZExtValue();
1247 uint64_t
Range = 0x1ULL << BW;
1249 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1250 Base =
N.getOperand(0);
1255 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1266 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1273bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1276 const DataLayout &
DL = CurDAG->getDataLayout();
1277 const TargetLowering *TLI = getTargetLowering();
1281 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1286 GlobalAddressSDNode *GAN =
1288 Base =
N.getOperand(0);
1298 if (CurDAG->isBaseWithConstantOffset(
N)) {
1300 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1303 Base =
N.getOperand(0);
1308 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1316 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1324 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1333bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1336 if (!CurDAG->isBaseWithConstantOffset(
N))
1339 int64_t RHSC =
RHS->getSExtValue();
1340 if (RHSC >= -256 && RHSC < 256) {
1341 Base =
N.getOperand(0);
1344 const TargetLowering *TLI = getTargetLowering();
1345 Base = CurDAG->getTargetFrameIndex(
1348 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1358 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1365bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1385 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1391 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1394 return isWorthFoldingAddr(
N,
Size);
1397bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1415 const SDNode *
Node =
N.getNode();
1416 for (SDNode *UI :
Node->users()) {
1422 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1425 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1428 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1433 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1436 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1441 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1445 if (IsExtendedRegisterWorthFolding &&
1452 if (isWorthFoldingAddr(
LHS,
Size))
1457 if (IsExtendedRegisterWorthFolding &&
1464 if (isWorthFoldingAddr(
RHS,
Size))
1476 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1479 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1481 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1482 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1486bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1499 const SDNode *
Node =
N.getNode();
1500 for (SDNode *UI :
Node->users()) {
1517 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1527 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1534 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1537 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1540 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1545 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1548 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1555 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1556 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1562 static const unsigned RegClassIDs[] = {
1563 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1564 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1565 AArch64::dsub2, AArch64::dsub3};
1571 static const unsigned RegClassIDs[] = {
1572 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1573 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1574 AArch64::qsub2, AArch64::qsub3};
1580 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1581 AArch64::ZPR3RegClassID,
1582 AArch64::ZPR4RegClassID};
1583 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1584 AArch64::zsub2, AArch64::zsub3};
1594 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1595 AArch64::ZPR4Mul4RegClassID};
1596 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1597 AArch64::zsub2, AArch64::zsub3};
1602 const unsigned RegClassIDs[],
1603 const unsigned SubRegs[]) {
1606 if (Regs.
size() == 1)
1617 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1620 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1621 Ops.push_back(Regs[i]);
1622 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1626 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1630void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1633 EVT VT =
N->getValueType(0);
1635 unsigned ExtOff = isExt;
1638 unsigned Vec0Off = ExtOff + 1;
1644 Ops.push_back(
N->getOperand(1));
1645 Ops.push_back(RegSeq);
1646 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1647 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1650static std::tuple<SDValue, SDValue>
1671 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1676 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1678 return std::make_tuple(
1683void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1688 SDValue AUTDisc =
N->getOperand(3);
1691 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1693 SDValue AUTAddrDisc, AUTConstDisc;
1694 std::tie(AUTConstDisc, AUTAddrDisc) =
1698 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1700 if (
N->getNumOperands() > 4)
1701 Ops.push_back(
N->getOperand(4));
1704 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1705 ReplaceNode(
N, AUT);
1707 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1708 AArch64::X16, Val,
SDValue());
1711 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1712 ReplaceNode(
N, AUT);
1716void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1726 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1731 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1732 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1734 SDValue AUTAddrDisc, AUTConstDisc;
1735 std::tie(AUTConstDisc, AUTAddrDisc) =
1738 SDValue PACAddrDisc, PACConstDisc;
1739 std::tie(PACConstDisc, PACAddrDisc) =
1742 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1743 AArch64::X16, Val,
SDValue());
1746 SDValue Addend =
N->getOperand(OffsetBase + 6);
1747 SDValue IncomingChain =
N->getOperand(0);
1748 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1749 PACKey, PACConstDisc, PACAddrDisc,
1750 Addend, IncomingChain, X16Copy.
getValue(1)};
1752 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1753 MVT::i64, MVT::Other,
Ops);
1754 ReplaceNode(
N, AUTRELLOADPAC);
1756 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1757 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1759 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1760 ReplaceNode(
N, AUTPAC);
1764bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1766 if (
LD->isUnindexed())
1768 EVT VT =
LD->getMemoryVT();
1769 EVT DstVT =
N->getValueType(0);
1773 int OffsetVal = (int)
OffsetOp->getZExtValue();
1778 unsigned Opcode = 0;
1781 bool InsertTo64 =
false;
1783 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1784 else if (VT == MVT::i32) {
1786 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1788 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1790 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1796 }
else if (VT == MVT::i16) {
1798 if (DstVT == MVT::i64)
1799 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1801 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1803 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1804 InsertTo64 = DstVT == MVT::i64;
1809 }
else if (VT == MVT::i8) {
1811 if (DstVT == MVT::i64)
1812 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1814 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1816 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1817 InsertTo64 = DstVT == MVT::i64;
1822 }
else if (VT == MVT::f16) {
1823 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1824 }
else if (VT == MVT::bf16) {
1825 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1826 }
else if (VT == MVT::f32) {
1827 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1828 }
else if (VT == MVT::f64 ||
1830 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1832 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1834 if (IsPre || OffsetVal != 8)
1838 Opcode = AArch64::LD1Onev8b_POST;
1841 Opcode = AArch64::LD1Onev4h_POST;
1844 Opcode = AArch64::LD1Onev2s_POST;
1847 Opcode = AArch64::LD1Onev1d_POST;
1853 if (IsPre || OffsetVal != 16)
1857 Opcode = AArch64::LD1Onev16b_POST;
1860 Opcode = AArch64::LD1Onev8h_POST;
1863 Opcode = AArch64::LD1Onev4s_POST;
1866 Opcode = AArch64::LD1Onev2d_POST;
1878 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1879 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1881 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1891 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1892 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1893 MVT::i64, LoadedVal, SubReg),
1897 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1900 CurDAG->RemoveDeadNode(
N);
1904void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1905 unsigned SubRegIdx) {
1907 EVT VT =
N->getValueType(0);
1913 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1915 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1917 for (
unsigned i = 0; i < NumVecs; ++i)
1919 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1926 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1930 CurDAG->RemoveDeadNode(
N);
1933void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1934 unsigned Opc,
unsigned SubRegIdx) {
1936 EVT VT =
N->getValueType(0);
1943 const EVT ResTys[] = {MVT::i64,
1944 MVT::Untyped, MVT::Other};
1946 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1954 ReplaceUses(
SDValue(
N, 0), SuperReg);
1956 for (
unsigned i = 0; i < NumVecs; ++i)
1958 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1966 CurDAG->RemoveDeadNode(
N);
1972std::tuple<unsigned, SDValue, SDValue>
1973AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1979 SDValue NewOffset = OldOffset;
1981 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1982 N, OldBase, NewBase, NewOffset);
1986 const bool IsRegReg =
1987 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1990 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
2003template <SelectTypeKind Kind>
2015 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2020 if (EltVT != MVT::i1)
2024 if (EltVT == MVT::bf16)
2026 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2056void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2059 if (
Imm->getZExtValue() > 1)
2063 EVT VT =
N->getValueType(0);
2065 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2068 for (
unsigned I = 0;
I < 2; ++
I)
2069 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2070 AArch64::psub0 +
I,
DL, VT, SuperReg));
2072 CurDAG->RemoveDeadNode(
N);
2075void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2077 EVT VT =
N->getValueType(0);
2081 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2084 for (
unsigned I = 0;
I < 2; ++
I)
2085 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2086 AArch64::psub0 +
I,
DL, VT, SuperReg));
2088 CurDAG->RemoveDeadNode(
N);
2091void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2093 EVT VT =
N->getValueType(0);
2097 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2099 for (
unsigned i = 0; i < NumVecs; ++i)
2100 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2101 AArch64::zsub0 + i,
DL, VT, SuperReg));
2103 CurDAG->RemoveDeadNode(
N);
2106void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2109 EVT VT =
N->getValueType(0);
2111 Ops.push_back(
N->getOperand(0));
2114 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2117 for (
unsigned i = 0; i < NumVecs; ++i)
2118 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2119 AArch64::zsub0 + i,
DL, VT, SuperReg));
2122 unsigned ChainIdx = NumVecs;
2124 CurDAG->RemoveDeadNode(
N);
2127void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2132 assert(Opcode != 0 &&
"Unexpected opcode");
2135 EVT VT =
N->getValueType(0);
2136 SDUse *OpsIter =
N->op_begin() + 1;
2139 auto GetMultiVecOperand = [&]() {
2142 return createZMulTuple(Regs);
2146 Ops.push_back(*OpsIter++);
2148 Ops.push_back(GetMultiVecOperand());
2150 Ops.push_back(GetMultiVecOperand());
2152 Ops.push_back(*OpsIter++);
2155 Ops.append(OpsIter,
N->op_end());
2157 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2159 for (
unsigned i = 0; i < NumVecs; ++i)
2160 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2161 AArch64::zsub0 + i,
DL, VT, SuperReg));
2163 CurDAG->RemoveDeadNode(
N);
2166void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2167 unsigned Scale,
unsigned Opc_ri,
2168 unsigned Opc_rr,
bool IsIntr) {
2169 assert(Scale < 5 &&
"Invalid scaling value.");
2171 EVT VT =
N->getValueType(0);
2178 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2179 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2185 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2187 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2189 for (
unsigned i = 0; i < NumVecs; ++i)
2190 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2191 AArch64::zsub0 + i,
DL, VT, SuperReg));
2194 unsigned ChainIdx = NumVecs;
2196 CurDAG->RemoveDeadNode(
N);
2199void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2204 assert(Scale < 4 &&
"Invalid scaling value.");
2206 EVT VT =
N->getValueType(0);
2214 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2220 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2222 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2224 for (
unsigned i = 0; i < NumVecs; ++i)
2225 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2226 AArch64::zsub0 + i,
DL, VT, SuperReg));
2229 unsigned ChainIdx = NumVecs;
2231 CurDAG->RemoveDeadNode(
N);
2234void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2236 if (
N->getValueType(0) != MVT::nxv4f32)
2238 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2241void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2242 unsigned NumOutVecs,
2246 if (
Imm->getZExtValue() > MaxImm)
2250 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2256 EVT VT =
Node->getValueType(0);
2259 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2262 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2263 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2264 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2267 unsigned ChainIdx = NumOutVecs;
2269 CurDAG->RemoveDeadNode(Node);
2272void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2273 unsigned NumOutVecs,
2276 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2281 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2285 EVT VT =
Node->getValueType(0);
2288 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2291 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2292 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2293 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2296 unsigned ChainIdx = NumOutVecs;
2298 CurDAG->RemoveDeadNode(Node);
2301void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2304 EVT VT =
N->getValueType(0);
2307 SDValue Zd = createZMulTuple(Regs);
2308 SDValue Zn =
N->getOperand(1 + NumVecs);
2309 SDValue Zm =
N->getOperand(2 + NumVecs);
2315 for (
unsigned i = 0; i < NumVecs; ++i)
2316 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2317 AArch64::zsub0 + i,
DL, VT, SuperReg));
2319 CurDAG->RemoveDeadNode(
N);
2349template <
unsigned MaxIdx,
unsigned Scale>
2350void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2351 unsigned BaseReg,
unsigned Op) {
2352 unsigned TileNum = 0;
2353 if (BaseReg != AArch64::ZA)
2354 TileNum =
N->getConstantOperandVal(2);
2360 if (BaseReg == AArch64::ZA)
2365 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2369 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2371 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2373 EVT VT =
N->getValueType(0);
2374 for (
unsigned I = 0;
I < NumVecs; ++
I)
2376 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2379 unsigned ChainIdx = NumVecs;
2381 CurDAG->RemoveDeadNode(
N);
2384void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2385 unsigned Op,
unsigned MaxIdx,
2386 unsigned Scale,
unsigned BaseReg) {
2391 if (BaseReg != AArch64::ZA)
2395 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2402 if (BaseReg != AArch64::ZA )
2403 Ops.push_back(
N->getOperand(2));
2406 Ops.push_back(
N->getOperand(0));
2407 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2409 EVT VT =
N->getValueType(0);
2410 for (
unsigned I = 0;
I < NumVecs; ++
I)
2412 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2416 unsigned ChainIdx = NumVecs;
2418 CurDAG->RemoveDeadNode(
N);
2421void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2422 unsigned NumOutVecs,
2426 EVT VT =
N->getValueType(0);
2427 unsigned NumInVecs =
N->getNumOperands() - 1;
2431 assert((NumInVecs == 2 || NumInVecs == 4) &&
2432 "Don't know how to handle multi-register input!");
2434 Ops.push_back(createZMulTuple(Regs));
2437 for (
unsigned I = 0;
I < NumInVecs;
I++)
2438 Ops.push_back(
N->getOperand(1 +
I));
2441 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2444 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2445 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2446 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2447 CurDAG->RemoveDeadNode(
N);
2450void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2453 EVT VT =
N->getOperand(2)->getValueType(0);
2461 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2470void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2471 unsigned Scale,
unsigned Opc_rr,
2477 SDValue RegSeq = createZTuple(Regs);
2483 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2484 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2490 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2498 const DataLayout &
DL = CurDAG->getDataLayout();
2499 const TargetLowering *TLI = getTargetLowering();
2503 int FI = FINode->getIndex();
2505 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2512void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2515 EVT VT =
N->getOperand(2)->getValueType(0);
2516 const EVT ResTys[] = {MVT::i64,
2528 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2572void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2575 EVT VT =
N->getValueType(0);
2587 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2589 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2591 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2593 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2597 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2598 AArch64::qsub2, AArch64::qsub3 };
2599 for (
unsigned i = 0; i < NumVecs; ++i) {
2600 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2607 CurDAG->RemoveDeadNode(
N);
2610void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2613 EVT VT =
N->getValueType(0);
2625 const EVT ResTys[] = {MVT::i64,
2628 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2631 CurDAG->getTargetConstant(LaneNo, dl,
2636 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2648 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2649 AArch64::qsub2, AArch64::qsub3 };
2650 for (
unsigned i = 0; i < NumVecs; ++i) {
2651 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2661 CurDAG->RemoveDeadNode(
N);
2664void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2667 EVT VT =
N->getOperand(2)->getValueType(0);
2679 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2681 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2683 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2692void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2695 EVT VT =
N->getOperand(2)->getValueType(0);
2707 const EVT ResTys[] = {MVT::i64,
2710 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2712 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2716 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2727 unsigned &LSB,
unsigned &MSB,
2728 unsigned NumberOfIgnoredLowBits,
2729 bool BiggerPattern) {
2731 "N must be a AND operation to call this function");
2733 EVT VT =
N->getValueType(0);
2738 assert((VT == MVT::i32 || VT == MVT::i64) &&
2739 "Type checking must have been done before calling this function");
2753 const SDNode *Op0 =
N->getOperand(0).getNode();
2760 if (AndImm & (AndImm + 1))
2763 bool ClampMSB =
false;
2783 ClampMSB = (VT == MVT::i32);
2784 }
else if (BiggerPattern) {
2790 Opd0 =
N->getOperand(0);
2796 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2799 <<
": Found large shift immediate, this should not happen\n"));
2813 MSB = MSB > 31 ? 31 : MSB;
2815 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2820 SDValue &Opd0,
unsigned &Immr,
2824 EVT VT =
N->getValueType(0);
2826 assert((VT == MVT::i32 || VT == MVT::i64) &&
2827 "Type checking must have been done before calling this function");
2831 Op =
Op->getOperand(0);
2832 VT =
Op->getValueType(0);
2841 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2845 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2846 Opd0 =
Op.getOperand(0);
2848 Imms = ShiftImm + Width - 1;
2876 Opd0 =
N->getOperand(0).getOperand(0);
2886 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2893 unsigned &Immr,
unsigned &Imms,
2894 bool BiggerPattern) {
2896 "N must be a SHR/SRA operation to call this function");
2898 EVT VT =
N->getValueType(0);
2903 assert((VT == MVT::i32 || VT == MVT::i64) &&
2904 "Type checking must have been done before calling this function");
2914 Opd0 =
N->getOperand(0).getOperand(0);
2915 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2921 Opd0 =
N->getOperand(0).getOperand(0);
2924 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2925 }
else if (BiggerPattern) {
2929 Opd0 =
N->getOperand(0);
2938 <<
": Found large shift immediate, this should not happen\n"));
2947 "bad amount in shift node!");
2948 int immr = SrlImm - ShlImm;
2953 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2955 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2959bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2962 EVT VT =
N->getValueType(0);
2963 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2964 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2975 unsigned Immr = ShiftImm;
2977 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2978 CurDAG->getTargetConstant(Imms, dl, VT)};
2979 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2984 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2985 unsigned NumberOfIgnoredLowBits = 0,
2986 bool BiggerPattern =
false) {
2987 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2990 switch (
N->getOpcode()) {
2992 if (!
N->isMachineOpcode())
2997 NumberOfIgnoredLowBits, BiggerPattern);
3006 unsigned NOpc =
N->getMachineOpcode();
3010 case AArch64::SBFMWri:
3011 case AArch64::UBFMWri:
3012 case AArch64::SBFMXri:
3013 case AArch64::UBFMXri:
3015 Opd0 =
N->getOperand(0);
3016 Immr =
N->getConstantOperandVal(1);
3017 Imms =
N->getConstantOperandVal(2);
3024bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3025 unsigned Opc, Immr, Imms;
3030 EVT VT =
N->getValueType(0);
3035 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3036 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3037 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3039 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3040 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3046 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3047 CurDAG->getTargetConstant(Imms, dl, VT)};
3048 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3057 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3058 assert((VT == MVT::i32 || VT == MVT::i64) &&
3059 "i32 or i64 mask type expected!");
3063 APInt SignificantDstMask =
3067 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3068 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3101 APInt OpUsefulBits(UsefulBits);
3105 OpUsefulBits <<= MSB - Imm + 1;
3110 OpUsefulBits <<= Imm;
3112 OpUsefulBits <<= MSB + 1;
3115 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3121 UsefulBits &= OpUsefulBits;
3138 APInt Mask(UsefulBits);
3139 Mask.clearAllBits();
3147 Mask.lshrInPlace(ShiftAmt);
3153 Mask.lshrInPlace(ShiftAmt);
3169 APInt OpUsefulBits(UsefulBits);
3183 OpUsefulBits <<= Width;
3186 if (
Op.getOperand(1) == Orig) {
3188 Mask = ResultUsefulBits & OpUsefulBits;
3192 if (
Op.getOperand(0) == Orig)
3194 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3200 OpUsefulBits <<= Width;
3202 OpUsefulBits <<= LSB;
3204 if (
Op.getOperand(1) == Orig) {
3206 Mask = ResultUsefulBits & OpUsefulBits;
3207 Mask.lshrInPlace(LSB);
3210 if (
Op.getOperand(0) == Orig)
3211 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3228 case AArch64::ANDSWri:
3229 case AArch64::ANDSXri:
3230 case AArch64::ANDWri:
3231 case AArch64::ANDXri:
3235 case AArch64::UBFMWri:
3236 case AArch64::UBFMXri:
3239 case AArch64::ORRWrs:
3240 case AArch64::ORRXrs:
3245 case AArch64::BFMWri:
3246 case AArch64::BFMXri:
3249 case AArch64::STRBBui:
3250 case AArch64::STURBBi:
3256 case AArch64::STRHHui:
3257 case AArch64::STURHHi:
3270 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3272 UsefulBits =
APInt(Bitwidth, 0);
3281 UsersUsefulBits |= UsefulBitsForUse;
3286 UsefulBits &= UsersUsefulBits;
3296 EVT VT =
Op.getValueType();
3299 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3302 if (ShlAmount > 0) {
3305 UBFMOpc, dl, VT,
Op,
3310 assert(ShlAmount < 0 &&
"expected right shift");
3311 int ShrAmount = -ShlAmount;
3323 const uint64_t NonZeroBits,
3330 const uint64_t NonZeroBits,
3337 bool BiggerPattern,
SDValue &Src,
3338 int &DstLSB,
int &Width) {
3339 EVT VT =
Op.getValueType();
3348 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3352 switch (
Op.getOpcode()) {
3357 NonZeroBits, Src, DstLSB, Width);
3360 NonZeroBits, Src, DstLSB, Width);
3373 EVT VT =
Op.getValueType();
3374 assert((VT == MVT::i32 || VT == MVT::i64) &&
3375 "Caller guarantees VT is one of i32 or i64");
3388 assert((~AndImm & NonZeroBits) == 0 &&
3389 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3418 if (!BiggerPattern && !AndOp0.
hasOneUse())
3437 <<
"Found large Width in bit-field-positioning -- this indicates no "
3438 "proper combining / constant folding was performed\n");
3447 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3462 "Op.getNode() should be a SHL node to call this function");
3464 "Op.getNode() should shift ShlImm to call this function");
3471 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3495 EVT VT =
Op.getValueType();
3496 assert((VT == MVT::i32 || VT == MVT::i64) &&
3497 "Caller guarantees that type is i32 or i64");
3504 if (!BiggerPattern && !
Op.hasOneUse())
3513 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3521 assert(VT == MVT::i32 || VT == MVT::i64);
3532 EVT VT =
N->getValueType(0);
3533 if (VT != MVT::i32 && VT != MVT::i64)
3551 if (!
And.hasOneUse() ||
3561 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3568 if ((OrImm & NotKnownZero) != 0) {
3580 unsigned ImmS = Width - 1;
3586 bool IsBFI = LSB != 0;
3591 unsigned OrChunks = 0, BFIChunks = 0;
3592 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3593 if (((OrImm >> Shift) & 0xFFFF) != 0)
3595 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3598 if (BFIChunks > OrChunks)
3604 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3612 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3621 if (!Dst.hasOneUse())
3624 EVT VT = Dst.getValueType();
3625 assert((VT == MVT::i32 || VT == MVT::i64) &&
3626 "Caller should guarantee that VT is one of i32 or i64");
3654 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3655 unsigned MaskWidth =
3658 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3664 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3665 ShiftedOperand =
SDValue(UBFMNode, 0);
3694 const bool BiggerPattern) {
3695 EVT VT =
N->getValueType(0);
3696 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3697 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3698 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3699 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3700 assert((VT == MVT::i32 || VT == MVT::i64) &&
3701 "Expect result type to be i32 or i64 since N is combinable to BFM");
3708 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3711 if (BiggerPattern) {
3734 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3796 EVT VT =
N->getValueType(0);
3797 if (VT != MVT::i32 && VT != MVT::i64)
3805 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3806 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3826 for (
int I = 0;
I < 4; ++
I) {
3829 unsigned ImmR, ImmS;
3830 bool BiggerPattern =
I / 2;
3831 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3833 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3839 NumberOfIgnoredLowBits, BiggerPattern)) {
3842 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3843 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3848 Width = ImmS - ImmR + 1;
3859 Src, DstLSB, Width)) {
3867 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3877 APInt BitsToBeInserted =
3880 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3904 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3937 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3939 if (Src->hasOneUse() &&
3942 Src = Src->getOperand(0);
3952 unsigned ImmS = Width - 1;
3958 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3966bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3975 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3988bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3992 EVT VT =
N->getValueType(0);
3993 if (VT != MVT::i32 && VT != MVT::i64)
3999 Op0, DstLSB, Width))
4005 unsigned ImmS = Width - 1;
4008 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4009 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4010 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4011 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4017bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4018 EVT VT =
N->getValueType(0);
4021 switch (
N->getOpcode()) {
4023 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4026 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4029 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4032 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4040 if (VT == MVT::i32) {
4043 }
else if (VT == MVT::i64) {
4049 SDValue ShiftAmt =
N->getOperand(1);
4069 (Add0Imm %
Size == 0)) {
4075 if (SubVT == MVT::i32) {
4076 NegOpc = AArch64::SUBWrr;
4077 ZeroReg = AArch64::WZR;
4079 assert(SubVT == MVT::i64);
4080 NegOpc = AArch64::SUBXrr;
4081 ZeroReg = AArch64::XZR;
4084 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4085 MachineSDNode *Neg =
4086 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4087 NewShiftAmt =
SDValue(Neg, 0);
4095 if (SubVT == MVT::i32) {
4096 NotOpc = AArch64::ORNWrr;
4097 ZeroReg = AArch64::WZR;
4099 assert(SubVT == MVT::i64);
4100 NotOpc = AArch64::ORNXrr;
4101 ZeroReg = AArch64::XZR;
4104 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4105 MachineSDNode *
Not =
4106 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4107 NewShiftAmt =
SDValue(Not, 0);
4128 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4129 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4130 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4131 NewShiftAmt, SubReg);
4132 NewShiftAmt =
SDValue(Ext, 0);
4136 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4143 bool isReciprocal) {
4146 FVal = CN->getValueAPF();
4149 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4159 if (
unsigned FBits =
4172 bool isReciprocal) {
4173 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4174 N.getValueType().getScalarSizeInBits() ==
4175 N.getOperand(0).getValueType().getScalarSizeInBits())
4176 N =
N.getOperand(0);
4178 auto ImmToFloat = [RegWidth](
APInt Imm) {
4192 switch (
N->getOpcode()) {
4193 case AArch64ISD::MOVIshift:
4194 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4195 <<
N.getConstantOperandVal(1)));
4197 case AArch64ISD::FMOV:
4198 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4200 case AArch64ISD::DUP:
4202 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4210 if (
unsigned FBits =
4219bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4220 unsigned RegWidth) {
4225bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4226 unsigned RegWidth) {
4228 CurDAG,
N, FixedPos, RegWidth,
false);
4231bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(
SDValue N,
4233 unsigned RegWidth) {
4235 CurDAG,
N, FixedPos, RegWidth,
true);
4238bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4240 unsigned RegWidth) {
4250 RegString.
split(Fields,
':');
4252 if (Fields.
size() == 1)
4256 &&
"Invalid number of fields in read register string");
4259 bool AllIntFields =
true;
4263 AllIntFields &= !
Field.getAsInteger(10, IntField);
4264 Ops.push_back(IntField);
4268 "Unexpected non-integer value in special register string.");
4271 if (
Ops[0] < 2 ||
Ops[1] > 7 ||
Ops[2] > 15 ||
Ops[3] > 15 ||
Ops[4] > 7)
4278 return ((
Ops[0] & 0x1) << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4279 (
Ops[3] << 3) | (
Ops[4]);
4286bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4288 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4291 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4293 unsigned Opcode64Bit = AArch64::MRS;
4298 const auto *TheReg =
4299 AArch64SysReg::lookupSysRegByName(RegString->getString());
4300 if (TheReg && TheReg->Readable &&
4301 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4302 Imm = TheReg->Encoding;
4308 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4309 Opcode64Bit = AArch64::ADR;
4317 SDValue InChain =
N->getOperand(0);
4318 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4319 if (!ReadIs128Bit) {
4320 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4321 {SysRegImm, InChain});
4323 SDNode *MRRS = CurDAG->getMachineNode(
4325 {MVT::Untyped , MVT::Other },
4326 {SysRegImm, InChain});
4330 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4332 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4338 ReplaceUses(
SDValue(
N, 2), OutChain);
4347bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4349 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4352 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4354 if (!WriteIs128Bit) {
4360 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4363 "Expected a constant integer expression.");
4364 unsigned Reg = PMapper->Encoding;
4365 uint64_t Immed =
N->getConstantOperandVal(2);
4366 CurDAG->SelectNodeTo(
4367 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4368 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4374 if (trySelectPState(
4375 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4376 AArch64::MSRpstateImm4))
4378 if (trySelectPState(
4379 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4380 AArch64::MSRpstateImm1))
4389 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4390 if (TheReg && TheReg->Writeable &&
4391 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4392 Imm = TheReg->Encoding;
4401 if (!WriteIs128Bit) {
4402 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4403 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4404 N->getOperand(2), InChain);
4408 SDNode *Pair = CurDAG->getMachineNode(
4409 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4410 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4413 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4415 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4417 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4418 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4426bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4431 if (Subtarget->hasLSE())
return false;
4433 if (MemTy == MVT::i8)
4434 Opcode = AArch64::CMP_SWAP_8;
4435 else if (MemTy == MVT::i16)
4436 Opcode = AArch64::CMP_SWAP_16;
4437 else if (MemTy == MVT::i32)
4438 Opcode = AArch64::CMP_SWAP_32;
4439 else if (MemTy == MVT::i64)
4440 Opcode = AArch64::CMP_SWAP_64;
4444 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4445 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4447 SDNode *CmpSwap = CurDAG->getMachineNode(
4449 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4456 CurDAG->RemoveDeadNode(
N);
4461bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4462 SDValue &Shift,
bool Negate) {
4469 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4472bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4481 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4488 if ((Val & ~0xff) == 0) {
4489 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4494 if ((Val & ~0xff00) == 0) {
4495 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4507bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4531 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4532 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4539 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4540 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4544 if (Val <= 65280 && Val % 256 == 0) {
4545 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4546 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4557bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4567 int32_t ImmVal, ShiftVal;
4572 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4573 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4577bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4579 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4583bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4586 if (ImmVal >= -128 && ImmVal < 128) {
4587 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4593bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4595 uint64_t ImmVal = CNode->getZExtValue();
4605 ImmVal &= 0xFFFFFFFF;
4614 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4621bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4625 ImmVal = CI->getZExtValue();
4627 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4638 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4647bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4648 uint64_t
High,
bool AllowSaturation,
4651 uint64_t ImmVal = CN->getZExtValue();
4658 if (ImmVal >
High) {
4659 if (!AllowSaturation)
4664 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4671bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4685 const TargetLowering *TLI = getTargetLowering();
4688 SDValue FiOp = CurDAG->getTargetFrameIndex(
4690 int TagOffset =
N->getConstantOperandVal(3);
4692 SDNode *Out = CurDAG->getMachineNode(
4693 AArch64::TAGPstack,
DL, MVT::i64,
4694 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4695 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4696 ReplaceNode(
N, Out);
4700void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4702 "llvm.aarch64.tagp third argument must be an immediate");
4703 if (trySelectStackSlotTagP(
N))
4710 int TagOffset =
N->getConstantOperandVal(3);
4711 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4712 {
N->getOperand(1),
N->getOperand(2)});
4713 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4714 {
SDValue(N1, 0),
N->getOperand(2)});
4715 SDNode *N3 = CurDAG->getMachineNode(
4716 AArch64::ADDG,
DL, MVT::i64,
4717 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4718 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4722bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4726 if (
N->getConstantOperandVal(2) != 0)
4728 if (!
N->getOperand(0).isUndef())
4732 EVT VT =
N->getValueType(0);
4733 EVT InVT =
N->getOperand(1).getValueType();
4744 "Expected to insert into a packed scalable vector!");
4747 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4748 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4749 N->getOperand(1), RC));
4753bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4757 if (
N->getConstantOperandVal(1) != 0)
4761 EVT VT =
N->getValueType(0);
4762 EVT InVT =
N->getOperand(0).getValueType();
4773 "Expected to extract from a packed scalable vector!");
4776 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4777 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4778 N->getOperand(0), RC));
4782bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4788 EVT VT =
N->getValueType(0);
4801 (Subtarget->hasSVE2() ||
4802 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4803 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4806 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4810 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4811 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4812 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4819 bool IsXOROperand =
true;
4821 IsXOROperand =
false;
4827 APInt ShlAmt, ShrAmt;
4835 if (!IsXOROperand) {
4837 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4840 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4841 SDNode *SubRegToReg =
4842 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4853 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4854 AArch64::XAR_ZZZI_D})) {
4855 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4880 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4890 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4898 bool IsXOROperand =
true;
4900 IsXOROperand =
false;
4903 R1 =
XOR.getOperand(0);
4904 R2 =
XOR.getOperand(1);
4914 if (ShAmt + HsAmt != VTSizeInBits)
4917 if (!IsXOROperand) {
4920 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4929 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4935 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4936 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4938 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4941 if (
R2.getValueType() == VT)
4942 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4947 SDValue SubReg = CurDAG->getTargetConstant(
4950 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4955 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4961 SDNode *XAR =
nullptr;
4965 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4966 AArch64::XAR_ZZZI_D}))
4967 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4969 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4972 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4978 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4979 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4982 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4983 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4986 SDValue SubReg = CurDAG->getTargetConstant(
4989 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4993 ReplaceNode(
N, XAR);
4997void AArch64DAGToDAGISel::Select(SDNode *Node) {
4999 if (
Node->isMachineOpcode()) {
5001 Node->setNodeId(-1);
5006 EVT VT =
Node->getValueType(0);
5008 switch (
Node->getOpcode()) {
5013 if (SelectCMP_SWAP(Node))
5018 case AArch64ISD::MRRS:
5019 if (tryReadRegister(Node))
5024 case AArch64ISD::MSRR:
5025 if (tryWriteRegister(Node))
5032 if (tryIndexedLoad(Node))
5041 if (tryBitfieldExtractOp(Node))
5043 if (tryBitfieldInsertInZeroOp(Node))
5048 if (tryShiftAmountMod(Node))
5053 if (tryBitfieldExtractOpFromSExt(Node))
5058 if (tryBitfieldInsertOp(Node))
5060 if (trySelectXAR(Node))
5065 if (trySelectCastScalableToFixedLengthVector(Node))
5071 if (trySelectCastFixedLengthToScalableVector(Node))
5080 if (ConstNode->
isZero()) {
5081 if (VT == MVT::i32) {
5083 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5084 ReplaceNode(Node,
New.getNode());
5086 }
else if (VT == MVT::i64) {
5088 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5089 ReplaceNode(Node,
New.getNode());
5100 const TargetLowering *TLI = getTargetLowering();
5101 SDValue TFI = CurDAG->getTargetFrameIndex(
5104 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5105 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5106 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5110 unsigned IntNo =
Node->getConstantOperandVal(1);
5114 case Intrinsic::aarch64_gcsss: {
5118 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5120 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5121 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5122 MVT::Other, Zero,
SDValue(SS1, 0));
5123 ReplaceNode(Node, SS2);
5126 case Intrinsic::aarch64_ldaxp:
5127 case Intrinsic::aarch64_ldxp: {
5129 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5134 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5135 MVT::Other, MemAddr, Chain);
5138 MachineMemOperand *MemOp =
5141 ReplaceNode(Node, Ld);
5144 case Intrinsic::aarch64_stlxp:
5145 case Intrinsic::aarch64_stxp: {
5147 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5155 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5157 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5159 MachineMemOperand *MemOp =
5163 ReplaceNode(Node, St);
5166 case Intrinsic::aarch64_neon_ld1x2:
5167 if (VT == MVT::v8i8) {
5168 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5170 }
else if (VT == MVT::v16i8) {
5171 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5173 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5174 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5176 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5177 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5179 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5180 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5182 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5183 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5185 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5186 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5188 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5189 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5193 case Intrinsic::aarch64_neon_ld1x3:
5194 if (VT == MVT::v8i8) {
5195 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5197 }
else if (VT == MVT::v16i8) {
5198 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5200 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5201 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5203 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5204 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5206 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5207 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5209 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5210 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5212 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5213 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5215 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5216 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5220 case Intrinsic::aarch64_neon_ld1x4:
5221 if (VT == MVT::v8i8) {
5222 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5224 }
else if (VT == MVT::v16i8) {
5225 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5227 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5228 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5230 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5231 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5233 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5234 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5236 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5237 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5239 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5240 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5242 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5243 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5247 case Intrinsic::aarch64_neon_ld2:
5248 if (VT == MVT::v8i8) {
5249 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5251 }
else if (VT == MVT::v16i8) {
5252 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5254 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5255 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5257 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5258 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5260 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5261 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5263 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5264 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5266 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5267 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5269 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5270 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5274 case Intrinsic::aarch64_neon_ld3:
5275 if (VT == MVT::v8i8) {
5276 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5278 }
else if (VT == MVT::v16i8) {
5279 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5281 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5282 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5284 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5285 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5287 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5288 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5290 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5291 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5293 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5294 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5296 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5297 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5301 case Intrinsic::aarch64_neon_ld4:
5302 if (VT == MVT::v8i8) {
5303 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5305 }
else if (VT == MVT::v16i8) {
5306 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5308 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5309 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5311 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5312 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5314 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5315 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5317 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5318 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5320 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5321 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5323 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5324 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5328 case Intrinsic::aarch64_neon_ld2r:
5329 if (VT == MVT::v8i8) {
5330 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5332 }
else if (VT == MVT::v16i8) {
5333 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5335 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5336 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5338 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5339 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5341 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5342 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5344 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5345 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5347 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5348 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5350 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5351 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5355 case Intrinsic::aarch64_neon_ld3r:
5356 if (VT == MVT::v8i8) {
5357 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5359 }
else if (VT == MVT::v16i8) {
5360 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5362 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5363 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5365 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5366 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5368 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5369 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5371 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5372 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5374 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5375 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5377 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5378 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5382 case Intrinsic::aarch64_neon_ld4r:
5383 if (VT == MVT::v8i8) {
5384 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5386 }
else if (VT == MVT::v16i8) {
5387 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5389 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5390 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5392 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5393 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5395 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5396 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5398 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5399 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5401 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5402 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5404 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5405 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5409 case Intrinsic::aarch64_neon_ld2lane:
5410 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5411 SelectLoadLane(Node, 2, AArch64::LD2i8);
5413 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5414 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5415 SelectLoadLane(Node, 2, AArch64::LD2i16);
5417 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5419 SelectLoadLane(Node, 2, AArch64::LD2i32);
5421 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5423 SelectLoadLane(Node, 2, AArch64::LD2i64);
5427 case Intrinsic::aarch64_neon_ld3lane:
5428 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5429 SelectLoadLane(Node, 3, AArch64::LD3i8);
5431 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5432 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5433 SelectLoadLane(Node, 3, AArch64::LD3i16);
5435 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5437 SelectLoadLane(Node, 3, AArch64::LD3i32);
5439 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5441 SelectLoadLane(Node, 3, AArch64::LD3i64);
5445 case Intrinsic::aarch64_neon_ld4lane:
5446 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5447 SelectLoadLane(Node, 4, AArch64::LD4i8);
5449 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5450 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5451 SelectLoadLane(Node, 4, AArch64::LD4i16);
5453 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5455 SelectLoadLane(Node, 4, AArch64::LD4i32);
5457 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5459 SelectLoadLane(Node, 4, AArch64::LD4i64);
5463 case Intrinsic::aarch64_ld64b:
5464 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5466 case Intrinsic::aarch64_sve_ld2q_sret: {
5467 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5470 case Intrinsic::aarch64_sve_ld3q_sret: {
5471 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5474 case Intrinsic::aarch64_sve_ld4q_sret: {
5475 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5478 case Intrinsic::aarch64_sve_ld2_sret: {
5479 if (VT == MVT::nxv16i8) {
5480 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5483 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5484 VT == MVT::nxv8bf16) {
5485 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5488 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5489 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5492 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5493 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5499 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5500 if (VT == MVT::nxv16i8) {
5501 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5502 SelectContiguousMultiVectorLoad(
5503 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5504 else if (Subtarget->hasSVE2p1())
5505 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5510 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5511 VT == MVT::nxv8bf16) {
5512 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5513 SelectContiguousMultiVectorLoad(
5514 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5515 else if (Subtarget->hasSVE2p1())
5516 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5521 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5522 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5523 SelectContiguousMultiVectorLoad(
5524 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5525 else if (Subtarget->hasSVE2p1())
5526 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5531 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5532 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5533 SelectContiguousMultiVectorLoad(
5534 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5535 else if (Subtarget->hasSVE2p1())
5536 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5544 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5545 if (VT == MVT::nxv16i8) {
5546 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5547 SelectContiguousMultiVectorLoad(
5548 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5549 else if (Subtarget->hasSVE2p1())
5550 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5555 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5556 VT == MVT::nxv8bf16) {
5557 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5558 SelectContiguousMultiVectorLoad(
5559 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5560 else if (Subtarget->hasSVE2p1())
5561 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5566 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5567 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5568 SelectContiguousMultiVectorLoad(
5569 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5570 else if (Subtarget->hasSVE2p1())
5571 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5576 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5577 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5578 SelectContiguousMultiVectorLoad(
5579 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5580 else if (Subtarget->hasSVE2p1())
5581 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5589 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5590 if (VT == MVT::nxv16i8) {
5591 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5592 SelectContiguousMultiVectorLoad(Node, 2, 0,
5593 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5594 AArch64::LDNT1B_2Z_PSEUDO);
5595 else if (Subtarget->hasSVE2p1())
5596 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5597 AArch64::LDNT1B_2Z);
5601 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5602 VT == MVT::nxv8bf16) {
5603 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5604 SelectContiguousMultiVectorLoad(Node, 2, 1,
5605 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5606 AArch64::LDNT1H_2Z_PSEUDO);
5607 else if (Subtarget->hasSVE2p1())
5608 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5609 AArch64::LDNT1H_2Z);
5613 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5614 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5615 SelectContiguousMultiVectorLoad(Node, 2, 2,
5616 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5617 AArch64::LDNT1W_2Z_PSEUDO);
5618 else if (Subtarget->hasSVE2p1())
5619 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5620 AArch64::LDNT1W_2Z);
5624 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5625 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5626 SelectContiguousMultiVectorLoad(Node, 2, 3,
5627 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5628 AArch64::LDNT1D_2Z_PSEUDO);
5629 else if (Subtarget->hasSVE2p1())
5630 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5631 AArch64::LDNT1D_2Z);
5638 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5639 if (VT == MVT::nxv16i8) {
5640 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5641 SelectContiguousMultiVectorLoad(Node, 4, 0,
5642 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5643 AArch64::LDNT1B_4Z_PSEUDO);
5644 else if (Subtarget->hasSVE2p1())
5645 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5646 AArch64::LDNT1B_4Z);
5650 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5651 VT == MVT::nxv8bf16) {
5652 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5653 SelectContiguousMultiVectorLoad(Node, 4, 1,
5654 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5655 AArch64::LDNT1H_4Z_PSEUDO);
5656 else if (Subtarget->hasSVE2p1())
5657 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5658 AArch64::LDNT1H_4Z);
5662 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5663 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5664 SelectContiguousMultiVectorLoad(Node, 4, 2,
5665 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5666 AArch64::LDNT1W_4Z_PSEUDO);
5667 else if (Subtarget->hasSVE2p1())
5668 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5669 AArch64::LDNT1W_4Z);
5673 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5674 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5675 SelectContiguousMultiVectorLoad(Node, 4, 3,
5676 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5677 AArch64::LDNT1D_4Z_PSEUDO);
5678 else if (Subtarget->hasSVE2p1())
5679 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5680 AArch64::LDNT1D_4Z);
5687 case Intrinsic::aarch64_sve_ld3_sret: {
5688 if (VT == MVT::nxv16i8) {
5689 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5692 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5693 VT == MVT::nxv8bf16) {
5694 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5697 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5698 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5701 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5702 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5708 case Intrinsic::aarch64_sve_ld4_sret: {
5709 if (VT == MVT::nxv16i8) {
5710 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5713 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5714 VT == MVT::nxv8bf16) {
5715 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5718 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5719 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5722 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5723 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5729 case Intrinsic::aarch64_sme_read_hor_vg2: {
5730 if (VT == MVT::nxv16i8) {
5731 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5732 AArch64::MOVA_2ZMXI_H_B);
5734 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5735 VT == MVT::nxv8bf16) {
5736 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5737 AArch64::MOVA_2ZMXI_H_H);
5739 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5740 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5741 AArch64::MOVA_2ZMXI_H_S);
5743 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5744 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5745 AArch64::MOVA_2ZMXI_H_D);
5750 case Intrinsic::aarch64_sme_read_ver_vg2: {
5751 if (VT == MVT::nxv16i8) {
5752 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5753 AArch64::MOVA_2ZMXI_V_B);
5755 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5756 VT == MVT::nxv8bf16) {
5757 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5758 AArch64::MOVA_2ZMXI_V_H);
5760 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5761 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5762 AArch64::MOVA_2ZMXI_V_S);
5764 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5765 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5766 AArch64::MOVA_2ZMXI_V_D);
5771 case Intrinsic::aarch64_sme_read_hor_vg4: {
5772 if (VT == MVT::nxv16i8) {
5773 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5774 AArch64::MOVA_4ZMXI_H_B);
5776 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5777 VT == MVT::nxv8bf16) {
5778 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5779 AArch64::MOVA_4ZMXI_H_H);
5781 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5782 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5783 AArch64::MOVA_4ZMXI_H_S);
5785 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5786 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5787 AArch64::MOVA_4ZMXI_H_D);
5792 case Intrinsic::aarch64_sme_read_ver_vg4: {
5793 if (VT == MVT::nxv16i8) {
5794 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5795 AArch64::MOVA_4ZMXI_V_B);
5797 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5798 VT == MVT::nxv8bf16) {
5799 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5800 AArch64::MOVA_4ZMXI_V_H);
5802 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5803 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5804 AArch64::MOVA_4ZMXI_V_S);
5806 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5807 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5808 AArch64::MOVA_4ZMXI_V_D);
5813 case Intrinsic::aarch64_sme_read_vg1x2: {
5814 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5815 AArch64::MOVA_VG2_2ZMXI);
5818 case Intrinsic::aarch64_sme_read_vg1x4: {
5819 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5820 AArch64::MOVA_VG4_4ZMXI);
5823 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5824 if (VT == MVT::nxv16i8) {
5825 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5827 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5828 VT == MVT::nxv8bf16) {
5829 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5831 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5832 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5834 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5835 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5840 case Intrinsic::aarch64_sme_readz_vert_x2: {
5841 if (VT == MVT::nxv16i8) {
5842 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5844 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5845 VT == MVT::nxv8bf16) {
5846 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5848 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5849 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5851 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5852 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5857 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5858 if (VT == MVT::nxv16i8) {
5859 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5861 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5862 VT == MVT::nxv8bf16) {
5863 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5865 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5866 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5868 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5869 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5874 case Intrinsic::aarch64_sme_readz_vert_x4: {
5875 if (VT == MVT::nxv16i8) {
5876 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5878 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5879 VT == MVT::nxv8bf16) {
5880 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5882 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5883 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5885 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5886 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5891 case Intrinsic::aarch64_sme_readz_x2: {
5892 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5896 case Intrinsic::aarch64_sme_readz_x4: {
5897 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5901 case Intrinsic::swift_async_context_addr: {
5904 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5906 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5907 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5908 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5910 ReplaceUses(
SDValue(Node, 0), Res);
5912 CurDAG->RemoveDeadNode(Node);
5914 auto &MF = CurDAG->getMachineFunction();
5915 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5916 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5919 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5921 Node->getValueType(0),
5922 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5923 AArch64::LUTI2_4ZTZI_S}))
5925 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5928 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5930 Node->getValueType(0),
5931 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5933 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5936 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5938 Node->getValueType(0),
5939 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5940 AArch64::LUTI2_2ZTZI_S}))
5942 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5945 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5947 Node->getValueType(0),
5948 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5949 AArch64::LUTI4_2ZTZI_S}))
5951 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5954 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5955 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5958 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5960 Node->getValueType(0),
5961 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5962 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5964 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5966 Node->getValueType(0),
5967 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5968 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5970 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5972 Node->getValueType(0),
5973 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5974 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5976 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5978 Node->getValueType(0),
5979 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5980 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5982 case Intrinsic::ptrauth_resign_load_relative:
5983 SelectPtrauthResign(Node);
5988 unsigned IntNo =
Node->getConstantOperandVal(0);
5992 case Intrinsic::aarch64_tagp:
5996 case Intrinsic::ptrauth_auth:
5997 SelectPtrauthAuth(Node);
6000 case Intrinsic::ptrauth_resign:
6001 SelectPtrauthResign(Node);
6004 case Intrinsic::aarch64_neon_tbl2:
6005 SelectTable(Node, 2,
6006 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
6009 case Intrinsic::aarch64_neon_tbl3:
6010 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
6011 : AArch64::TBLv16i8Three,
6014 case Intrinsic::aarch64_neon_tbl4:
6015 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6016 : AArch64::TBLv16i8Four,
6019 case Intrinsic::aarch64_neon_tbx2:
6020 SelectTable(Node, 2,
6021 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6024 case Intrinsic::aarch64_neon_tbx3:
6025 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6026 : AArch64::TBXv16i8Three,
6029 case Intrinsic::aarch64_neon_tbx4:
6030 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6031 : AArch64::TBXv16i8Four,
6034 case Intrinsic::aarch64_sve_srshl_single_x2:
6036 Node->getValueType(0),
6037 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6038 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6039 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6041 case Intrinsic::aarch64_sve_srshl_single_x4:
6043 Node->getValueType(0),
6044 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6045 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6046 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6048 case Intrinsic::aarch64_sve_urshl_single_x2:
6050 Node->getValueType(0),
6051 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6052 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6053 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6055 case Intrinsic::aarch64_sve_urshl_single_x4:
6057 Node->getValueType(0),
6058 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6059 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6060 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6062 case Intrinsic::aarch64_sve_srshl_x2:
6064 Node->getValueType(0),
6065 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6066 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6067 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6069 case Intrinsic::aarch64_sve_srshl_x4:
6071 Node->getValueType(0),
6072 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6073 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6074 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6076 case Intrinsic::aarch64_sve_urshl_x2:
6078 Node->getValueType(0),
6079 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6080 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6081 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6083 case Intrinsic::aarch64_sve_urshl_x4:
6085 Node->getValueType(0),
6086 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6087 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6088 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6090 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6092 Node->getValueType(0),
6093 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6094 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6095 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6097 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6099 Node->getValueType(0),
6100 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6101 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6102 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6104 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6106 Node->getValueType(0),
6107 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6108 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6109 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6111 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6113 Node->getValueType(0),
6114 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6115 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6116 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6118 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6120 Node->getValueType(0),
6121 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6122 AArch64::FSCALE_2ZZ_D}))
6123 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6125 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6127 Node->getValueType(0),
6128 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6129 AArch64::FSCALE_4ZZ_D}))
6130 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6132 case Intrinsic::aarch64_sme_fp8_scale_x2:
6134 Node->getValueType(0),
6135 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6136 AArch64::FSCALE_2Z2Z_D}))
6137 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6139 case Intrinsic::aarch64_sme_fp8_scale_x4:
6141 Node->getValueType(0),
6142 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6143 AArch64::FSCALE_4Z4Z_D}))
6144 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6146 case Intrinsic::aarch64_sve_whilege_x2:
6148 Node->getValueType(0),
6149 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6150 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6151 SelectWhilePair(Node,
Op);
6153 case Intrinsic::aarch64_sve_whilegt_x2:
6155 Node->getValueType(0),
6156 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6157 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6158 SelectWhilePair(Node,
Op);
6160 case Intrinsic::aarch64_sve_whilehi_x2:
6162 Node->getValueType(0),
6163 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6164 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6165 SelectWhilePair(Node,
Op);
6167 case Intrinsic::aarch64_sve_whilehs_x2:
6169 Node->getValueType(0),
6170 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6171 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6172 SelectWhilePair(Node,
Op);
6174 case Intrinsic::aarch64_sve_whilele_x2:
6176 Node->getValueType(0),
6177 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6178 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6179 SelectWhilePair(Node,
Op);
6181 case Intrinsic::aarch64_sve_whilelo_x2:
6183 Node->getValueType(0),
6184 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6185 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6186 SelectWhilePair(Node,
Op);
6188 case Intrinsic::aarch64_sve_whilels_x2:
6190 Node->getValueType(0),
6191 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6192 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6193 SelectWhilePair(Node,
Op);
6195 case Intrinsic::aarch64_sve_whilelt_x2:
6197 Node->getValueType(0),
6198 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6199 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6200 SelectWhilePair(Node,
Op);
6202 case Intrinsic::aarch64_sve_smax_single_x2:
6204 Node->getValueType(0),
6205 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6206 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6207 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6209 case Intrinsic::aarch64_sve_umax_single_x2:
6211 Node->getValueType(0),
6212 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6213 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6214 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6216 case Intrinsic::aarch64_sve_fmax_single_x2:
6218 Node->getValueType(0),
6219 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6220 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6221 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6223 case Intrinsic::aarch64_sve_smax_single_x4:
6225 Node->getValueType(0),
6226 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6227 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6228 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6230 case Intrinsic::aarch64_sve_umax_single_x4:
6232 Node->getValueType(0),
6233 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6234 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6235 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6237 case Intrinsic::aarch64_sve_fmax_single_x4:
6239 Node->getValueType(0),
6240 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6241 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6242 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6244 case Intrinsic::aarch64_sve_smin_single_x2:
6246 Node->getValueType(0),
6247 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6248 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6249 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6251 case Intrinsic::aarch64_sve_umin_single_x2:
6253 Node->getValueType(0),
6254 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6255 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6256 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6258 case Intrinsic::aarch64_sve_fmin_single_x2:
6260 Node->getValueType(0),
6261 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6262 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6263 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6265 case Intrinsic::aarch64_sve_smin_single_x4:
6267 Node->getValueType(0),
6268 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6269 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6270 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6272 case Intrinsic::aarch64_sve_umin_single_x4:
6274 Node->getValueType(0),
6275 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6276 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6277 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6279 case Intrinsic::aarch64_sve_fmin_single_x4:
6281 Node->getValueType(0),
6282 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6283 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6284 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6286 case Intrinsic::aarch64_sve_smax_x2:
6288 Node->getValueType(0),
6289 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6290 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6291 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6293 case Intrinsic::aarch64_sve_umax_x2:
6295 Node->getValueType(0),
6296 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6297 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6298 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6300 case Intrinsic::aarch64_sve_fmax_x2:
6302 Node->getValueType(0),
6303 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6304 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6305 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6307 case Intrinsic::aarch64_sve_smax_x4:
6309 Node->getValueType(0),
6310 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6311 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6312 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6314 case Intrinsic::aarch64_sve_umax_x4:
6316 Node->getValueType(0),
6317 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6318 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6319 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6321 case Intrinsic::aarch64_sve_fmax_x4:
6323 Node->getValueType(0),
6324 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6325 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6326 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6328 case Intrinsic::aarch64_sme_famax_x2:
6330 Node->getValueType(0),
6331 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6332 AArch64::FAMAX_2Z2Z_D}))
6333 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6335 case Intrinsic::aarch64_sme_famax_x4:
6337 Node->getValueType(0),
6338 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6339 AArch64::FAMAX_4Z4Z_D}))
6340 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6342 case Intrinsic::aarch64_sme_famin_x2:
6344 Node->getValueType(0),
6345 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6346 AArch64::FAMIN_2Z2Z_D}))
6347 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6349 case Intrinsic::aarch64_sme_famin_x4:
6351 Node->getValueType(0),
6352 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6353 AArch64::FAMIN_4Z4Z_D}))
6354 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6356 case Intrinsic::aarch64_sve_smin_x2:
6358 Node->getValueType(0),
6359 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6360 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6361 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6363 case Intrinsic::aarch64_sve_umin_x2:
6365 Node->getValueType(0),
6366 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6367 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6368 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6370 case Intrinsic::aarch64_sve_fmin_x2:
6372 Node->getValueType(0),
6373 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6374 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6375 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6377 case Intrinsic::aarch64_sve_smin_x4:
6379 Node->getValueType(0),
6380 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6381 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6382 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6384 case Intrinsic::aarch64_sve_umin_x4:
6386 Node->getValueType(0),
6387 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6388 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6389 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6391 case Intrinsic::aarch64_sve_fmin_x4:
6393 Node->getValueType(0),
6394 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6395 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6396 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6398 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6400 Node->getValueType(0),
6401 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6402 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6403 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6405 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6407 Node->getValueType(0),
6408 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6409 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6410 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6412 case Intrinsic::aarch64_sve_fminnm_single_x2:
6414 Node->getValueType(0),
6415 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6416 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6417 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6419 case Intrinsic::aarch64_sve_fminnm_single_x4:
6421 Node->getValueType(0),
6422 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6423 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6424 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6426 case Intrinsic::aarch64_sve_fscale_single_x4:
6427 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6429 case Intrinsic::aarch64_sve_fscale_single_x2:
6430 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6432 case Intrinsic::aarch64_sve_fmul_single_x4:
6434 Node->getValueType(0),
6435 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6436 AArch64::FMUL_4ZZ_D}))
6437 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6439 case Intrinsic::aarch64_sve_fmul_single_x2:
6441 Node->getValueType(0),
6442 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6443 AArch64::FMUL_2ZZ_D}))
6444 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6446 case Intrinsic::aarch64_sve_fmaxnm_x2:
6448 Node->getValueType(0),
6449 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6450 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6451 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6453 case Intrinsic::aarch64_sve_fmaxnm_x4:
6455 Node->getValueType(0),
6456 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6457 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6458 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6460 case Intrinsic::aarch64_sve_fminnm_x2:
6462 Node->getValueType(0),
6463 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6464 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6465 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6467 case Intrinsic::aarch64_sve_fminnm_x4:
6469 Node->getValueType(0),
6470 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6471 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6472 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6474 case Intrinsic::aarch64_sve_aese_lane_x2:
6475 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6477 case Intrinsic::aarch64_sve_aesd_lane_x2:
6478 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6480 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6481 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6483 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6484 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6486 case Intrinsic::aarch64_sve_aese_lane_x4:
6487 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6489 case Intrinsic::aarch64_sve_aesd_lane_x4:
6490 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6492 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6493 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6495 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6496 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6498 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6499 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6501 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6505 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6507 for (
unsigned I = 0;
I < 2;
I++)
6509 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6511 CurDAG->RemoveDeadNode(Node);
6514 case Intrinsic::aarch64_sve_fscale_x4:
6515 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6517 case Intrinsic::aarch64_sve_fscale_x2:
6518 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6520 case Intrinsic::aarch64_sve_fmul_x4:
6522 Node->getValueType(0),
6523 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6524 AArch64::FMUL_4Z4Z_D}))
6525 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6527 case Intrinsic::aarch64_sve_fmul_x2:
6529 Node->getValueType(0),
6530 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6531 AArch64::FMUL_2Z2Z_D}))
6532 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6534 case Intrinsic::aarch64_sve_fcvtzs_x2:
6535 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6537 case Intrinsic::aarch64_sve_scvtf_x2:
6538 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6540 case Intrinsic::aarch64_sve_fcvtzu_x2:
6541 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6543 case Intrinsic::aarch64_sve_ucvtf_x2:
6544 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6546 case Intrinsic::aarch64_sve_fcvtzs_x4:
6547 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6549 case Intrinsic::aarch64_sve_scvtf_x4:
6550 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6552 case Intrinsic::aarch64_sve_fcvtzu_x4:
6553 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6555 case Intrinsic::aarch64_sve_ucvtf_x4:
6556 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6558 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6559 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6561 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6562 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6564 case Intrinsic::aarch64_sve_sclamp_single_x2:
6566 Node->getValueType(0),
6567 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6568 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6569 SelectClamp(Node, 2,
Op);
6571 case Intrinsic::aarch64_sve_uclamp_single_x2:
6573 Node->getValueType(0),
6574 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6575 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6576 SelectClamp(Node, 2,
Op);
6578 case Intrinsic::aarch64_sve_fclamp_single_x2:
6580 Node->getValueType(0),
6581 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6582 AArch64::FCLAMP_VG2_2Z2Z_D}))
6583 SelectClamp(Node, 2,
Op);
6585 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6586 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6588 case Intrinsic::aarch64_sve_sclamp_single_x4:
6590 Node->getValueType(0),
6591 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6592 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6593 SelectClamp(Node, 4,
Op);
6595 case Intrinsic::aarch64_sve_uclamp_single_x4:
6597 Node->getValueType(0),
6598 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6599 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6600 SelectClamp(Node, 4,
Op);
6602 case Intrinsic::aarch64_sve_fclamp_single_x4:
6604 Node->getValueType(0),
6605 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6606 AArch64::FCLAMP_VG4_4Z4Z_D}))
6607 SelectClamp(Node, 4,
Op);
6609 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6610 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6612 case Intrinsic::aarch64_sve_add_single_x2:
6614 Node->getValueType(0),
6615 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6616 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6617 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6619 case Intrinsic::aarch64_sve_add_single_x4:
6621 Node->getValueType(0),
6622 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6623 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6624 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6626 case Intrinsic::aarch64_sve_zip_x2:
6628 Node->getValueType(0),
6629 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6630 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6631 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6633 case Intrinsic::aarch64_sve_zipq_x2:
6634 SelectUnaryMultiIntrinsic(Node, 2,
false,
6635 AArch64::ZIP_VG2_2ZZZ_Q);
6637 case Intrinsic::aarch64_sve_zip_x4:
6639 Node->getValueType(0),
6640 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6641 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6642 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6644 case Intrinsic::aarch64_sve_zipq_x4:
6645 SelectUnaryMultiIntrinsic(Node, 4,
true,
6646 AArch64::ZIP_VG4_4Z4Z_Q);
6648 case Intrinsic::aarch64_sve_uzp_x2:
6650 Node->getValueType(0),
6651 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6652 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6653 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6655 case Intrinsic::aarch64_sve_uzpq_x2:
6656 SelectUnaryMultiIntrinsic(Node, 2,
false,
6657 AArch64::UZP_VG2_2ZZZ_Q);
6659 case Intrinsic::aarch64_sve_uzp_x4:
6661 Node->getValueType(0),
6662 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6663 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6664 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6666 case Intrinsic::aarch64_sve_uzpq_x4:
6667 SelectUnaryMultiIntrinsic(Node, 4,
true,
6668 AArch64::UZP_VG4_4Z4Z_Q);
6670 case Intrinsic::aarch64_sve_sel_x2:
6672 Node->getValueType(0),
6673 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6674 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6675 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6677 case Intrinsic::aarch64_sve_sel_x4:
6679 Node->getValueType(0),
6680 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6681 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6682 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6684 case Intrinsic::aarch64_sve_frinta_x2:
6685 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6687 case Intrinsic::aarch64_sve_frinta_x4:
6688 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6690 case Intrinsic::aarch64_sve_frintm_x2:
6691 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6693 case Intrinsic::aarch64_sve_frintm_x4:
6694 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6696 case Intrinsic::aarch64_sve_frintn_x2:
6697 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6699 case Intrinsic::aarch64_sve_frintn_x4:
6700 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6702 case Intrinsic::aarch64_sve_frintp_x2:
6703 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6705 case Intrinsic::aarch64_sve_frintp_x4:
6706 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6708 case Intrinsic::aarch64_sve_sunpk_x2:
6710 Node->getValueType(0),
6711 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6712 AArch64::SUNPK_VG2_2ZZ_D}))
6713 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6715 case Intrinsic::aarch64_sve_uunpk_x2:
6717 Node->getValueType(0),
6718 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6719 AArch64::UUNPK_VG2_2ZZ_D}))
6720 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6722 case Intrinsic::aarch64_sve_sunpk_x4:
6724 Node->getValueType(0),
6725 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6726 AArch64::SUNPK_VG4_4Z2Z_D}))
6727 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6729 case Intrinsic::aarch64_sve_uunpk_x4:
6731 Node->getValueType(0),
6732 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6733 AArch64::UUNPK_VG4_4Z2Z_D}))
6734 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6736 case Intrinsic::aarch64_sve_pext_x2: {
6738 Node->getValueType(0),
6739 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6740 AArch64::PEXT_2PCI_D}))
6741 SelectPExtPair(Node,
Op);
6748 unsigned IntNo =
Node->getConstantOperandVal(1);
6749 if (
Node->getNumOperands() >= 3)
6750 VT =
Node->getOperand(2)->getValueType(0);
6754 case Intrinsic::aarch64_neon_st1x2: {
6755 if (VT == MVT::v8i8) {
6756 SelectStore(Node, 2, AArch64::ST1Twov8b);
6758 }
else if (VT == MVT::v16i8) {
6759 SelectStore(Node, 2, AArch64::ST1Twov16b);
6761 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6762 VT == MVT::v4bf16) {
6763 SelectStore(Node, 2, AArch64::ST1Twov4h);
6765 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6766 VT == MVT::v8bf16) {
6767 SelectStore(Node, 2, AArch64::ST1Twov8h);
6769 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6770 SelectStore(Node, 2, AArch64::ST1Twov2s);
6772 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6773 SelectStore(Node, 2, AArch64::ST1Twov4s);
6775 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6776 SelectStore(Node, 2, AArch64::ST1Twov2d);
6778 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6779 SelectStore(Node, 2, AArch64::ST1Twov1d);
6784 case Intrinsic::aarch64_neon_st1x3: {
6785 if (VT == MVT::v8i8) {
6786 SelectStore(Node, 3, AArch64::ST1Threev8b);
6788 }
else if (VT == MVT::v16i8) {
6789 SelectStore(Node, 3, AArch64::ST1Threev16b);
6791 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6792 VT == MVT::v4bf16) {
6793 SelectStore(Node, 3, AArch64::ST1Threev4h);
6795 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6796 VT == MVT::v8bf16) {
6797 SelectStore(Node, 3, AArch64::ST1Threev8h);
6799 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6800 SelectStore(Node, 3, AArch64::ST1Threev2s);
6802 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6803 SelectStore(Node, 3, AArch64::ST1Threev4s);
6805 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6806 SelectStore(Node, 3, AArch64::ST1Threev2d);
6808 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6809 SelectStore(Node, 3, AArch64::ST1Threev1d);
6814 case Intrinsic::aarch64_neon_st1x4: {
6815 if (VT == MVT::v8i8) {
6816 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6818 }
else if (VT == MVT::v16i8) {
6819 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6821 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6822 VT == MVT::v4bf16) {
6823 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6825 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6826 VT == MVT::v8bf16) {
6827 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6829 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6830 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6832 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6833 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6835 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6836 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6838 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6839 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6844 case Intrinsic::aarch64_neon_st2: {
6845 if (VT == MVT::v8i8) {
6846 SelectStore(Node, 2, AArch64::ST2Twov8b);
6848 }
else if (VT == MVT::v16i8) {
6849 SelectStore(Node, 2, AArch64::ST2Twov16b);
6851 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6852 VT == MVT::v4bf16) {
6853 SelectStore(Node, 2, AArch64::ST2Twov4h);
6855 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6856 VT == MVT::v8bf16) {
6857 SelectStore(Node, 2, AArch64::ST2Twov8h);
6859 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6860 SelectStore(Node, 2, AArch64::ST2Twov2s);
6862 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6863 SelectStore(Node, 2, AArch64::ST2Twov4s);
6865 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6866 SelectStore(Node, 2, AArch64::ST2Twov2d);
6868 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6869 SelectStore(Node, 2, AArch64::ST1Twov1d);
6874 case Intrinsic::aarch64_neon_st3: {
6875 if (VT == MVT::v8i8) {
6876 SelectStore(Node, 3, AArch64::ST3Threev8b);
6878 }
else if (VT == MVT::v16i8) {
6879 SelectStore(Node, 3, AArch64::ST3Threev16b);
6881 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6882 VT == MVT::v4bf16) {
6883 SelectStore(Node, 3, AArch64::ST3Threev4h);
6885 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6886 VT == MVT::v8bf16) {
6887 SelectStore(Node, 3, AArch64::ST3Threev8h);
6889 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6890 SelectStore(Node, 3, AArch64::ST3Threev2s);
6892 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6893 SelectStore(Node, 3, AArch64::ST3Threev4s);
6895 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6896 SelectStore(Node, 3, AArch64::ST3Threev2d);
6898 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6899 SelectStore(Node, 3, AArch64::ST1Threev1d);
6904 case Intrinsic::aarch64_neon_st4: {
6905 if (VT == MVT::v8i8) {
6906 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6908 }
else if (VT == MVT::v16i8) {
6909 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6911 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6912 VT == MVT::v4bf16) {
6913 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6915 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6916 VT == MVT::v8bf16) {
6917 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6919 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6920 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6922 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6923 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6925 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6926 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6928 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6929 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6934 case Intrinsic::aarch64_neon_st2lane: {
6935 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6936 SelectStoreLane(Node, 2, AArch64::ST2i8);
6938 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6939 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6940 SelectStoreLane(Node, 2, AArch64::ST2i16);
6942 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6944 SelectStoreLane(Node, 2, AArch64::ST2i32);
6946 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6948 SelectStoreLane(Node, 2, AArch64::ST2i64);
6953 case Intrinsic::aarch64_neon_st3lane: {
6954 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6955 SelectStoreLane(Node, 3, AArch64::ST3i8);
6957 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6958 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6959 SelectStoreLane(Node, 3, AArch64::ST3i16);
6961 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6963 SelectStoreLane(Node, 3, AArch64::ST3i32);
6965 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6967 SelectStoreLane(Node, 3, AArch64::ST3i64);
6972 case Intrinsic::aarch64_neon_st4lane: {
6973 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6974 SelectStoreLane(Node, 4, AArch64::ST4i8);
6976 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6977 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6978 SelectStoreLane(Node, 4, AArch64::ST4i16);
6980 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6982 SelectStoreLane(Node, 4, AArch64::ST4i32);
6984 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6986 SelectStoreLane(Node, 4, AArch64::ST4i64);
6991 case Intrinsic::aarch64_sve_st2q: {
6992 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6995 case Intrinsic::aarch64_sve_st3q: {
6996 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6999 case Intrinsic::aarch64_sve_st4q: {
7000 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
7003 case Intrinsic::aarch64_sve_st2: {
7004 if (VT == MVT::nxv16i8) {
7005 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
7007 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7008 VT == MVT::nxv8bf16) {
7009 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
7011 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7012 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7014 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7015 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7020 case Intrinsic::aarch64_sve_st3: {
7021 if (VT == MVT::nxv16i8) {
7022 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7024 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7025 VT == MVT::nxv8bf16) {
7026 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7028 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7029 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7031 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7032 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7037 case Intrinsic::aarch64_sve_st4: {
7038 if (VT == MVT::nxv16i8) {
7039 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7041 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7042 VT == MVT::nxv8bf16) {
7043 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7045 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7046 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7048 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7049 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7057 case AArch64ISD::LD2post: {
7058 if (VT == MVT::v8i8) {
7059 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7061 }
else if (VT == MVT::v16i8) {
7062 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7064 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7065 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7067 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7068 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7070 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7071 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7073 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7074 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7076 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7077 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7079 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7080 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7085 case AArch64ISD::LD3post: {
7086 if (VT == MVT::v8i8) {
7087 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7089 }
else if (VT == MVT::v16i8) {
7090 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7092 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7093 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7095 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7096 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7098 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7099 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7101 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7102 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7104 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7105 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7107 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7108 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7113 case AArch64ISD::LD4post: {
7114 if (VT == MVT::v8i8) {
7115 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7117 }
else if (VT == MVT::v16i8) {
7118 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7120 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7121 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7123 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7124 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7126 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7127 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7129 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7130 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7132 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7133 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7135 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7136 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7141 case AArch64ISD::LD1x2post: {
7142 if (VT == MVT::v8i8) {
7143 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7145 }
else if (VT == MVT::v16i8) {
7146 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7148 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7149 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7151 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7152 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7154 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7155 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7157 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7158 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7160 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7161 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7163 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7164 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7169 case AArch64ISD::LD1x3post: {
7170 if (VT == MVT::v8i8) {
7171 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7173 }
else if (VT == MVT::v16i8) {
7174 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7176 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7177 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7179 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7180 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7182 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7183 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7185 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7186 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7188 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7189 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7191 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7192 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7197 case AArch64ISD::LD1x4post: {
7198 if (VT == MVT::v8i8) {
7199 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7201 }
else if (VT == MVT::v16i8) {
7202 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7204 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7205 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7207 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7208 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7210 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7211 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7213 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7214 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7216 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7217 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7219 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7220 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7225 case AArch64ISD::LD1DUPpost: {
7226 if (VT == MVT::v8i8) {
7227 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7229 }
else if (VT == MVT::v16i8) {
7230 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7232 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7233 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7235 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7236 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7238 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7239 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7241 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7242 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7244 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7245 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7247 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7248 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7253 case AArch64ISD::LD2DUPpost: {
7254 if (VT == MVT::v8i8) {
7255 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7257 }
else if (VT == MVT::v16i8) {
7258 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7260 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7261 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7263 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7264 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7266 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7267 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7269 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7270 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7272 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7273 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7275 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7276 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7281 case AArch64ISD::LD3DUPpost: {
7282 if (VT == MVT::v8i8) {
7283 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7285 }
else if (VT == MVT::v16i8) {
7286 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7288 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7289 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7291 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7292 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7294 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7295 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7297 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7298 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7300 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7301 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7303 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7304 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7309 case AArch64ISD::LD4DUPpost: {
7310 if (VT == MVT::v8i8) {
7311 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7313 }
else if (VT == MVT::v16i8) {
7314 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7316 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7317 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7319 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7320 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7322 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7323 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7325 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7326 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7328 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7329 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7331 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7332 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7337 case AArch64ISD::LD1LANEpost: {
7338 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7339 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7341 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7342 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7343 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7345 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7347 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7349 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7351 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7356 case AArch64ISD::LD2LANEpost: {
7357 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7358 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7360 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7361 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7362 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7364 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7366 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7368 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7370 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7375 case AArch64ISD::LD3LANEpost: {
7376 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7377 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7379 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7380 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7381 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7383 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7385 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7387 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7389 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7394 case AArch64ISD::LD4LANEpost: {
7395 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7396 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7398 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7399 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7400 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7402 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7404 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7406 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7408 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7413 case AArch64ISD::ST2post: {
7414 VT =
Node->getOperand(1).getValueType();
7415 if (VT == MVT::v8i8) {
7416 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7418 }
else if (VT == MVT::v16i8) {
7419 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7421 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7422 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7424 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7425 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7427 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7428 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7430 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7431 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7433 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7434 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7436 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7437 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7442 case AArch64ISD::ST3post: {
7443 VT =
Node->getOperand(1).getValueType();
7444 if (VT == MVT::v8i8) {
7445 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7447 }
else if (VT == MVT::v16i8) {
7448 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7450 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7451 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7453 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7454 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7456 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7457 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7459 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7460 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7462 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7463 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7465 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7466 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7471 case AArch64ISD::ST4post: {
7472 VT =
Node->getOperand(1).getValueType();
7473 if (VT == MVT::v8i8) {
7474 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7476 }
else if (VT == MVT::v16i8) {
7477 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7479 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7480 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7482 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7483 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7485 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7486 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7488 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7489 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7491 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7492 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7494 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7495 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7500 case AArch64ISD::ST1x2post: {
7501 VT =
Node->getOperand(1).getValueType();
7502 if (VT == MVT::v8i8) {
7503 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7505 }
else if (VT == MVT::v16i8) {
7506 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7508 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7509 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7511 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7512 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7514 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7515 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7517 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7518 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7520 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7521 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7523 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7524 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7529 case AArch64ISD::ST1x3post: {
7530 VT =
Node->getOperand(1).getValueType();
7531 if (VT == MVT::v8i8) {
7532 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7534 }
else if (VT == MVT::v16i8) {
7535 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7537 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7538 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7540 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7541 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7543 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7544 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7546 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7547 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7549 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7550 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7552 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7553 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7558 case AArch64ISD::ST1x4post: {
7559 VT =
Node->getOperand(1).getValueType();
7560 if (VT == MVT::v8i8) {
7561 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7563 }
else if (VT == MVT::v16i8) {
7564 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7566 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7567 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7569 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7570 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7572 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7573 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7575 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7576 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7578 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7579 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7581 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7582 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7587 case AArch64ISD::ST2LANEpost: {
7588 VT =
Node->getOperand(1).getValueType();
7589 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7590 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7592 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7593 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7594 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7596 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7598 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7600 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7602 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7607 case AArch64ISD::ST3LANEpost: {
7608 VT =
Node->getOperand(1).getValueType();
7609 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7610 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7612 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7613 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7614 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7616 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7618 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7620 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7622 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7627 case AArch64ISD::ST4LANEpost: {
7628 VT =
Node->getOperand(1).getValueType();
7629 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7630 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7632 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7633 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7634 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7636 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7638 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7640 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7642 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7657 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7669 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7673 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7674 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7689 return MemIntr->getMemoryVT();
7696 DataVT = Load->getValueType(0);
7698 DataVT = Load->getValueType(0);
7700 DataVT = Store->getValue().getValueType();
7702 DataVT = Store->getValue().getValueType();
7709 const unsigned Opcode = Root->
getOpcode();
7713 case AArch64ISD::LD1_MERGE_ZERO:
7714 case AArch64ISD::LD1S_MERGE_ZERO:
7715 case AArch64ISD::LDNF1_MERGE_ZERO:
7716 case AArch64ISD::LDNF1S_MERGE_ZERO:
7718 case AArch64ISD::ST1_PRED:
7730 case Intrinsic::aarch64_sme_ldr:
7731 case Intrinsic::aarch64_sme_str:
7732 return MVT::nxv16i8;
7733 case Intrinsic::aarch64_sve_prf:
7738 case Intrinsic::aarch64_sve_ld2_sret:
7739 case Intrinsic::aarch64_sve_ld2q_sret:
7742 case Intrinsic::aarch64_sve_st2q:
7745 case Intrinsic::aarch64_sve_ld3_sret:
7746 case Intrinsic::aarch64_sve_ld3q_sret:
7749 case Intrinsic::aarch64_sve_st3q:
7752 case Intrinsic::aarch64_sve_ld4_sret:
7753 case Intrinsic::aarch64_sve_ld4q_sret:
7756 case Intrinsic::aarch64_sve_st4q:
7759 case Intrinsic::aarch64_sve_ld1udq:
7760 case Intrinsic::aarch64_sve_st1dq:
7761 return EVT(MVT::nxv1i64);
7762 case Intrinsic::aarch64_sve_ld1uwq:
7763 case Intrinsic::aarch64_sve_st1wq:
7764 return EVT(MVT::nxv1i32);
7771template <
int64_t Min,
int64_t Max>
7772bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7776 const DataLayout &
DL = CurDAG->getDataLayout();
7777 const MachineFrameInfo &MFI = MF->getFrameInfo();
7785 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7799 int64_t MulImm = std::numeric_limits<int64_t>::max();
7803 int64_t ByteOffset =
C->getSExtValue();
7804 const auto KnownVScale =
7807 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7810 MulImm = ByteOffset / KnownVScale;
7817 if ((MulImm % MemWidthBytes) != 0)
7820 int64_t
Offset = MulImm / MemWidthBytes;
7824 Base =
N.getOperand(0);
7833 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7839bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7858 int64_t ImmOff =
C->getSExtValue();
7859 unsigned Size = 1 << Scale;
7868 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7870 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7881 if (
C->getZExtValue() == Scale) {
7890bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7891 const AArch64TargetLowering *TLI =
7892 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7897bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7898 return N.getValueType().isScalableVectorOf(MVT::i1);
7901bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7906 int64_t ImmOff =
C->getSExtValue();
7907 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7908 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7913 if (
SDValue C = MatchConstantOffset(
N)) {
7914 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7920 if (CurDAG->isBaseWithConstantOffset(
N)) {
7921 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7922 Base =
N.getOperand(0);
7930 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7934bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7954 uint64_t LowerBound = 0, UpperBound = 64;
7972 if (CN->getAPIntValue().uge(LowerBound) &&
7973 CN->getAPIntValue().ult(UpperBound)) {
7975 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7983template <
bool MatchCBB>
7990 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7992 Reg =
N.getOperand(0);
7994 SDLoc(
N), MVT::i32);
8002 Reg =
N.getOperand(0);
8022SDValue AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode &
N) {
8023 EVT VT =
N.getValueType(0);
8034 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8043 unsigned CondCode = CC->getZExtValue();
8046 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8048 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8049 else if (VT == MVT::f32)
8050 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8051 else if (VT == MVT::f64)
8052 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8060 if (TVal == CmpLHS && FVal == CmpRHS)
8062 else if (TVal == CmpRHS && FVal == CmpLHS)
8067 if (TVal == CmpLHS && FVal == CmpRHS)
8069 else if (TVal == CmpRHS && FVal == CmpLHS)
8078 unsigned Opc = getOpc(VT, isMax);
8084 if (!CFP || CFP->getValueAPF().isNaN())
8089 if (CFP->isZero() && !
N.getFlags().hasNoSignedZeros())
8095 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8101 return SDValue(CurDAG->getMachineNode(
Opc,
DL, VT, CmpLHS, CmpRHS), 0);
8104void AArch64DAGToDAGISel::PreprocessISelDAG() {
8105 bool MadeChange =
false;
8111 switch (
N.getOpcode()) {
8113 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8114 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8115 ScalarTy ==
N.getOperand(0).getValueType())
8120 case AArch64ISD::CSEL:
8121 Result = tryFoldCselToFMaxMin(
N);
8128 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8134 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8140 CurDAG->RemoveDeadNodes();
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static std::optional< APInt > GetNEONSplatValue(SDValue N)
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static SDValue addBitcastHints(SelectionDAG &DAG, SDNode &N)
addBitcastHints - This method adds bitcast hints to the operands of a node to help instruction select...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static std::optional< APInt > DecodeNEONSplat(SDValue N)
static bool checkCVTFixedPointOperandWithFBitsForVectors(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static 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
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static const fltSemantics & IEEEhalf()
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
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.
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 uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
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.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ 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.
bool isScalableVectorOf(EVT EltVT) const
Return true if this is a scalable vector with matching element type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.