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));
1962 CurDAG->RemoveDeadNode(
N);
1968std::tuple<unsigned, SDValue, SDValue>
1969AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1975 SDValue NewOffset = OldOffset;
1977 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1978 N, OldBase, NewBase, NewOffset);
1982 const bool IsRegReg =
1983 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1986 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1999template <SelectTypeKind Kind>
2011 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2016 if (EltVT != MVT::i1)
2020 if (EltVT == MVT::bf16)
2022 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2052void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2055 if (
Imm->getZExtValue() > 1)
2059 EVT VT =
N->getValueType(0);
2061 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2064 for (
unsigned I = 0;
I < 2; ++
I)
2065 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2066 AArch64::psub0 +
I,
DL, VT, SuperReg));
2068 CurDAG->RemoveDeadNode(
N);
2071void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2073 EVT VT =
N->getValueType(0);
2077 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2080 for (
unsigned I = 0;
I < 2; ++
I)
2081 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2082 AArch64::psub0 +
I,
DL, VT, SuperReg));
2084 CurDAG->RemoveDeadNode(
N);
2087void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2089 EVT VT =
N->getValueType(0);
2093 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2095 for (
unsigned i = 0; i < NumVecs; ++i)
2096 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2097 AArch64::zsub0 + i,
DL, VT, SuperReg));
2099 CurDAG->RemoveDeadNode(
N);
2102void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2105 EVT VT =
N->getValueType(0);
2107 Ops.push_back(
N->getOperand(0));
2110 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2113 for (
unsigned i = 0; i < NumVecs; ++i)
2114 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2115 AArch64::zsub0 + i,
DL, VT, SuperReg));
2118 unsigned ChainIdx = NumVecs;
2120 CurDAG->RemoveDeadNode(
N);
2123void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2128 assert(Opcode != 0 &&
"Unexpected opcode");
2131 EVT VT =
N->getValueType(0);
2132 SDUse *OpsIter =
N->op_begin() + 1;
2135 auto GetMultiVecOperand = [&]() {
2138 return createZMulTuple(Regs);
2142 Ops.push_back(*OpsIter++);
2144 Ops.push_back(GetMultiVecOperand());
2146 Ops.push_back(GetMultiVecOperand());
2148 Ops.push_back(*OpsIter++);
2151 Ops.append(OpsIter,
N->op_end());
2153 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2155 for (
unsigned i = 0; i < NumVecs; ++i)
2156 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2157 AArch64::zsub0 + i,
DL, VT, SuperReg));
2159 CurDAG->RemoveDeadNode(
N);
2162void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2163 unsigned Scale,
unsigned Opc_ri,
2164 unsigned Opc_rr,
bool IsIntr) {
2165 assert(Scale < 5 &&
"Invalid scaling value.");
2167 EVT VT =
N->getValueType(0);
2174 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2175 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2181 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2183 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2185 for (
unsigned i = 0; i < NumVecs; ++i)
2186 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2187 AArch64::zsub0 + i,
DL, VT, SuperReg));
2190 unsigned ChainIdx = NumVecs;
2192 CurDAG->RemoveDeadNode(
N);
2195void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2200 assert(Scale < 4 &&
"Invalid scaling value.");
2202 EVT VT =
N->getValueType(0);
2210 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2216 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2218 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2220 for (
unsigned i = 0; i < NumVecs; ++i)
2221 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2222 AArch64::zsub0 + i,
DL, VT, SuperReg));
2225 unsigned ChainIdx = NumVecs;
2227 CurDAG->RemoveDeadNode(
N);
2230void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2232 if (
N->getValueType(0) != MVT::nxv4f32)
2234 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2237void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2238 unsigned NumOutVecs,
2242 if (
Imm->getZExtValue() > MaxImm)
2246 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2252 EVT VT =
Node->getValueType(0);
2255 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2258 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2259 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2260 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2263 unsigned ChainIdx = NumOutVecs;
2265 CurDAG->RemoveDeadNode(Node);
2268void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2269 unsigned NumOutVecs,
2272 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2277 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2281 EVT VT =
Node->getValueType(0);
2284 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2287 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2288 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2289 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2292 unsigned ChainIdx = NumOutVecs;
2294 CurDAG->RemoveDeadNode(Node);
2297void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2300 EVT VT =
N->getValueType(0);
2303 SDValue Zd = createZMulTuple(Regs);
2304 SDValue Zn =
N->getOperand(1 + NumVecs);
2305 SDValue Zm =
N->getOperand(2 + NumVecs);
2311 for (
unsigned i = 0; i < NumVecs; ++i)
2312 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2313 AArch64::zsub0 + i,
DL, VT, SuperReg));
2315 CurDAG->RemoveDeadNode(
N);
2345template <
unsigned MaxIdx,
unsigned Scale>
2346void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2347 unsigned BaseReg,
unsigned Op) {
2348 unsigned TileNum = 0;
2349 if (BaseReg != AArch64::ZA)
2350 TileNum =
N->getConstantOperandVal(2);
2356 if (BaseReg == AArch64::ZA)
2361 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2365 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2367 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2369 EVT VT =
N->getValueType(0);
2370 for (
unsigned I = 0;
I < NumVecs; ++
I)
2372 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2375 unsigned ChainIdx = NumVecs;
2377 CurDAG->RemoveDeadNode(
N);
2380void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2381 unsigned Op,
unsigned MaxIdx,
2382 unsigned Scale,
unsigned BaseReg) {
2387 if (BaseReg != AArch64::ZA)
2391 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2398 if (BaseReg != AArch64::ZA )
2399 Ops.push_back(
N->getOperand(2));
2402 Ops.push_back(
N->getOperand(0));
2403 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2405 EVT VT =
N->getValueType(0);
2406 for (
unsigned I = 0;
I < NumVecs; ++
I)
2408 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2412 unsigned ChainIdx = NumVecs;
2414 CurDAG->RemoveDeadNode(
N);
2417void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2418 unsigned NumOutVecs,
2422 EVT VT =
N->getValueType(0);
2423 unsigned NumInVecs =
N->getNumOperands() - 1;
2427 assert((NumInVecs == 2 || NumInVecs == 4) &&
2428 "Don't know how to handle multi-register input!");
2430 Ops.push_back(createZMulTuple(Regs));
2433 for (
unsigned I = 0;
I < NumInVecs;
I++)
2434 Ops.push_back(
N->getOperand(1 +
I));
2437 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2440 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2441 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2442 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2443 CurDAG->RemoveDeadNode(
N);
2446void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2449 EVT VT =
N->getOperand(2)->getValueType(0);
2457 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2466void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2467 unsigned Scale,
unsigned Opc_rr,
2473 SDValue RegSeq = createZTuple(Regs);
2479 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2480 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2486 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2494 const DataLayout &
DL = CurDAG->getDataLayout();
2495 const TargetLowering *TLI = getTargetLowering();
2499 int FI = FINode->getIndex();
2501 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2508void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2511 EVT VT =
N->getOperand(2)->getValueType(0);
2512 const EVT ResTys[] = {MVT::i64,
2524 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2564void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2567 EVT VT =
N->getValueType(0);
2579 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2581 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2583 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2585 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2589 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2590 AArch64::qsub2, AArch64::qsub3 };
2591 for (
unsigned i = 0; i < NumVecs; ++i) {
2592 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2599 CurDAG->RemoveDeadNode(
N);
2602void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2605 EVT VT =
N->getValueType(0);
2617 const EVT ResTys[] = {MVT::i64,
2620 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2623 CurDAG->getTargetConstant(LaneNo, dl,
2628 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2640 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2641 AArch64::qsub2, AArch64::qsub3 };
2642 for (
unsigned i = 0; i < NumVecs; ++i) {
2643 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2653 CurDAG->RemoveDeadNode(
N);
2656void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2659 EVT VT =
N->getOperand(2)->getValueType(0);
2671 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2673 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2675 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2684void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2687 EVT VT =
N->getOperand(2)->getValueType(0);
2699 const EVT ResTys[] = {MVT::i64,
2702 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2704 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2708 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2719 unsigned &LSB,
unsigned &MSB,
2720 unsigned NumberOfIgnoredLowBits,
2721 bool BiggerPattern) {
2723 "N must be a AND operation to call this function");
2725 EVT VT =
N->getValueType(0);
2730 assert((VT == MVT::i32 || VT == MVT::i64) &&
2731 "Type checking must have been done before calling this function");
2745 const SDNode *Op0 =
N->getOperand(0).getNode();
2752 if (AndImm & (AndImm + 1))
2755 bool ClampMSB =
false;
2775 ClampMSB = (VT == MVT::i32);
2776 }
else if (BiggerPattern) {
2782 Opd0 =
N->getOperand(0);
2788 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2791 <<
": Found large shift immediate, this should not happen\n"));
2805 MSB = MSB > 31 ? 31 : MSB;
2807 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2812 SDValue &Opd0,
unsigned &Immr,
2816 EVT VT =
N->getValueType(0);
2818 assert((VT == MVT::i32 || VT == MVT::i64) &&
2819 "Type checking must have been done before calling this function");
2823 Op =
Op->getOperand(0);
2824 VT =
Op->getValueType(0);
2833 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2837 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2838 Opd0 =
Op.getOperand(0);
2840 Imms = ShiftImm + Width - 1;
2868 Opd0 =
N->getOperand(0).getOperand(0);
2878 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2885 unsigned &Immr,
unsigned &Imms,
2886 bool BiggerPattern) {
2888 "N must be a SHR/SRA operation to call this function");
2890 EVT VT =
N->getValueType(0);
2895 assert((VT == MVT::i32 || VT == MVT::i64) &&
2896 "Type checking must have been done before calling this function");
2906 Opd0 =
N->getOperand(0).getOperand(0);
2907 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2913 Opd0 =
N->getOperand(0).getOperand(0);
2916 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2917 }
else if (BiggerPattern) {
2921 Opd0 =
N->getOperand(0);
2930 <<
": Found large shift immediate, this should not happen\n"));
2939 "bad amount in shift node!");
2940 int immr = SrlImm - ShlImm;
2945 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2947 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2951bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2954 EVT VT =
N->getValueType(0);
2955 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2956 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2967 unsigned Immr = ShiftImm;
2969 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2970 CurDAG->getTargetConstant(Imms, dl, VT)};
2971 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2976 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2977 unsigned NumberOfIgnoredLowBits = 0,
2978 bool BiggerPattern =
false) {
2979 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2982 switch (
N->getOpcode()) {
2984 if (!
N->isMachineOpcode())
2989 NumberOfIgnoredLowBits, BiggerPattern);
2998 unsigned NOpc =
N->getMachineOpcode();
3002 case AArch64::SBFMWri:
3003 case AArch64::UBFMWri:
3004 case AArch64::SBFMXri:
3005 case AArch64::UBFMXri:
3007 Opd0 =
N->getOperand(0);
3008 Immr =
N->getConstantOperandVal(1);
3009 Imms =
N->getConstantOperandVal(2);
3016bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3017 unsigned Opc, Immr, Imms;
3022 EVT VT =
N->getValueType(0);
3027 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3028 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3029 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3031 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3032 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3038 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3039 CurDAG->getTargetConstant(Imms, dl, VT)};
3040 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3049 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3050 assert((VT == MVT::i32 || VT == MVT::i64) &&
3051 "i32 or i64 mask type expected!");
3055 APInt SignificantDstMask =
3059 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3060 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3093 APInt OpUsefulBits(UsefulBits);
3097 OpUsefulBits <<= MSB - Imm + 1;
3102 OpUsefulBits <<= Imm;
3104 OpUsefulBits <<= MSB + 1;
3107 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3113 UsefulBits &= OpUsefulBits;
3130 APInt Mask(UsefulBits);
3131 Mask.clearAllBits();
3139 Mask.lshrInPlace(ShiftAmt);
3145 Mask.lshrInPlace(ShiftAmt);
3161 APInt OpUsefulBits(UsefulBits);
3175 OpUsefulBits <<= Width;
3178 if (
Op.getOperand(1) == Orig) {
3180 Mask = ResultUsefulBits & OpUsefulBits;
3184 if (
Op.getOperand(0) == Orig)
3186 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3192 OpUsefulBits <<= Width;
3194 OpUsefulBits <<= LSB;
3196 if (
Op.getOperand(1) == Orig) {
3198 Mask = ResultUsefulBits & OpUsefulBits;
3199 Mask.lshrInPlace(LSB);
3202 if (
Op.getOperand(0) == Orig)
3203 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3220 case AArch64::ANDSWri:
3221 case AArch64::ANDSXri:
3222 case AArch64::ANDWri:
3223 case AArch64::ANDXri:
3227 case AArch64::UBFMWri:
3228 case AArch64::UBFMXri:
3231 case AArch64::ORRWrs:
3232 case AArch64::ORRXrs:
3237 case AArch64::BFMWri:
3238 case AArch64::BFMXri:
3241 case AArch64::STRBBui:
3242 case AArch64::STURBBi:
3248 case AArch64::STRHHui:
3249 case AArch64::STURHHi:
3262 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3264 UsefulBits =
APInt(Bitwidth, 0);
3273 UsersUsefulBits |= UsefulBitsForUse;
3278 UsefulBits &= UsersUsefulBits;
3288 EVT VT =
Op.getValueType();
3291 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3294 if (ShlAmount > 0) {
3297 UBFMOpc, dl, VT,
Op,
3302 assert(ShlAmount < 0 &&
"expected right shift");
3303 int ShrAmount = -ShlAmount;
3315 const uint64_t NonZeroBits,
3322 const uint64_t NonZeroBits,
3329 bool BiggerPattern,
SDValue &Src,
3330 int &DstLSB,
int &Width) {
3331 EVT VT =
Op.getValueType();
3340 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3344 switch (
Op.getOpcode()) {
3349 NonZeroBits, Src, DstLSB, Width);
3352 NonZeroBits, Src, DstLSB, Width);
3365 EVT VT =
Op.getValueType();
3366 assert((VT == MVT::i32 || VT == MVT::i64) &&
3367 "Caller guarantees VT is one of i32 or i64");
3380 assert((~AndImm & NonZeroBits) == 0 &&
3381 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3410 if (!BiggerPattern && !AndOp0.
hasOneUse())
3429 <<
"Found large Width in bit-field-positioning -- this indicates no "
3430 "proper combining / constant folding was performed\n");
3439 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3454 "Op.getNode() should be a SHL node to call this function");
3456 "Op.getNode() should shift ShlImm to call this function");
3463 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3487 EVT VT =
Op.getValueType();
3488 assert((VT == MVT::i32 || VT == MVT::i64) &&
3489 "Caller guarantees that type is i32 or i64");
3496 if (!BiggerPattern && !
Op.hasOneUse())
3505 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3513 assert(VT == MVT::i32 || VT == MVT::i64);
3524 EVT VT =
N->getValueType(0);
3525 if (VT != MVT::i32 && VT != MVT::i64)
3543 if (!
And.hasOneUse() ||
3553 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3560 if ((OrImm & NotKnownZero) != 0) {
3572 unsigned ImmS = Width - 1;
3578 bool IsBFI = LSB != 0;
3583 unsigned OrChunks = 0, BFIChunks = 0;
3584 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3585 if (((OrImm >> Shift) & 0xFFFF) != 0)
3587 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3590 if (BFIChunks > OrChunks)
3596 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3604 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3613 if (!Dst.hasOneUse())
3616 EVT VT = Dst.getValueType();
3617 assert((VT == MVT::i32 || VT == MVT::i64) &&
3618 "Caller should guarantee that VT is one of i32 or i64");
3646 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3647 unsigned MaskWidth =
3650 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3656 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3657 ShiftedOperand =
SDValue(UBFMNode, 0);
3686 const bool BiggerPattern) {
3687 EVT VT =
N->getValueType(0);
3688 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3689 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3690 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3691 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3692 assert((VT == MVT::i32 || VT == MVT::i64) &&
3693 "Expect result type to be i32 or i64 since N is combinable to BFM");
3700 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3703 if (BiggerPattern) {
3726 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3788 EVT VT =
N->getValueType(0);
3789 if (VT != MVT::i32 && VT != MVT::i64)
3797 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3798 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3818 for (
int I = 0;
I < 4; ++
I) {
3821 unsigned ImmR, ImmS;
3822 bool BiggerPattern =
I / 2;
3823 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3825 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3831 NumberOfIgnoredLowBits, BiggerPattern)) {
3834 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3835 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3840 Width = ImmS - ImmR + 1;
3851 Src, DstLSB, Width)) {
3859 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3869 APInt BitsToBeInserted =
3872 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3896 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3929 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3931 if (Src->hasOneUse() &&
3934 Src = Src->getOperand(0);
3944 unsigned ImmS = Width - 1;
3950 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3958bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3967 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3980bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3984 EVT VT =
N->getValueType(0);
3985 if (VT != MVT::i32 && VT != MVT::i64)
3991 Op0, DstLSB, Width))
3997 unsigned ImmS = Width - 1;
4000 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4001 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4002 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4003 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4009bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4010 EVT VT =
N->getValueType(0);
4013 switch (
N->getOpcode()) {
4015 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4018 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4021 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4024 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4032 if (VT == MVT::i32) {
4035 }
else if (VT == MVT::i64) {
4041 SDValue ShiftAmt =
N->getOperand(1);
4061 (Add0Imm %
Size == 0)) {
4067 if (SubVT == MVT::i32) {
4068 NegOpc = AArch64::SUBWrr;
4069 ZeroReg = AArch64::WZR;
4071 assert(SubVT == MVT::i64);
4072 NegOpc = AArch64::SUBXrr;
4073 ZeroReg = AArch64::XZR;
4076 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4077 MachineSDNode *Neg =
4078 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4079 NewShiftAmt =
SDValue(Neg, 0);
4087 if (SubVT == MVT::i32) {
4088 NotOpc = AArch64::ORNWrr;
4089 ZeroReg = AArch64::WZR;
4091 assert(SubVT == MVT::i64);
4092 NotOpc = AArch64::ORNXrr;
4093 ZeroReg = AArch64::XZR;
4096 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4097 MachineSDNode *
Not =
4098 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4099 NewShiftAmt =
SDValue(Not, 0);
4120 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4121 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4122 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4123 NewShiftAmt, SubReg);
4124 NewShiftAmt =
SDValue(Ext, 0);
4128 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4135 bool isReciprocal) {
4138 FVal = CN->getValueAPF();
4141 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4151 if (
unsigned FBits =
4164 bool isReciprocal) {
4165 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4166 N.getValueType().getScalarSizeInBits() ==
4167 N.getOperand(0).getValueType().getScalarSizeInBits())
4168 N =
N.getOperand(0);
4170 auto ImmToFloat = [RegWidth](
APInt Imm) {
4184 switch (
N->getOpcode()) {
4185 case AArch64ISD::MOVIshift:
4186 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4187 <<
N.getConstantOperandVal(1)));
4189 case AArch64ISD::FMOV:
4190 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4192 case AArch64ISD::DUP:
4194 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4202 if (
unsigned FBits =
4211bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4212 unsigned RegWidth) {
4217bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4218 unsigned RegWidth) {
4220 CurDAG,
N, FixedPos, RegWidth,
false);
4223bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(
SDValue N,
4225 unsigned RegWidth) {
4227 CurDAG,
N, FixedPos, RegWidth,
true);
4230bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4232 unsigned RegWidth) {
4242 RegString.
split(Fields,
':');
4244 if (Fields.
size() == 1)
4248 &&
"Invalid number of fields in read register string");
4251 bool AllIntFields =
true;
4255 AllIntFields &= !
Field.getAsInteger(10, IntField);
4256 Ops.push_back(IntField);
4260 "Unexpected non-integer value in special register string.");
4265 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4266 (
Ops[3] << 3) | (
Ops[4]);
4273bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4275 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4278 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4280 unsigned Opcode64Bit = AArch64::MRS;
4285 const auto *TheReg =
4286 AArch64SysReg::lookupSysRegByName(RegString->getString());
4287 if (TheReg && TheReg->Readable &&
4288 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4289 Imm = TheReg->Encoding;
4295 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4296 Opcode64Bit = AArch64::ADR;
4304 SDValue InChain =
N->getOperand(0);
4305 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4306 if (!ReadIs128Bit) {
4307 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4308 {SysRegImm, InChain});
4310 SDNode *MRRS = CurDAG->getMachineNode(
4312 {MVT::Untyped , MVT::Other },
4313 {SysRegImm, InChain});
4317 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4319 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4325 ReplaceUses(
SDValue(
N, 2), OutChain);
4334bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4336 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4339 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4341 if (!WriteIs128Bit) {
4347 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4350 "Expected a constant integer expression.");
4351 unsigned Reg = PMapper->Encoding;
4352 uint64_t Immed =
N->getConstantOperandVal(2);
4353 CurDAG->SelectNodeTo(
4354 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4355 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4361 if (trySelectPState(
4362 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4363 AArch64::MSRpstateImm4))
4365 if (trySelectPState(
4366 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4367 AArch64::MSRpstateImm1))
4376 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4377 if (TheReg && TheReg->Writeable &&
4378 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4379 Imm = TheReg->Encoding;
4388 if (!WriteIs128Bit) {
4389 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4390 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4391 N->getOperand(2), InChain);
4395 SDNode *Pair = CurDAG->getMachineNode(
4396 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4397 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4400 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4402 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4404 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4405 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4413bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4418 if (Subtarget->hasLSE())
return false;
4420 if (MemTy == MVT::i8)
4421 Opcode = AArch64::CMP_SWAP_8;
4422 else if (MemTy == MVT::i16)
4423 Opcode = AArch64::CMP_SWAP_16;
4424 else if (MemTy == MVT::i32)
4425 Opcode = AArch64::CMP_SWAP_32;
4426 else if (MemTy == MVT::i64)
4427 Opcode = AArch64::CMP_SWAP_64;
4431 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4432 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4434 SDNode *CmpSwap = CurDAG->getMachineNode(
4436 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4443 CurDAG->RemoveDeadNode(
N);
4448bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4449 SDValue &Shift,
bool Negate) {
4456 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4459bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4468 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4475 if ((Val & ~0xff) == 0) {
4476 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4481 if ((Val & ~0xff00) == 0) {
4482 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4494bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4518 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4519 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4526 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4527 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4531 if (Val <= 65280 && Val % 256 == 0) {
4532 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4533 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4544bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4554 int32_t ImmVal, ShiftVal;
4559 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4560 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4564bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4566 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4570bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4573 if (ImmVal >= -128 && ImmVal < 128) {
4574 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4580bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4582 uint64_t ImmVal = CNode->getZExtValue();
4592 ImmVal &= 0xFFFFFFFF;
4601 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4608bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4612 ImmVal = CI->getZExtValue();
4614 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4625 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4634bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4635 uint64_t
High,
bool AllowSaturation,
4638 uint64_t ImmVal = CN->getZExtValue();
4645 if (ImmVal >
High) {
4646 if (!AllowSaturation)
4651 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4658bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4672 const TargetLowering *TLI = getTargetLowering();
4675 SDValue FiOp = CurDAG->getTargetFrameIndex(
4677 int TagOffset =
N->getConstantOperandVal(3);
4679 SDNode *Out = CurDAG->getMachineNode(
4680 AArch64::TAGPstack,
DL, MVT::i64,
4681 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4682 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4683 ReplaceNode(
N, Out);
4687void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4689 "llvm.aarch64.tagp third argument must be an immediate");
4690 if (trySelectStackSlotTagP(
N))
4697 int TagOffset =
N->getConstantOperandVal(3);
4698 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4699 {
N->getOperand(1),
N->getOperand(2)});
4700 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4701 {
SDValue(N1, 0),
N->getOperand(2)});
4702 SDNode *N3 = CurDAG->getMachineNode(
4703 AArch64::ADDG,
DL, MVT::i64,
4704 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4705 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4709bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4713 if (
N->getConstantOperandVal(2) != 0)
4715 if (!
N->getOperand(0).isUndef())
4719 EVT VT =
N->getValueType(0);
4720 EVT InVT =
N->getOperand(1).getValueType();
4731 "Expected to insert into a packed scalable vector!");
4734 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4735 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4736 N->getOperand(1), RC));
4740bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4744 if (
N->getConstantOperandVal(1) != 0)
4748 EVT VT =
N->getValueType(0);
4749 EVT InVT =
N->getOperand(0).getValueType();
4760 "Expected to extract from a packed scalable vector!");
4763 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4764 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4765 N->getOperand(0), RC));
4769bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4775 EVT VT =
N->getValueType(0);
4788 (Subtarget->hasSVE2() ||
4789 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4790 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4793 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4797 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4798 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4799 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4806 bool IsXOROperand =
true;
4808 IsXOROperand =
false;
4814 APInt ShlAmt, ShrAmt;
4822 if (!IsXOROperand) {
4824 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4827 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4828 SDNode *SubRegToReg =
4829 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4840 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4841 AArch64::XAR_ZZZI_D})) {
4842 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4867 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4877 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4885 bool IsXOROperand =
true;
4887 IsXOROperand =
false;
4890 R1 =
XOR.getOperand(0);
4891 R2 =
XOR.getOperand(1);
4901 if (ShAmt + HsAmt != VTSizeInBits)
4904 if (!IsXOROperand) {
4907 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4916 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4922 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4923 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4925 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4928 if (
R2.getValueType() == VT)
4929 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4934 SDValue SubReg = CurDAG->getTargetConstant(
4937 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4942 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4948 SDNode *XAR =
nullptr;
4952 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4953 AArch64::XAR_ZZZI_D}))
4954 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4956 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4959 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4965 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4966 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4969 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4970 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4973 SDValue SubReg = CurDAG->getTargetConstant(
4976 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4980 ReplaceNode(
N, XAR);
4984void AArch64DAGToDAGISel::Select(SDNode *Node) {
4986 if (
Node->isMachineOpcode()) {
4988 Node->setNodeId(-1);
4993 EVT VT =
Node->getValueType(0);
4995 switch (
Node->getOpcode()) {
5000 if (SelectCMP_SWAP(Node))
5005 case AArch64ISD::MRRS:
5006 if (tryReadRegister(Node))
5011 case AArch64ISD::MSRR:
5012 if (tryWriteRegister(Node))
5019 if (tryIndexedLoad(Node))
5028 if (tryBitfieldExtractOp(Node))
5030 if (tryBitfieldInsertInZeroOp(Node))
5035 if (tryShiftAmountMod(Node))
5040 if (tryBitfieldExtractOpFromSExt(Node))
5045 if (tryBitfieldInsertOp(Node))
5047 if (trySelectXAR(Node))
5052 if (trySelectCastScalableToFixedLengthVector(Node))
5058 if (trySelectCastFixedLengthToScalableVector(Node))
5067 if (ConstNode->
isZero()) {
5068 if (VT == MVT::i32) {
5070 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5071 ReplaceNode(Node,
New.getNode());
5073 }
else if (VT == MVT::i64) {
5075 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5076 ReplaceNode(Node,
New.getNode());
5087 const TargetLowering *TLI = getTargetLowering();
5088 SDValue TFI = CurDAG->getTargetFrameIndex(
5091 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5092 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5093 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5097 unsigned IntNo =
Node->getConstantOperandVal(1);
5101 case Intrinsic::aarch64_gcsss: {
5105 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5107 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5108 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5109 MVT::Other, Zero,
SDValue(SS1, 0));
5110 ReplaceNode(Node, SS2);
5113 case Intrinsic::aarch64_ldaxp:
5114 case Intrinsic::aarch64_ldxp: {
5116 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5121 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5122 MVT::Other, MemAddr, Chain);
5125 MachineMemOperand *MemOp =
5128 ReplaceNode(Node, Ld);
5131 case Intrinsic::aarch64_stlxp:
5132 case Intrinsic::aarch64_stxp: {
5134 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5142 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5144 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5146 MachineMemOperand *MemOp =
5150 ReplaceNode(Node, St);
5153 case Intrinsic::aarch64_neon_ld1x2:
5154 if (VT == MVT::v8i8) {
5155 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5157 }
else if (VT == MVT::v16i8) {
5158 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5160 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5161 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5163 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5164 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5166 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5167 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5169 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5170 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5172 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5173 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5175 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5176 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5180 case Intrinsic::aarch64_neon_ld1x3:
5181 if (VT == MVT::v8i8) {
5182 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5184 }
else if (VT == MVT::v16i8) {
5185 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5187 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5188 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5190 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5191 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5193 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5194 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5196 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5197 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5199 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5200 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5202 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5203 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5207 case Intrinsic::aarch64_neon_ld1x4:
5208 if (VT == MVT::v8i8) {
5209 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5211 }
else if (VT == MVT::v16i8) {
5212 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5214 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5215 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5217 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5218 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5220 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5221 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5223 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5224 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5226 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5227 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5229 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5230 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5234 case Intrinsic::aarch64_neon_ld2:
5235 if (VT == MVT::v8i8) {
5236 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5238 }
else if (VT == MVT::v16i8) {
5239 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5241 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5242 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5244 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5245 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5247 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5248 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5250 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5251 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5253 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5254 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5256 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5257 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5261 case Intrinsic::aarch64_neon_ld3:
5262 if (VT == MVT::v8i8) {
5263 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5265 }
else if (VT == MVT::v16i8) {
5266 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5268 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5269 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5271 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5272 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5274 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5275 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5277 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5278 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5280 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5281 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5283 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5284 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5288 case Intrinsic::aarch64_neon_ld4:
5289 if (VT == MVT::v8i8) {
5290 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5292 }
else if (VT == MVT::v16i8) {
5293 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5295 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5296 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5298 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5299 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5301 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5302 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5304 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5305 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5307 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5308 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5310 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5311 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5315 case Intrinsic::aarch64_neon_ld2r:
5316 if (VT == MVT::v8i8) {
5317 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5319 }
else if (VT == MVT::v16i8) {
5320 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5322 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5323 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5325 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5326 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5328 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5329 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5331 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5332 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5334 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5335 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5337 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5338 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5342 case Intrinsic::aarch64_neon_ld3r:
5343 if (VT == MVT::v8i8) {
5344 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5346 }
else if (VT == MVT::v16i8) {
5347 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5349 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5350 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5352 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5353 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5355 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5356 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5358 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5359 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5361 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5362 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5364 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5365 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5369 case Intrinsic::aarch64_neon_ld4r:
5370 if (VT == MVT::v8i8) {
5371 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5373 }
else if (VT == MVT::v16i8) {
5374 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5376 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5377 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5379 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5380 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5382 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5383 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5385 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5386 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5388 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5389 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5391 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5392 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5396 case Intrinsic::aarch64_neon_ld2lane:
5397 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5398 SelectLoadLane(Node, 2, AArch64::LD2i8);
5400 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5401 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5402 SelectLoadLane(Node, 2, AArch64::LD2i16);
5404 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5406 SelectLoadLane(Node, 2, AArch64::LD2i32);
5408 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5410 SelectLoadLane(Node, 2, AArch64::LD2i64);
5414 case Intrinsic::aarch64_neon_ld3lane:
5415 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5416 SelectLoadLane(Node, 3, AArch64::LD3i8);
5418 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5419 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5420 SelectLoadLane(Node, 3, AArch64::LD3i16);
5422 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5424 SelectLoadLane(Node, 3, AArch64::LD3i32);
5426 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5428 SelectLoadLane(Node, 3, AArch64::LD3i64);
5432 case Intrinsic::aarch64_neon_ld4lane:
5433 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5434 SelectLoadLane(Node, 4, AArch64::LD4i8);
5436 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5437 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5438 SelectLoadLane(Node, 4, AArch64::LD4i16);
5440 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5442 SelectLoadLane(Node, 4, AArch64::LD4i32);
5444 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5446 SelectLoadLane(Node, 4, AArch64::LD4i64);
5450 case Intrinsic::aarch64_ld64b:
5451 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5453 case Intrinsic::aarch64_sve_ld2q_sret: {
5454 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5457 case Intrinsic::aarch64_sve_ld3q_sret: {
5458 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5461 case Intrinsic::aarch64_sve_ld4q_sret: {
5462 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5465 case Intrinsic::aarch64_sve_ld2_sret: {
5466 if (VT == MVT::nxv16i8) {
5467 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5470 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5471 VT == MVT::nxv8bf16) {
5472 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5475 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5476 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5479 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5480 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5486 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5487 if (VT == MVT::nxv16i8) {
5488 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5489 SelectContiguousMultiVectorLoad(
5490 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5491 else if (Subtarget->hasSVE2p1())
5492 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5497 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5498 VT == MVT::nxv8bf16) {
5499 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5500 SelectContiguousMultiVectorLoad(
5501 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5502 else if (Subtarget->hasSVE2p1())
5503 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5508 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5509 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5510 SelectContiguousMultiVectorLoad(
5511 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5512 else if (Subtarget->hasSVE2p1())
5513 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5518 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5519 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5520 SelectContiguousMultiVectorLoad(
5521 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5522 else if (Subtarget->hasSVE2p1())
5523 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5531 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5532 if (VT == MVT::nxv16i8) {
5533 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5534 SelectContiguousMultiVectorLoad(
5535 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5536 else if (Subtarget->hasSVE2p1())
5537 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5542 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5543 VT == MVT::nxv8bf16) {
5544 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5545 SelectContiguousMultiVectorLoad(
5546 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5547 else if (Subtarget->hasSVE2p1())
5548 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5553 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5554 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5555 SelectContiguousMultiVectorLoad(
5556 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5557 else if (Subtarget->hasSVE2p1())
5558 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5563 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5564 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5565 SelectContiguousMultiVectorLoad(
5566 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5567 else if (Subtarget->hasSVE2p1())
5568 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5576 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5577 if (VT == MVT::nxv16i8) {
5578 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5579 SelectContiguousMultiVectorLoad(Node, 2, 0,
5580 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5581 AArch64::LDNT1B_2Z_PSEUDO);
5582 else if (Subtarget->hasSVE2p1())
5583 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5584 AArch64::LDNT1B_2Z);
5588 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5589 VT == MVT::nxv8bf16) {
5590 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5591 SelectContiguousMultiVectorLoad(Node, 2, 1,
5592 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5593 AArch64::LDNT1H_2Z_PSEUDO);
5594 else if (Subtarget->hasSVE2p1())
5595 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5596 AArch64::LDNT1H_2Z);
5600 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5601 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5602 SelectContiguousMultiVectorLoad(Node, 2, 2,
5603 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5604 AArch64::LDNT1W_2Z_PSEUDO);
5605 else if (Subtarget->hasSVE2p1())
5606 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5607 AArch64::LDNT1W_2Z);
5611 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5612 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5613 SelectContiguousMultiVectorLoad(Node, 2, 3,
5614 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5615 AArch64::LDNT1D_2Z_PSEUDO);
5616 else if (Subtarget->hasSVE2p1())
5617 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5618 AArch64::LDNT1D_2Z);
5625 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5626 if (VT == MVT::nxv16i8) {
5627 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5628 SelectContiguousMultiVectorLoad(Node, 4, 0,
5629 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5630 AArch64::LDNT1B_4Z_PSEUDO);
5631 else if (Subtarget->hasSVE2p1())
5632 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5633 AArch64::LDNT1B_4Z);
5637 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5638 VT == MVT::nxv8bf16) {
5639 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5640 SelectContiguousMultiVectorLoad(Node, 4, 1,
5641 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5642 AArch64::LDNT1H_4Z_PSEUDO);
5643 else if (Subtarget->hasSVE2p1())
5644 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5645 AArch64::LDNT1H_4Z);
5649 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5650 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5651 SelectContiguousMultiVectorLoad(Node, 4, 2,
5652 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5653 AArch64::LDNT1W_4Z_PSEUDO);
5654 else if (Subtarget->hasSVE2p1())
5655 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5656 AArch64::LDNT1W_4Z);
5660 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5661 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5662 SelectContiguousMultiVectorLoad(Node, 4, 3,
5663 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5664 AArch64::LDNT1D_4Z_PSEUDO);
5665 else if (Subtarget->hasSVE2p1())
5666 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5667 AArch64::LDNT1D_4Z);
5674 case Intrinsic::aarch64_sve_ld3_sret: {
5675 if (VT == MVT::nxv16i8) {
5676 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5679 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5680 VT == MVT::nxv8bf16) {
5681 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5684 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5685 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5688 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5689 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5695 case Intrinsic::aarch64_sve_ld4_sret: {
5696 if (VT == MVT::nxv16i8) {
5697 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5700 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5701 VT == MVT::nxv8bf16) {
5702 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5705 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5706 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5709 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5710 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5716 case Intrinsic::aarch64_sme_read_hor_vg2: {
5717 if (VT == MVT::nxv16i8) {
5718 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5719 AArch64::MOVA_2ZMXI_H_B);
5721 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5722 VT == MVT::nxv8bf16) {
5723 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5724 AArch64::MOVA_2ZMXI_H_H);
5726 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5727 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5728 AArch64::MOVA_2ZMXI_H_S);
5730 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5731 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5732 AArch64::MOVA_2ZMXI_H_D);
5737 case Intrinsic::aarch64_sme_read_ver_vg2: {
5738 if (VT == MVT::nxv16i8) {
5739 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5740 AArch64::MOVA_2ZMXI_V_B);
5742 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5743 VT == MVT::nxv8bf16) {
5744 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5745 AArch64::MOVA_2ZMXI_V_H);
5747 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5748 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5749 AArch64::MOVA_2ZMXI_V_S);
5751 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5752 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5753 AArch64::MOVA_2ZMXI_V_D);
5758 case Intrinsic::aarch64_sme_read_hor_vg4: {
5759 if (VT == MVT::nxv16i8) {
5760 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5761 AArch64::MOVA_4ZMXI_H_B);
5763 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5764 VT == MVT::nxv8bf16) {
5765 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5766 AArch64::MOVA_4ZMXI_H_H);
5768 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5769 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5770 AArch64::MOVA_4ZMXI_H_S);
5772 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5773 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5774 AArch64::MOVA_4ZMXI_H_D);
5779 case Intrinsic::aarch64_sme_read_ver_vg4: {
5780 if (VT == MVT::nxv16i8) {
5781 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5782 AArch64::MOVA_4ZMXI_V_B);
5784 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5785 VT == MVT::nxv8bf16) {
5786 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5787 AArch64::MOVA_4ZMXI_V_H);
5789 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5790 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5791 AArch64::MOVA_4ZMXI_V_S);
5793 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5794 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5795 AArch64::MOVA_4ZMXI_V_D);
5800 case Intrinsic::aarch64_sme_read_vg1x2: {
5801 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5802 AArch64::MOVA_VG2_2ZMXI);
5805 case Intrinsic::aarch64_sme_read_vg1x4: {
5806 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5807 AArch64::MOVA_VG4_4ZMXI);
5810 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5811 if (VT == MVT::nxv16i8) {
5812 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5814 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5815 VT == MVT::nxv8bf16) {
5816 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5818 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5819 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5821 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5822 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5827 case Intrinsic::aarch64_sme_readz_vert_x2: {
5828 if (VT == MVT::nxv16i8) {
5829 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5831 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5832 VT == MVT::nxv8bf16) {
5833 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5835 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5836 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5838 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5839 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5844 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5845 if (VT == MVT::nxv16i8) {
5846 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5848 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5849 VT == MVT::nxv8bf16) {
5850 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5852 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5853 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5855 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5856 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5861 case Intrinsic::aarch64_sme_readz_vert_x4: {
5862 if (VT == MVT::nxv16i8) {
5863 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5865 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5866 VT == MVT::nxv8bf16) {
5867 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5869 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5870 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5872 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5873 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5878 case Intrinsic::aarch64_sme_readz_x2: {
5879 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5883 case Intrinsic::aarch64_sme_readz_x4: {
5884 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5888 case Intrinsic::swift_async_context_addr: {
5891 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5893 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5894 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5895 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5897 ReplaceUses(
SDValue(Node, 0), Res);
5899 CurDAG->RemoveDeadNode(Node);
5901 auto &MF = CurDAG->getMachineFunction();
5902 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5903 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5906 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5908 Node->getValueType(0),
5909 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5910 AArch64::LUTI2_4ZTZI_S}))
5912 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5915 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5917 Node->getValueType(0),
5918 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5920 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5923 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5925 Node->getValueType(0),
5926 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5927 AArch64::LUTI2_2ZTZI_S}))
5929 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5932 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5934 Node->getValueType(0),
5935 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5936 AArch64::LUTI4_2ZTZI_S}))
5938 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5941 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5942 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5945 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5947 Node->getValueType(0),
5948 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5949 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5951 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5953 Node->getValueType(0),
5954 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5955 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5957 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5959 Node->getValueType(0),
5960 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5961 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5963 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5965 Node->getValueType(0),
5966 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5967 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5969 case Intrinsic::ptrauth_resign_load_relative:
5970 SelectPtrauthResign(Node);
5975 unsigned IntNo =
Node->getConstantOperandVal(0);
5979 case Intrinsic::aarch64_tagp:
5983 case Intrinsic::ptrauth_auth:
5984 SelectPtrauthAuth(Node);
5987 case Intrinsic::ptrauth_resign:
5988 SelectPtrauthResign(Node);
5991 case Intrinsic::aarch64_neon_tbl2:
5992 SelectTable(Node, 2,
5993 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5996 case Intrinsic::aarch64_neon_tbl3:
5997 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5998 : AArch64::TBLv16i8Three,
6001 case Intrinsic::aarch64_neon_tbl4:
6002 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6003 : AArch64::TBLv16i8Four,
6006 case Intrinsic::aarch64_neon_tbx2:
6007 SelectTable(Node, 2,
6008 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6011 case Intrinsic::aarch64_neon_tbx3:
6012 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6013 : AArch64::TBXv16i8Three,
6016 case Intrinsic::aarch64_neon_tbx4:
6017 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6018 : AArch64::TBXv16i8Four,
6021 case Intrinsic::aarch64_sve_srshl_single_x2:
6023 Node->getValueType(0),
6024 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6025 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6026 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6028 case Intrinsic::aarch64_sve_srshl_single_x4:
6030 Node->getValueType(0),
6031 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6032 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6033 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6035 case Intrinsic::aarch64_sve_urshl_single_x2:
6037 Node->getValueType(0),
6038 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6039 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6040 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6042 case Intrinsic::aarch64_sve_urshl_single_x4:
6044 Node->getValueType(0),
6045 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6046 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6047 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6049 case Intrinsic::aarch64_sve_srshl_x2:
6051 Node->getValueType(0),
6052 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6053 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6054 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6056 case Intrinsic::aarch64_sve_srshl_x4:
6058 Node->getValueType(0),
6059 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6060 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6061 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6063 case Intrinsic::aarch64_sve_urshl_x2:
6065 Node->getValueType(0),
6066 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6067 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6068 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6070 case Intrinsic::aarch64_sve_urshl_x4:
6072 Node->getValueType(0),
6073 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6074 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6075 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6077 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6079 Node->getValueType(0),
6080 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6081 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6082 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6084 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6086 Node->getValueType(0),
6087 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6088 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6089 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6091 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6093 Node->getValueType(0),
6094 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6095 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6096 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6098 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6100 Node->getValueType(0),
6101 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6102 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6103 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6105 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6107 Node->getValueType(0),
6108 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6109 AArch64::FSCALE_2ZZ_D}))
6110 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6112 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6114 Node->getValueType(0),
6115 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6116 AArch64::FSCALE_4ZZ_D}))
6117 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6119 case Intrinsic::aarch64_sme_fp8_scale_x2:
6121 Node->getValueType(0),
6122 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6123 AArch64::FSCALE_2Z2Z_D}))
6124 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6126 case Intrinsic::aarch64_sme_fp8_scale_x4:
6128 Node->getValueType(0),
6129 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6130 AArch64::FSCALE_4Z4Z_D}))
6131 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6133 case Intrinsic::aarch64_sve_whilege_x2:
6135 Node->getValueType(0),
6136 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6137 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6138 SelectWhilePair(Node,
Op);
6140 case Intrinsic::aarch64_sve_whilegt_x2:
6142 Node->getValueType(0),
6143 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6144 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6145 SelectWhilePair(Node,
Op);
6147 case Intrinsic::aarch64_sve_whilehi_x2:
6149 Node->getValueType(0),
6150 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6151 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6152 SelectWhilePair(Node,
Op);
6154 case Intrinsic::aarch64_sve_whilehs_x2:
6156 Node->getValueType(0),
6157 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6158 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6159 SelectWhilePair(Node,
Op);
6161 case Intrinsic::aarch64_sve_whilele_x2:
6163 Node->getValueType(0),
6164 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6165 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6166 SelectWhilePair(Node,
Op);
6168 case Intrinsic::aarch64_sve_whilelo_x2:
6170 Node->getValueType(0),
6171 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6172 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6173 SelectWhilePair(Node,
Op);
6175 case Intrinsic::aarch64_sve_whilels_x2:
6177 Node->getValueType(0),
6178 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6179 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6180 SelectWhilePair(Node,
Op);
6182 case Intrinsic::aarch64_sve_whilelt_x2:
6184 Node->getValueType(0),
6185 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6186 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6187 SelectWhilePair(Node,
Op);
6189 case Intrinsic::aarch64_sve_smax_single_x2:
6191 Node->getValueType(0),
6192 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6193 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6194 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6196 case Intrinsic::aarch64_sve_umax_single_x2:
6198 Node->getValueType(0),
6199 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6200 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6201 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6203 case Intrinsic::aarch64_sve_fmax_single_x2:
6205 Node->getValueType(0),
6206 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6207 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6208 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6210 case Intrinsic::aarch64_sve_smax_single_x4:
6212 Node->getValueType(0),
6213 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6214 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6215 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6217 case Intrinsic::aarch64_sve_umax_single_x4:
6219 Node->getValueType(0),
6220 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6221 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6222 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6224 case Intrinsic::aarch64_sve_fmax_single_x4:
6226 Node->getValueType(0),
6227 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6228 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6229 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6231 case Intrinsic::aarch64_sve_smin_single_x2:
6233 Node->getValueType(0),
6234 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6235 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6236 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6238 case Intrinsic::aarch64_sve_umin_single_x2:
6240 Node->getValueType(0),
6241 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6242 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6243 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6245 case Intrinsic::aarch64_sve_fmin_single_x2:
6247 Node->getValueType(0),
6248 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6249 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6250 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6252 case Intrinsic::aarch64_sve_smin_single_x4:
6254 Node->getValueType(0),
6255 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6256 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6257 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6259 case Intrinsic::aarch64_sve_umin_single_x4:
6261 Node->getValueType(0),
6262 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6263 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6264 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6266 case Intrinsic::aarch64_sve_fmin_single_x4:
6268 Node->getValueType(0),
6269 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6270 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6271 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6273 case Intrinsic::aarch64_sve_smax_x2:
6275 Node->getValueType(0),
6276 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6277 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6278 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6280 case Intrinsic::aarch64_sve_umax_x2:
6282 Node->getValueType(0),
6283 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6284 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6285 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6287 case Intrinsic::aarch64_sve_fmax_x2:
6289 Node->getValueType(0),
6290 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6291 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6292 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6294 case Intrinsic::aarch64_sve_smax_x4:
6296 Node->getValueType(0),
6297 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6298 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6299 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6301 case Intrinsic::aarch64_sve_umax_x4:
6303 Node->getValueType(0),
6304 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6305 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6306 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6308 case Intrinsic::aarch64_sve_fmax_x4:
6310 Node->getValueType(0),
6311 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6312 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6313 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6315 case Intrinsic::aarch64_sme_famax_x2:
6317 Node->getValueType(0),
6318 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6319 AArch64::FAMAX_2Z2Z_D}))
6320 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6322 case Intrinsic::aarch64_sme_famax_x4:
6324 Node->getValueType(0),
6325 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6326 AArch64::FAMAX_4Z4Z_D}))
6327 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6329 case Intrinsic::aarch64_sme_famin_x2:
6331 Node->getValueType(0),
6332 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6333 AArch64::FAMIN_2Z2Z_D}))
6334 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6336 case Intrinsic::aarch64_sme_famin_x4:
6338 Node->getValueType(0),
6339 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6340 AArch64::FAMIN_4Z4Z_D}))
6341 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6343 case Intrinsic::aarch64_sve_smin_x2:
6345 Node->getValueType(0),
6346 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6347 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6348 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6350 case Intrinsic::aarch64_sve_umin_x2:
6352 Node->getValueType(0),
6353 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6354 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6355 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6357 case Intrinsic::aarch64_sve_fmin_x2:
6359 Node->getValueType(0),
6360 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6361 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6362 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6364 case Intrinsic::aarch64_sve_smin_x4:
6366 Node->getValueType(0),
6367 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6368 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6369 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6371 case Intrinsic::aarch64_sve_umin_x4:
6373 Node->getValueType(0),
6374 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6375 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6376 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6378 case Intrinsic::aarch64_sve_fmin_x4:
6380 Node->getValueType(0),
6381 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6382 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6383 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6385 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6387 Node->getValueType(0),
6388 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6389 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6390 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6392 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6394 Node->getValueType(0),
6395 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6396 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6397 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6399 case Intrinsic::aarch64_sve_fminnm_single_x2:
6401 Node->getValueType(0),
6402 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6403 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6404 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6406 case Intrinsic::aarch64_sve_fminnm_single_x4:
6408 Node->getValueType(0),
6409 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6410 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6411 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6413 case Intrinsic::aarch64_sve_fscale_single_x4:
6414 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6416 case Intrinsic::aarch64_sve_fscale_single_x2:
6417 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6419 case Intrinsic::aarch64_sve_fmul_single_x4:
6421 Node->getValueType(0),
6422 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6423 AArch64::FMUL_4ZZ_D}))
6424 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6426 case Intrinsic::aarch64_sve_fmul_single_x2:
6428 Node->getValueType(0),
6429 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6430 AArch64::FMUL_2ZZ_D}))
6431 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6433 case Intrinsic::aarch64_sve_fmaxnm_x2:
6435 Node->getValueType(0),
6436 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6437 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6438 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6440 case Intrinsic::aarch64_sve_fmaxnm_x4:
6442 Node->getValueType(0),
6443 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6444 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6445 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6447 case Intrinsic::aarch64_sve_fminnm_x2:
6449 Node->getValueType(0),
6450 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6451 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6452 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6454 case Intrinsic::aarch64_sve_fminnm_x4:
6456 Node->getValueType(0),
6457 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6458 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6459 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6461 case Intrinsic::aarch64_sve_aese_lane_x2:
6462 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6464 case Intrinsic::aarch64_sve_aesd_lane_x2:
6465 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6467 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6468 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6470 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6471 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6473 case Intrinsic::aarch64_sve_aese_lane_x4:
6474 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6476 case Intrinsic::aarch64_sve_aesd_lane_x4:
6477 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6479 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6480 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6482 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6483 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6485 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6486 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6488 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6492 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6494 for (
unsigned I = 0;
I < 2;
I++)
6496 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6498 CurDAG->RemoveDeadNode(Node);
6501 case Intrinsic::aarch64_sve_fscale_x4:
6502 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6504 case Intrinsic::aarch64_sve_fscale_x2:
6505 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6507 case Intrinsic::aarch64_sve_fmul_x4:
6509 Node->getValueType(0),
6510 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6511 AArch64::FMUL_4Z4Z_D}))
6512 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6514 case Intrinsic::aarch64_sve_fmul_x2:
6516 Node->getValueType(0),
6517 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6518 AArch64::FMUL_2Z2Z_D}))
6519 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6521 case Intrinsic::aarch64_sve_fcvtzs_x2:
6522 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6524 case Intrinsic::aarch64_sve_scvtf_x2:
6525 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6527 case Intrinsic::aarch64_sve_fcvtzu_x2:
6528 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6530 case Intrinsic::aarch64_sve_ucvtf_x2:
6531 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6533 case Intrinsic::aarch64_sve_fcvtzs_x4:
6534 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6536 case Intrinsic::aarch64_sve_scvtf_x4:
6537 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6539 case Intrinsic::aarch64_sve_fcvtzu_x4:
6540 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6542 case Intrinsic::aarch64_sve_ucvtf_x4:
6543 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6545 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6546 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6548 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6549 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6551 case Intrinsic::aarch64_sve_sclamp_single_x2:
6553 Node->getValueType(0),
6554 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6555 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6556 SelectClamp(Node, 2,
Op);
6558 case Intrinsic::aarch64_sve_uclamp_single_x2:
6560 Node->getValueType(0),
6561 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6562 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6563 SelectClamp(Node, 2,
Op);
6565 case Intrinsic::aarch64_sve_fclamp_single_x2:
6567 Node->getValueType(0),
6568 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6569 AArch64::FCLAMP_VG2_2Z2Z_D}))
6570 SelectClamp(Node, 2,
Op);
6572 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6573 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6575 case Intrinsic::aarch64_sve_sclamp_single_x4:
6577 Node->getValueType(0),
6578 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6579 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6580 SelectClamp(Node, 4,
Op);
6582 case Intrinsic::aarch64_sve_uclamp_single_x4:
6584 Node->getValueType(0),
6585 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6586 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6587 SelectClamp(Node, 4,
Op);
6589 case Intrinsic::aarch64_sve_fclamp_single_x4:
6591 Node->getValueType(0),
6592 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6593 AArch64::FCLAMP_VG4_4Z4Z_D}))
6594 SelectClamp(Node, 4,
Op);
6596 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6597 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6599 case Intrinsic::aarch64_sve_add_single_x2:
6601 Node->getValueType(0),
6602 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6603 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6604 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6606 case Intrinsic::aarch64_sve_add_single_x4:
6608 Node->getValueType(0),
6609 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6610 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6611 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6613 case Intrinsic::aarch64_sve_zip_x2:
6615 Node->getValueType(0),
6616 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6617 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6618 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6620 case Intrinsic::aarch64_sve_zipq_x2:
6621 SelectUnaryMultiIntrinsic(Node, 2,
false,
6622 AArch64::ZIP_VG2_2ZZZ_Q);
6624 case Intrinsic::aarch64_sve_zip_x4:
6626 Node->getValueType(0),
6627 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6628 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6629 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6631 case Intrinsic::aarch64_sve_zipq_x4:
6632 SelectUnaryMultiIntrinsic(Node, 4,
true,
6633 AArch64::ZIP_VG4_4Z4Z_Q);
6635 case Intrinsic::aarch64_sve_uzp_x2:
6637 Node->getValueType(0),
6638 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6639 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6640 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6642 case Intrinsic::aarch64_sve_uzpq_x2:
6643 SelectUnaryMultiIntrinsic(Node, 2,
false,
6644 AArch64::UZP_VG2_2ZZZ_Q);
6646 case Intrinsic::aarch64_sve_uzp_x4:
6648 Node->getValueType(0),
6649 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6650 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6651 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6653 case Intrinsic::aarch64_sve_uzpq_x4:
6654 SelectUnaryMultiIntrinsic(Node, 4,
true,
6655 AArch64::UZP_VG4_4Z4Z_Q);
6657 case Intrinsic::aarch64_sve_sel_x2:
6659 Node->getValueType(0),
6660 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6661 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6662 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6664 case Intrinsic::aarch64_sve_sel_x4:
6666 Node->getValueType(0),
6667 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6668 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6669 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6671 case Intrinsic::aarch64_sve_frinta_x2:
6672 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6674 case Intrinsic::aarch64_sve_frinta_x4:
6675 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6677 case Intrinsic::aarch64_sve_frintm_x2:
6678 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6680 case Intrinsic::aarch64_sve_frintm_x4:
6681 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6683 case Intrinsic::aarch64_sve_frintn_x2:
6684 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6686 case Intrinsic::aarch64_sve_frintn_x4:
6687 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6689 case Intrinsic::aarch64_sve_frintp_x2:
6690 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6692 case Intrinsic::aarch64_sve_frintp_x4:
6693 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6695 case Intrinsic::aarch64_sve_sunpk_x2:
6697 Node->getValueType(0),
6698 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6699 AArch64::SUNPK_VG2_2ZZ_D}))
6700 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6702 case Intrinsic::aarch64_sve_uunpk_x2:
6704 Node->getValueType(0),
6705 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6706 AArch64::UUNPK_VG2_2ZZ_D}))
6707 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6709 case Intrinsic::aarch64_sve_sunpk_x4:
6711 Node->getValueType(0),
6712 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6713 AArch64::SUNPK_VG4_4Z2Z_D}))
6714 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6716 case Intrinsic::aarch64_sve_uunpk_x4:
6718 Node->getValueType(0),
6719 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6720 AArch64::UUNPK_VG4_4Z2Z_D}))
6721 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6723 case Intrinsic::aarch64_sve_pext_x2: {
6725 Node->getValueType(0),
6726 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6727 AArch64::PEXT_2PCI_D}))
6728 SelectPExtPair(Node,
Op);
6735 unsigned IntNo =
Node->getConstantOperandVal(1);
6736 if (
Node->getNumOperands() >= 3)
6737 VT =
Node->getOperand(2)->getValueType(0);
6741 case Intrinsic::aarch64_neon_st1x2: {
6742 if (VT == MVT::v8i8) {
6743 SelectStore(Node, 2, AArch64::ST1Twov8b);
6745 }
else if (VT == MVT::v16i8) {
6746 SelectStore(Node, 2, AArch64::ST1Twov16b);
6748 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6749 VT == MVT::v4bf16) {
6750 SelectStore(Node, 2, AArch64::ST1Twov4h);
6752 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6753 VT == MVT::v8bf16) {
6754 SelectStore(Node, 2, AArch64::ST1Twov8h);
6756 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6757 SelectStore(Node, 2, AArch64::ST1Twov2s);
6759 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6760 SelectStore(Node, 2, AArch64::ST1Twov4s);
6762 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6763 SelectStore(Node, 2, AArch64::ST1Twov2d);
6765 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6766 SelectStore(Node, 2, AArch64::ST1Twov1d);
6771 case Intrinsic::aarch64_neon_st1x3: {
6772 if (VT == MVT::v8i8) {
6773 SelectStore(Node, 3, AArch64::ST1Threev8b);
6775 }
else if (VT == MVT::v16i8) {
6776 SelectStore(Node, 3, AArch64::ST1Threev16b);
6778 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6779 VT == MVT::v4bf16) {
6780 SelectStore(Node, 3, AArch64::ST1Threev4h);
6782 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6783 VT == MVT::v8bf16) {
6784 SelectStore(Node, 3, AArch64::ST1Threev8h);
6786 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6787 SelectStore(Node, 3, AArch64::ST1Threev2s);
6789 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6790 SelectStore(Node, 3, AArch64::ST1Threev4s);
6792 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6793 SelectStore(Node, 3, AArch64::ST1Threev2d);
6795 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6796 SelectStore(Node, 3, AArch64::ST1Threev1d);
6801 case Intrinsic::aarch64_neon_st1x4: {
6802 if (VT == MVT::v8i8) {
6803 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6805 }
else if (VT == MVT::v16i8) {
6806 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6808 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6809 VT == MVT::v4bf16) {
6810 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6812 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6813 VT == MVT::v8bf16) {
6814 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6816 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6817 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6819 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6820 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6822 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6823 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6825 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6826 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6831 case Intrinsic::aarch64_neon_st2: {
6832 if (VT == MVT::v8i8) {
6833 SelectStore(Node, 2, AArch64::ST2Twov8b);
6835 }
else if (VT == MVT::v16i8) {
6836 SelectStore(Node, 2, AArch64::ST2Twov16b);
6838 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6839 VT == MVT::v4bf16) {
6840 SelectStore(Node, 2, AArch64::ST2Twov4h);
6842 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6843 VT == MVT::v8bf16) {
6844 SelectStore(Node, 2, AArch64::ST2Twov8h);
6846 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6847 SelectStore(Node, 2, AArch64::ST2Twov2s);
6849 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6850 SelectStore(Node, 2, AArch64::ST2Twov4s);
6852 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6853 SelectStore(Node, 2, AArch64::ST2Twov2d);
6855 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6856 SelectStore(Node, 2, AArch64::ST1Twov1d);
6861 case Intrinsic::aarch64_neon_st3: {
6862 if (VT == MVT::v8i8) {
6863 SelectStore(Node, 3, AArch64::ST3Threev8b);
6865 }
else if (VT == MVT::v16i8) {
6866 SelectStore(Node, 3, AArch64::ST3Threev16b);
6868 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6869 VT == MVT::v4bf16) {
6870 SelectStore(Node, 3, AArch64::ST3Threev4h);
6872 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6873 VT == MVT::v8bf16) {
6874 SelectStore(Node, 3, AArch64::ST3Threev8h);
6876 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6877 SelectStore(Node, 3, AArch64::ST3Threev2s);
6879 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6880 SelectStore(Node, 3, AArch64::ST3Threev4s);
6882 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6883 SelectStore(Node, 3, AArch64::ST3Threev2d);
6885 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6886 SelectStore(Node, 3, AArch64::ST1Threev1d);
6891 case Intrinsic::aarch64_neon_st4: {
6892 if (VT == MVT::v8i8) {
6893 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6895 }
else if (VT == MVT::v16i8) {
6896 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6898 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6899 VT == MVT::v4bf16) {
6900 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6902 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6903 VT == MVT::v8bf16) {
6904 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6906 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6907 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6909 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6910 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6912 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6913 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6915 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6916 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6921 case Intrinsic::aarch64_neon_st2lane: {
6922 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6923 SelectStoreLane(Node, 2, AArch64::ST2i8);
6925 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6926 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6927 SelectStoreLane(Node, 2, AArch64::ST2i16);
6929 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6931 SelectStoreLane(Node, 2, AArch64::ST2i32);
6933 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6935 SelectStoreLane(Node, 2, AArch64::ST2i64);
6940 case Intrinsic::aarch64_neon_st3lane: {
6941 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6942 SelectStoreLane(Node, 3, AArch64::ST3i8);
6944 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6945 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6946 SelectStoreLane(Node, 3, AArch64::ST3i16);
6948 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6950 SelectStoreLane(Node, 3, AArch64::ST3i32);
6952 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6954 SelectStoreLane(Node, 3, AArch64::ST3i64);
6959 case Intrinsic::aarch64_neon_st4lane: {
6960 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6961 SelectStoreLane(Node, 4, AArch64::ST4i8);
6963 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6964 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6965 SelectStoreLane(Node, 4, AArch64::ST4i16);
6967 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6969 SelectStoreLane(Node, 4, AArch64::ST4i32);
6971 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6973 SelectStoreLane(Node, 4, AArch64::ST4i64);
6978 case Intrinsic::aarch64_sve_st2q: {
6979 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6982 case Intrinsic::aarch64_sve_st3q: {
6983 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6986 case Intrinsic::aarch64_sve_st4q: {
6987 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6990 case Intrinsic::aarch64_sve_st2: {
6991 if (VT == MVT::nxv16i8) {
6992 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6994 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6995 VT == MVT::nxv8bf16) {
6996 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6998 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6999 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7001 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7002 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7007 case Intrinsic::aarch64_sve_st3: {
7008 if (VT == MVT::nxv16i8) {
7009 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7011 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7012 VT == MVT::nxv8bf16) {
7013 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7015 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7016 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7018 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7019 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7024 case Intrinsic::aarch64_sve_st4: {
7025 if (VT == MVT::nxv16i8) {
7026 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7028 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7029 VT == MVT::nxv8bf16) {
7030 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7032 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7033 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7035 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7036 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7044 case AArch64ISD::LD2post: {
7045 if (VT == MVT::v8i8) {
7046 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7048 }
else if (VT == MVT::v16i8) {
7049 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7051 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7052 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7054 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7055 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7057 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7058 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7060 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7061 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7063 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7064 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7066 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7067 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7072 case AArch64ISD::LD3post: {
7073 if (VT == MVT::v8i8) {
7074 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7076 }
else if (VT == MVT::v16i8) {
7077 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7079 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7080 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7082 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7083 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7085 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7086 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7088 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7089 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7091 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7092 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7094 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7095 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7100 case AArch64ISD::LD4post: {
7101 if (VT == MVT::v8i8) {
7102 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7104 }
else if (VT == MVT::v16i8) {
7105 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7107 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7108 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7110 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7111 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7113 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7114 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7116 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7117 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7119 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7120 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7122 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7123 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7128 case AArch64ISD::LD1x2post: {
7129 if (VT == MVT::v8i8) {
7130 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7132 }
else if (VT == MVT::v16i8) {
7133 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7135 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7136 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7138 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7139 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7141 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7142 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7144 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7145 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7147 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7148 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7150 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7151 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7156 case AArch64ISD::LD1x3post: {
7157 if (VT == MVT::v8i8) {
7158 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7160 }
else if (VT == MVT::v16i8) {
7161 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7163 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7164 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7166 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7167 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7169 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7170 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7172 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7173 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7175 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7176 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7178 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7179 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7184 case AArch64ISD::LD1x4post: {
7185 if (VT == MVT::v8i8) {
7186 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7188 }
else if (VT == MVT::v16i8) {
7189 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7191 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7192 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7194 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7195 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7197 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7198 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7200 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7201 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7203 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7204 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7206 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7207 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7212 case AArch64ISD::LD1DUPpost: {
7213 if (VT == MVT::v8i8) {
7214 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7216 }
else if (VT == MVT::v16i8) {
7217 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7219 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7220 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7222 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7223 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7225 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7226 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7228 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7229 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7231 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7232 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7234 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7235 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7240 case AArch64ISD::LD2DUPpost: {
7241 if (VT == MVT::v8i8) {
7242 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7244 }
else if (VT == MVT::v16i8) {
7245 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7247 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7248 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7250 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7251 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7253 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7254 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7256 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7257 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7259 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7260 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7262 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7263 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7268 case AArch64ISD::LD3DUPpost: {
7269 if (VT == MVT::v8i8) {
7270 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7272 }
else if (VT == MVT::v16i8) {
7273 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7275 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7276 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7278 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7279 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7281 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7282 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7284 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7285 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7287 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7288 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7290 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7291 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7296 case AArch64ISD::LD4DUPpost: {
7297 if (VT == MVT::v8i8) {
7298 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7300 }
else if (VT == MVT::v16i8) {
7301 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7303 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7304 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7306 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7307 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7309 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7310 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7312 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7313 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7315 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7316 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7318 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7319 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7324 case AArch64ISD::LD1LANEpost: {
7325 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7326 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7328 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7329 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7330 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7332 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7334 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7336 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7338 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7343 case AArch64ISD::LD2LANEpost: {
7344 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7345 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7347 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7348 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7349 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7351 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7353 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7355 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7357 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7362 case AArch64ISD::LD3LANEpost: {
7363 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7364 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7366 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7367 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7368 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7370 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7372 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7374 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7376 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7381 case AArch64ISD::LD4LANEpost: {
7382 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7383 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7385 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7386 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7387 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7389 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7391 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7393 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7395 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7400 case AArch64ISD::ST2post: {
7401 VT =
Node->getOperand(1).getValueType();
7402 if (VT == MVT::v8i8) {
7403 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7405 }
else if (VT == MVT::v16i8) {
7406 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7408 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7409 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7411 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7412 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7414 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7415 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7417 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7418 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7420 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7421 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7423 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7424 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7429 case AArch64ISD::ST3post: {
7430 VT =
Node->getOperand(1).getValueType();
7431 if (VT == MVT::v8i8) {
7432 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7434 }
else if (VT == MVT::v16i8) {
7435 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7437 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7438 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7440 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7441 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7443 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7444 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7446 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7447 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7449 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7450 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7452 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7453 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7458 case AArch64ISD::ST4post: {
7459 VT =
Node->getOperand(1).getValueType();
7460 if (VT == MVT::v8i8) {
7461 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7463 }
else if (VT == MVT::v16i8) {
7464 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7466 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7467 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7469 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7470 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7472 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7473 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7475 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7476 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7478 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7479 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7481 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7482 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7487 case AArch64ISD::ST1x2post: {
7488 VT =
Node->getOperand(1).getValueType();
7489 if (VT == MVT::v8i8) {
7490 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7492 }
else if (VT == MVT::v16i8) {
7493 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7495 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7496 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7498 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7499 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7501 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7502 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7504 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7505 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7507 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7508 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7510 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7511 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7516 case AArch64ISD::ST1x3post: {
7517 VT =
Node->getOperand(1).getValueType();
7518 if (VT == MVT::v8i8) {
7519 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7521 }
else if (VT == MVT::v16i8) {
7522 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7524 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7525 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7527 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7528 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7530 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7531 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7533 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7534 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7536 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7537 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7539 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7540 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7545 case AArch64ISD::ST1x4post: {
7546 VT =
Node->getOperand(1).getValueType();
7547 if (VT == MVT::v8i8) {
7548 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7550 }
else if (VT == MVT::v16i8) {
7551 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7553 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7554 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7556 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7557 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7559 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7560 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7562 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7563 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7565 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7566 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7568 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7569 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7574 case AArch64ISD::ST2LANEpost: {
7575 VT =
Node->getOperand(1).getValueType();
7576 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7577 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7579 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7580 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7581 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7583 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7585 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7587 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7589 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7594 case AArch64ISD::ST3LANEpost: {
7595 VT =
Node->getOperand(1).getValueType();
7596 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7597 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7599 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7600 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7601 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7603 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7605 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7607 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7609 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7614 case AArch64ISD::ST4LANEpost: {
7615 VT =
Node->getOperand(1).getValueType();
7616 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7617 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7619 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7620 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7621 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7623 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7625 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7627 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7629 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7644 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7656 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7660 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7661 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7676 return MemIntr->getMemoryVT();
7683 DataVT = Load->getValueType(0);
7685 DataVT = Load->getValueType(0);
7687 DataVT = Store->getValue().getValueType();
7689 DataVT = Store->getValue().getValueType();
7696 const unsigned Opcode = Root->
getOpcode();
7700 case AArch64ISD::LD1_MERGE_ZERO:
7701 case AArch64ISD::LD1S_MERGE_ZERO:
7702 case AArch64ISD::LDNF1_MERGE_ZERO:
7703 case AArch64ISD::LDNF1S_MERGE_ZERO:
7705 case AArch64ISD::ST1_PRED:
7717 case Intrinsic::aarch64_sme_ldr:
7718 case Intrinsic::aarch64_sme_str:
7719 return MVT::nxv16i8;
7720 case Intrinsic::aarch64_sve_prf:
7725 case Intrinsic::aarch64_sve_ld2_sret:
7726 case Intrinsic::aarch64_sve_ld2q_sret:
7729 case Intrinsic::aarch64_sve_st2q:
7732 case Intrinsic::aarch64_sve_ld3_sret:
7733 case Intrinsic::aarch64_sve_ld3q_sret:
7736 case Intrinsic::aarch64_sve_st3q:
7739 case Intrinsic::aarch64_sve_ld4_sret:
7740 case Intrinsic::aarch64_sve_ld4q_sret:
7743 case Intrinsic::aarch64_sve_st4q:
7746 case Intrinsic::aarch64_sve_ld1udq:
7747 case Intrinsic::aarch64_sve_st1dq:
7748 return EVT(MVT::nxv1i64);
7749 case Intrinsic::aarch64_sve_ld1uwq:
7750 case Intrinsic::aarch64_sve_st1wq:
7751 return EVT(MVT::nxv1i32);
7758template <
int64_t Min,
int64_t Max>
7759bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7763 const DataLayout &
DL = CurDAG->getDataLayout();
7764 const MachineFrameInfo &MFI = MF->getFrameInfo();
7772 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7786 int64_t MulImm = std::numeric_limits<int64_t>::max();
7790 int64_t ByteOffset =
C->getSExtValue();
7791 const auto KnownVScale =
7794 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7797 MulImm = ByteOffset / KnownVScale;
7804 if ((MulImm % MemWidthBytes) != 0)
7807 int64_t
Offset = MulImm / MemWidthBytes;
7811 Base =
N.getOperand(0);
7820 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7826bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7845 int64_t ImmOff =
C->getSExtValue();
7846 unsigned Size = 1 << Scale;
7855 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7857 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7868 if (
C->getZExtValue() == Scale) {
7877bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7878 const AArch64TargetLowering *TLI =
7879 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7884bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7885 EVT VT =
N.getValueType();
7889bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7894 int64_t ImmOff =
C->getSExtValue();
7895 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7896 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7901 if (
SDValue C = MatchConstantOffset(
N)) {
7902 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7908 if (CurDAG->isBaseWithConstantOffset(
N)) {
7909 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7910 Base =
N.getOperand(0);
7918 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7922bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7942 uint64_t LowerBound = 0, UpperBound = 64;
7960 if (CN->getAPIntValue().uge(LowerBound) &&
7961 CN->getAPIntValue().ult(UpperBound)) {
7963 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7971template <
bool MatchCBB>
7978 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7980 Reg =
N.getOperand(0);
7982 SDLoc(
N), MVT::i32);
7990 Reg =
N.getOperand(0);
8010SDValue AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode &
N) {
8011 EVT VT =
N.getValueType(0);
8022 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8031 unsigned CondCode = CC->getZExtValue();
8034 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8036 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8037 else if (VT == MVT::f32)
8038 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8039 else if (VT == MVT::f64)
8040 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8048 if (TVal == CmpLHS && FVal == CmpRHS)
8050 else if (TVal == CmpRHS && FVal == CmpLHS)
8055 if (TVal == CmpLHS && FVal == CmpRHS)
8057 else if (TVal == CmpRHS && FVal == CmpLHS)
8066 unsigned Opc = getOpc(VT, isMax);
8072 if (!CFP || CFP->getValueAPF().isNaN())
8077 if (CFP->isZero() && !
N.getFlags().hasNoSignedZeros())
8083 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8089 return SDValue(CurDAG->getMachineNode(
Opc,
DL, VT, CmpLHS, CmpRHS), 0);
8092void AArch64DAGToDAGISel::PreprocessISelDAG() {
8093 bool MadeChange =
false;
8099 switch (
N.getOpcode()) {
8101 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8102 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8103 ScalarTy ==
N.getOperand(0).getValueType())
8108 case AArch64ISD::CSEL:
8109 Result = tryFoldCselToFMaxMin(
N);
8116 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8122 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8128 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.
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.