22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
64 void PreprocessISelDAG()
override;
68 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
70 std::vector<SDValue> &OutOps)
override;
72 template <
signed Low,
signed High,
signed Scale>
75 template <
signed Low,
signed High>
83 return SelectShiftedRegister(
N,
false,
Reg, Shift);
86 return SelectShiftedRegister(
N,
true,
Reg, Shift);
89 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
95 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
98 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
101 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
104 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
107 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
116 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
119 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
122 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
131 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
134 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
137 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
139 template <
unsigned Size,
unsigned Max>
143 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
146 int64_t
C = CI->getSExtValue();
154 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
161 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
167 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
172 N =
N->getOperand(0);
176 EVT VT =
N->getValueType(0);
177 EVT LVT =
N->getOperand(0).getValueType();
178 unsigned Index =
N->getConstantOperandVal(1);
182 Res =
N->getOperand(0);
187 if (
N.getOpcode() != AArch64ISD::VLSHR)
190 EVT VT =
Op.getValueType();
191 unsigned ShtAmt =
N->getConstantOperandVal(1);
196 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
198 Op.getOperand(1).getConstantOperandVal(0)
199 <<
Op.getOperand(1).getConstantOperandVal(1));
200 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
203 Op.getOperand(1).getConstantOperandVal(0));
207 if (Imm != 1ULL << (ShtAmt - 1))
210 Res1 =
Op.getOperand(0);
211 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
215 bool SelectDupZeroOrUndef(
SDValue N) {
216 switch(
N->getOpcode()) {
219 case AArch64ISD::DUP:
221 auto Opnd0 =
N->getOperand(0);
235 bool SelectAny(
SDValue) {
return true; }
238 switch(
N->getOpcode()) {
239 case AArch64ISD::DUP:
241 auto Opnd0 =
N->getOperand(0);
253 template <MVT::SimpleValueType VT,
bool Negate>
255 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT>
265 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
268 template <MVT::SimpleValueType VT,
bool Invert = false>
270 return SelectSVELogicalImm(
N, VT, Imm, Invert);
273 template <MVT::SimpleValueType VT>
275 return SelectSVEArithImm(
N, VT, Imm);
278 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
280 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
287 EVT EltVT =
N->getValueType(0).getVectorElementType();
288 return SelectSVEShiftImm(
N->getOperand(0), 1,
294 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
301 MulImm = 1LL << MulImm;
303 if ((MulImm % std::abs(Scale)) != 0)
307 if ((MulImm >= Min) && (MulImm <= Max)) {
308 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
315 template <
signed Max,
signed Scale>
322 if (MulImm >= 0 && MulImm <= Max) {
324 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
331 template <
unsigned BaseReg,
unsigned Max>
339 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
362 const unsigned SubRegs[]);
364 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
366 bool tryIndexedLoad(
SDNode *
N);
368 void SelectPtrauthAuth(
SDNode *
N);
369 void SelectPtrauthResign(
SDNode *
N);
371 bool trySelectStackSlotTagP(
SDNode *
N);
374 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
376 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
380 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
381 unsigned Opc_rr,
unsigned Opc_ri,
382 bool IsIntr =
false);
383 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
384 unsigned Scale,
unsigned Opc_ri,
386 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
387 bool IsZmMulti,
unsigned Opcode,
388 bool HasPred =
false);
390 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
391 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
395 bool IsTupleInput,
unsigned Opc);
396 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 template <
unsigned MaxIdx,
unsigned Scale>
399 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
401 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
402 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
403 unsigned BaseReg = 0);
406 template <
int64_t Min,
int64_t Max>
410 template <
unsigned Scale>
412 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
415 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
420 template <
unsigned MaxIdx,
unsigned Scale>
425 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
430 unsigned Opc_rr,
unsigned Opc_ri);
431 std::tuple<unsigned, SDValue, SDValue>
432 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
436 bool tryBitfieldExtractOp(
SDNode *
N);
437 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
438 bool tryBitfieldInsertOp(
SDNode *
N);
439 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
440 bool tryShiftAmountMod(
SDNode *
N);
442 bool tryReadRegister(
SDNode *
N);
443 bool tryWriteRegister(
SDNode *
N);
445 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
446 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
453#include "AArch64GenDAGISel.inc"
461 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
463 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
476 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
477 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
478 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
481 template<
unsigned RegW
idth>
483 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
485 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
487 template <
unsigned RegW
idth>
489 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
491 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
493 template<
unsigned RegW
idth>
495 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
501 template <
unsigned FloatW
idth>
503 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
509 bool SelectCMP_SWAP(
SDNode *
N);
528 bool AllowSaturation,
SDValue &Imm);
536 bool SelectAllActivePredicate(
SDValue N);
541 template <
bool MatchCBB>
551 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
555char AArch64DAGToDAGISelLegacy::ID = 0;
563 auto getFloatVT = [&](
EVT VT) {
565 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
566 return VT.changeElementType(*(DAG.getContext()),
567 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
572 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
573 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
577 EVT OrigVT =
N.getValueType(0);
579 return DAG.getBitcast(OrigVT, OpNode);
586 Imm =
C->getZExtValue();
603 return N->getOpcode() ==
Opc &&
614 return Imm == ImmExpected;
619 assert(RegWidth == 32 || RegWidth == 64);
621 return APInt(RegWidth,
628 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
629 if (
N->getOpcode() == AArch64ISD::NVCAST)
630 N =
N->getOperand(0);
631 unsigned SplatWidth =
N.getScalarValueSizeInBits();
632 if (
N.getOpcode() == AArch64ISD::FMOV)
634 if (
N->getOpcode() == AArch64ISD::MOVI)
635 return APInt(SplatWidth,
N.getConstantOperandVal(0));
636 if (
N->getOpcode() == AArch64ISD::MOVIshift)
637 return APInt(SplatWidth,
N.getConstantOperandVal(0)
638 <<
N.getConstantOperandVal(1));
639 if (
N->getOpcode() == AArch64ISD::MVNIshift)
640 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
641 <<
N.getConstantOperandVal(1));
642 if (
N->getOpcode() == AArch64ISD::MOVIedit)
644 N.getConstantOperandVal(0)));
645 if (
N->getOpcode() == AArch64ISD::DUP)
647 return Const->getAPIntValue().trunc(SplatWidth);
656 unsigned SplatWidth =
N.getScalarValueSizeInBits();
658 if (SplatVal->getBitWidth() <= SplatWidth)
660 if (SplatVal->isSplat(SplatWidth))
661 return SplatVal->trunc(SplatWidth);
666bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
673 ImmVal->getZExtValue(), Encoding))
676 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
680bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
683 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
684 N.getValueType().getScalarType().getSimpleVT(),
690bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
693 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
697bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
699 std::vector<SDValue> &OutOps) {
700 switch(ConstraintID) {
703 case InlineAsm::ConstraintCode::m:
704 case InlineAsm::ConstraintCode::o:
705 case InlineAsm::ConstraintCode::Q:
709 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
711 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
713 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
714 dl,
Op.getValueType(),
716 OutOps.push_back(NewOp);
735 uint64_t Immed =
N.getNode()->getAsZExtVal();
738 if (Immed >> 12 == 0) {
740 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
748 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
749 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
766 uint64_t Immed =
N.getNode()->getAsZExtVal();
774 if (
N.getValueType() == MVT::i32)
775 Immed = ~((uint32_t)Immed) + 1;
777 Immed = ~Immed + 1ULL;
778 if (Immed & 0xFFFFFFFFFF000000ULL)
781 Immed &= 0xFFFFFFULL;
782 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
789 switch (
N.getOpcode()) {
815 unsigned ShiftVal = CSD->getZExtValue();
833bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
836 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
841 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
865 EVT VT =
N.getValueType();
866 if (VT != MVT::i32 && VT != MVT::i64)
869 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
875 unsigned LHSOpcode =
LHS->getOpcode();
889 unsigned LowZBits, MaskLen;
893 unsigned BitWidth =
N.getValueSizeInBits();
900 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
903 NewShiftC = LowZBits - ShiftAmtC;
904 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
910 NewShiftC = LowZBits + ShiftAmtC;
923 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
925 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
929 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
931 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
932 NewShiftAmt, BitWidthMinus1),
935 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
949 SrcVT =
N.getOperand(0).getValueType();
951 if (!IsLoadStore && SrcVT == MVT::i8)
953 else if (!IsLoadStore && SrcVT == MVT::i16)
955 else if (SrcVT == MVT::i32)
957 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
962 EVT SrcVT =
N.getOperand(0).getValueType();
963 if (!IsLoadStore && SrcVT == MVT::i8)
965 else if (!IsLoadStore && SrcVT == MVT::i16)
967 else if (SrcVT == MVT::i32)
969 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
997bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
1000 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1005 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1006 V.getConstantOperandVal(1) <= 4 &&
1019bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
1021 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1031 unsigned BitSize =
N.getValueSizeInBits();
1032 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1035 Reg =
N.getOperand(0);
1036 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1037 return isWorthFoldingALU(
N,
true);
1048 if (
N.getValueType() == MVT::i32)
1056template<
signed Low,
signed High,
signed Scale>
1062 if ((MulImm % std::abs(Scale)) == 0) {
1063 int64_t RDVLImm = MulImm / Scale;
1064 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1065 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1074template <
signed Low,
signed High>
1075bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1080 if (MulImm >=
Low && MulImm <=
High) {
1081 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1092 unsigned ShiftVal = 0;
1107 Reg =
N.getOperand(0).getOperand(0);
1119 Op =
Op->getOperand(0);
1121 Op.getOperand(0).getValueType().isFixedLengthVector())
1125 Reg =
N.getOperand(0);
1130 unsigned Opc =
N.getOpcode();
1148 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1150 return isWorthFoldingALU(
N);
1157 unsigned ShiftVal = 0;
1171 Reg =
N.getOperand(0);
1172 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1174 return isWorthFoldingALU(
N);
1183 for (
auto *
User :
N->users()) {
1210bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1211 unsigned BW,
unsigned Size,
1215 const DataLayout &
DL = CurDAG->getDataLayout();
1216 const TargetLowering *TLI = getTargetLowering();
1220 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1226 if (CurDAG->isBaseWithConstantOffset(
N)) {
1229 int64_t RHSC =
RHS->getSExtValue();
1231 int64_t
Range = 0x1LL << (BW - 1);
1233 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1234 RHSC < (
Range << Scale)) {
1235 Base =
N.getOperand(0);
1240 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1245 uint64_t RHSC =
RHS->getZExtValue();
1247 uint64_t
Range = 0x1ULL << BW;
1249 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1250 Base =
N.getOperand(0);
1255 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1266 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1273bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1276 const DataLayout &
DL = CurDAG->getDataLayout();
1277 const TargetLowering *TLI = getTargetLowering();
1281 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1286 GlobalAddressSDNode *GAN =
1288 Base =
N.getOperand(0);
1298 if (CurDAG->isBaseWithConstantOffset(
N)) {
1300 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1303 Base =
N.getOperand(0);
1308 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1316 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1324 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1333bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1336 if (!CurDAG->isBaseWithConstantOffset(
N))
1339 int64_t RHSC =
RHS->getSExtValue();
1340 if (RHSC >= -256 && RHSC < 256) {
1341 Base =
N.getOperand(0);
1344 const TargetLowering *TLI = getTargetLowering();
1345 Base = CurDAG->getTargetFrameIndex(
1348 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1358 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1365bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1385 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1391 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1394 return isWorthFoldingAddr(
N,
Size);
1397bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1415 const SDNode *
Node =
N.getNode();
1416 for (SDNode *UI :
Node->users()) {
1422 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1425 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1428 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1433 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1436 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1441 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1445 if (IsExtendedRegisterWorthFolding &&
1452 if (isWorthFoldingAddr(
LHS,
Size))
1457 if (IsExtendedRegisterWorthFolding &&
1464 if (isWorthFoldingAddr(
RHS,
Size))
1476 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1479 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1481 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1482 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1486bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1499 const SDNode *
Node =
N.getNode();
1500 for (SDNode *UI :
Node->users()) {
1517 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1527 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1534 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1537 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1540 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1545 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1548 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1555 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1556 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1562 static const unsigned RegClassIDs[] = {
1563 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1564 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1565 AArch64::dsub2, AArch64::dsub3};
1571 static const unsigned RegClassIDs[] = {
1572 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1573 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1574 AArch64::qsub2, AArch64::qsub3};
1580 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1581 AArch64::ZPR3RegClassID,
1582 AArch64::ZPR4RegClassID};
1583 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1584 AArch64::zsub2, AArch64::zsub3};
1594 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1595 AArch64::ZPR4Mul4RegClassID};
1596 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1597 AArch64::zsub2, AArch64::zsub3};
1602 const unsigned RegClassIDs[],
1603 const unsigned SubRegs[]) {
1606 if (Regs.
size() == 1)
1617 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1620 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1621 Ops.push_back(Regs[i]);
1622 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1626 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1630void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1633 EVT VT =
N->getValueType(0);
1635 unsigned ExtOff = isExt;
1638 unsigned Vec0Off = ExtOff + 1;
1644 Ops.push_back(
N->getOperand(1));
1645 Ops.push_back(RegSeq);
1646 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1647 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1650static std::tuple<SDValue, SDValue>
1671 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1676 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1678 return std::make_tuple(
1683void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1688 SDValue AUTDisc =
N->getOperand(3);
1691 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1693 SDValue AUTAddrDisc, AUTConstDisc;
1694 std::tie(AUTConstDisc, AUTAddrDisc) =
1698 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1700 if (
N->getNumOperands() > 4)
1701 Ops.push_back(
N->getOperand(4));
1704 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1705 ReplaceNode(
N, AUT);
1707 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1708 AArch64::X16, Val,
SDValue());
1711 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1712 ReplaceNode(
N, AUT);
1716void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1726 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1731 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1732 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1734 SDValue AUTAddrDisc, AUTConstDisc;
1735 std::tie(AUTConstDisc, AUTAddrDisc) =
1738 SDValue PACAddrDisc, PACConstDisc;
1739 std::tie(PACConstDisc, PACAddrDisc) =
1742 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1743 AArch64::X16, Val,
SDValue());
1746 SDValue Addend =
N->getOperand(OffsetBase + 6);
1747 SDValue IncomingChain =
N->getOperand(0);
1748 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1749 PACKey, PACConstDisc, PACAddrDisc,
1750 Addend, IncomingChain, X16Copy.
getValue(1)};
1752 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1753 MVT::i64, MVT::Other,
Ops);
1754 ReplaceNode(
N, AUTRELLOADPAC);
1756 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1757 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1759 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1760 ReplaceNode(
N, AUTPAC);
1764bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1766 if (
LD->isUnindexed())
1768 EVT VT =
LD->getMemoryVT();
1769 EVT DstVT =
N->getValueType(0);
1773 int OffsetVal = (int)
OffsetOp->getZExtValue();
1778 unsigned Opcode = 0;
1781 bool InsertTo64 =
false;
1783 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1784 else if (VT == MVT::i32) {
1786 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1788 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1790 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1796 }
else if (VT == MVT::i16) {
1798 if (DstVT == MVT::i64)
1799 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1801 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1803 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1804 InsertTo64 = DstVT == MVT::i64;
1809 }
else if (VT == MVT::i8) {
1811 if (DstVT == MVT::i64)
1812 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1814 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1816 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1817 InsertTo64 = DstVT == MVT::i64;
1822 }
else if (VT == MVT::f16) {
1823 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1824 }
else if (VT == MVT::bf16) {
1825 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1826 }
else if (VT == MVT::f32) {
1827 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1828 }
else if (VT == MVT::f64 ||
1830 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1832 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1834 if (IsPre || OffsetVal != 8)
1838 Opcode = AArch64::LD1Onev8b_POST;
1841 Opcode = AArch64::LD1Onev4h_POST;
1844 Opcode = AArch64::LD1Onev2s_POST;
1847 Opcode = AArch64::LD1Onev1d_POST;
1853 if (IsPre || OffsetVal != 16)
1857 Opcode = AArch64::LD1Onev16b_POST;
1860 Opcode = AArch64::LD1Onev8h_POST;
1863 Opcode = AArch64::LD1Onev4s_POST;
1866 Opcode = AArch64::LD1Onev2d_POST;
1878 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1879 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1881 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1891 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1892 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1893 MVT::i64, LoadedVal, SubReg),
1897 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1900 CurDAG->RemoveDeadNode(
N);
1904void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1905 unsigned SubRegIdx) {
1907 EVT VT =
N->getValueType(0);
1913 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1915 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1917 for (
unsigned i = 0; i < NumVecs; ++i)
1919 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1926 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1930 CurDAG->RemoveDeadNode(
N);
1933void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1934 unsigned Opc,
unsigned SubRegIdx) {
1936 EVT VT =
N->getValueType(0);
1943 const EVT ResTys[] = {MVT::i64,
1944 MVT::Untyped, MVT::Other};
1946 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1954 ReplaceUses(
SDValue(
N, 0), SuperReg);
1956 for (
unsigned i = 0; i < NumVecs; ++i)
1958 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1966 CurDAG->RemoveDeadNode(
N);
1972std::tuple<unsigned, SDValue, SDValue>
1973AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1979 SDValue NewOffset = OldOffset;
1981 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1982 N, OldBase, NewBase, NewOffset);
1986 const bool IsRegReg =
1987 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1990 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
2003template <SelectTypeKind Kind>
2015 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2020 if (EltVT != MVT::i1)
2024 if (EltVT == MVT::bf16)
2026 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2056void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2059 if (
Imm->getZExtValue() > 1)
2063 EVT VT =
N->getValueType(0);
2065 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2068 for (
unsigned I = 0;
I < 2; ++
I)
2069 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2070 AArch64::psub0 +
I,
DL, VT, SuperReg));
2072 CurDAG->RemoveDeadNode(
N);
2075void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2077 EVT VT =
N->getValueType(0);
2081 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2084 for (
unsigned I = 0;
I < 2; ++
I)
2085 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2086 AArch64::psub0 +
I,
DL, VT, SuperReg));
2088 CurDAG->RemoveDeadNode(
N);
2091void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2093 EVT VT =
N->getValueType(0);
2097 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2099 for (
unsigned i = 0; i < NumVecs; ++i)
2100 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2101 AArch64::zsub0 + i,
DL, VT, SuperReg));
2103 CurDAG->RemoveDeadNode(
N);
2106void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2109 EVT VT =
N->getValueType(0);
2111 Ops.push_back(
N->getOperand(0));
2114 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2117 for (
unsigned i = 0; i < NumVecs; ++i)
2118 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2119 AArch64::zsub0 + i,
DL, VT, SuperReg));
2122 unsigned ChainIdx = NumVecs;
2124 CurDAG->RemoveDeadNode(
N);
2127void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2132 assert(Opcode != 0 &&
"Unexpected opcode");
2135 EVT VT =
N->getValueType(0);
2136 SDUse *OpsIter =
N->op_begin() + 1;
2139 auto GetMultiVecOperand = [&]() {
2142 return createZMulTuple(Regs);
2146 Ops.push_back(*OpsIter++);
2148 Ops.push_back(GetMultiVecOperand());
2150 Ops.push_back(GetMultiVecOperand());
2152 Ops.push_back(*OpsIter++);
2155 Ops.append(OpsIter,
N->op_end());
2157 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2159 for (
unsigned i = 0; i < NumVecs; ++i)
2160 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2161 AArch64::zsub0 + i,
DL, VT, SuperReg));
2163 CurDAG->RemoveDeadNode(
N);
2166void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2167 unsigned Scale,
unsigned Opc_ri,
2168 unsigned Opc_rr,
bool IsIntr) {
2169 assert(Scale < 5 &&
"Invalid scaling value.");
2171 EVT VT =
N->getValueType(0);
2178 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2179 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2185 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2187 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2189 for (
unsigned i = 0; i < NumVecs; ++i)
2190 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2191 AArch64::zsub0 + i,
DL, VT, SuperReg));
2194 unsigned ChainIdx = NumVecs;
2196 CurDAG->RemoveDeadNode(
N);
2199void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2204 assert(Scale < 4 &&
"Invalid scaling value.");
2206 EVT VT =
N->getValueType(0);
2214 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2220 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2222 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2224 for (
unsigned i = 0; i < NumVecs; ++i)
2225 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2226 AArch64::zsub0 + i,
DL, VT, SuperReg));
2229 unsigned ChainIdx = NumVecs;
2231 CurDAG->RemoveDeadNode(
N);
2234void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2236 if (
N->getValueType(0) != MVT::nxv4f32)
2238 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2241void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2242 unsigned NumOutVecs,
2246 if (
Imm->getZExtValue() > MaxImm)
2250 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2256 EVT VT =
Node->getValueType(0);
2259 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2262 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2263 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2264 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2267 unsigned ChainIdx = NumOutVecs;
2269 CurDAG->RemoveDeadNode(Node);
2272void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2273 unsigned NumOutVecs,
2276 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2281 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2285 EVT VT =
Node->getValueType(0);
2288 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2291 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2292 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2293 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2296 unsigned ChainIdx = NumOutVecs;
2298 CurDAG->RemoveDeadNode(Node);
2301void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2304 EVT VT =
N->getValueType(0);
2307 SDValue Zd = createZMulTuple(Regs);
2308 SDValue Zn =
N->getOperand(1 + NumVecs);
2309 SDValue Zm =
N->getOperand(2 + NumVecs);
2315 for (
unsigned i = 0; i < NumVecs; ++i)
2316 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2317 AArch64::zsub0 + i,
DL, VT, SuperReg));
2319 CurDAG->RemoveDeadNode(
N);
2349template <
unsigned MaxIdx,
unsigned Scale>
2350void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2351 unsigned BaseReg,
unsigned Op) {
2352 unsigned TileNum = 0;
2353 if (BaseReg != AArch64::ZA)
2354 TileNum =
N->getConstantOperandVal(2);
2360 if (BaseReg == AArch64::ZA)
2365 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2369 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2371 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2373 EVT VT =
N->getValueType(0);
2374 for (
unsigned I = 0;
I < NumVecs; ++
I)
2376 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2379 unsigned ChainIdx = NumVecs;
2381 CurDAG->RemoveDeadNode(
N);
2384void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2385 unsigned Op,
unsigned MaxIdx,
2386 unsigned Scale,
unsigned BaseReg) {
2391 if (BaseReg != AArch64::ZA)
2395 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2402 if (BaseReg != AArch64::ZA )
2403 Ops.push_back(
N->getOperand(2));
2406 Ops.push_back(
N->getOperand(0));
2407 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2409 EVT VT =
N->getValueType(0);
2410 for (
unsigned I = 0;
I < NumVecs; ++
I)
2412 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2416 unsigned ChainIdx = NumVecs;
2418 CurDAG->RemoveDeadNode(
N);
2421void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2422 unsigned NumOutVecs,
2426 EVT VT =
N->getValueType(0);
2427 unsigned NumInVecs =
N->getNumOperands() - 1;
2431 assert((NumInVecs == 2 || NumInVecs == 4) &&
2432 "Don't know how to handle multi-register input!");
2434 Ops.push_back(createZMulTuple(Regs));
2437 for (
unsigned I = 0;
I < NumInVecs;
I++)
2438 Ops.push_back(
N->getOperand(1 +
I));
2441 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2444 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2445 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2446 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2447 CurDAG->RemoveDeadNode(
N);
2450void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2453 EVT VT =
N->getOperand(2)->getValueType(0);
2461 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2470void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2471 unsigned Scale,
unsigned Opc_rr,
2477 SDValue RegSeq = createZTuple(Regs);
2483 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2484 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2490 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2498 const DataLayout &
DL = CurDAG->getDataLayout();
2499 const TargetLowering *TLI = getTargetLowering();
2503 int FI = FINode->getIndex();
2505 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2512void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2515 EVT VT =
N->getOperand(2)->getValueType(0);
2516 const EVT ResTys[] = {MVT::i64,
2528 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2572void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2575 EVT VT =
N->getValueType(0);
2587 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2589 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2591 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2593 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2597 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2598 AArch64::qsub2, AArch64::qsub3 };
2599 for (
unsigned i = 0; i < NumVecs; ++i) {
2600 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2607 CurDAG->RemoveDeadNode(
N);
2610void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2613 EVT VT =
N->getValueType(0);
2625 const EVT ResTys[] = {MVT::i64,
2628 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2631 CurDAG->getTargetConstant(LaneNo, dl,
2636 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2648 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2649 AArch64::qsub2, AArch64::qsub3 };
2650 for (
unsigned i = 0; i < NumVecs; ++i) {
2651 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2661 CurDAG->RemoveDeadNode(
N);
2664void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2667 EVT VT =
N->getOperand(2)->getValueType(0);
2679 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2681 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2683 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2692void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2695 EVT VT =
N->getOperand(2)->getValueType(0);
2707 const EVT ResTys[] = {MVT::i64,
2710 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2712 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2716 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2727 unsigned &LSB,
unsigned &MSB,
2728 unsigned NumberOfIgnoredLowBits,
2729 bool BiggerPattern) {
2731 "N must be a AND operation to call this function");
2733 EVT VT =
N->getValueType(0);
2738 assert((VT == MVT::i32 || VT == MVT::i64) &&
2739 "Type checking must have been done before calling this function");
2753 const SDNode *Op0 =
N->getOperand(0).getNode();
2760 if (AndImm & (AndImm + 1))
2763 bool ClampMSB =
false;
2783 ClampMSB = (VT == MVT::i32);
2784 }
else if (BiggerPattern) {
2790 Opd0 =
N->getOperand(0);
2796 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2799 <<
": Found large shift immediate, this should not happen\n"));
2813 MSB = MSB > 31 ? 31 : MSB;
2815 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2820 SDValue &Opd0,
unsigned &Immr,
2824 EVT VT =
N->getValueType(0);
2826 assert((VT == MVT::i32 || VT == MVT::i64) &&
2827 "Type checking must have been done before calling this function");
2831 Op =
Op->getOperand(0);
2832 VT =
Op->getValueType(0);
2841 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2845 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2846 Opd0 =
Op.getOperand(0);
2848 Imms = ShiftImm + Width - 1;
2876 Opd0 =
N->getOperand(0).getOperand(0);
2886 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2893 unsigned &Immr,
unsigned &Imms,
2894 bool BiggerPattern) {
2896 "N must be a SHR/SRA operation to call this function");
2898 EVT VT =
N->getValueType(0);
2903 assert((VT == MVT::i32 || VT == MVT::i64) &&
2904 "Type checking must have been done before calling this function");
2914 Opd0 =
N->getOperand(0).getOperand(0);
2915 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2921 Opd0 =
N->getOperand(0).getOperand(0);
2924 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2925 }
else if (BiggerPattern) {
2929 Opd0 =
N->getOperand(0);
2938 <<
": Found large shift immediate, this should not happen\n"));
2947 "bad amount in shift node!");
2948 int immr = SrlImm - ShlImm;
2953 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2955 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2959bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2962 EVT VT =
N->getValueType(0);
2963 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2964 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2975 unsigned Immr = ShiftImm;
2977 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2978 CurDAG->getTargetConstant(Imms, dl, VT)};
2979 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2984 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2985 unsigned NumberOfIgnoredLowBits = 0,
2986 bool BiggerPattern =
false) {
2987 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2990 switch (
N->getOpcode()) {
2992 if (!
N->isMachineOpcode())
2997 NumberOfIgnoredLowBits, BiggerPattern);
3006 unsigned NOpc =
N->getMachineOpcode();
3010 case AArch64::SBFMWri:
3011 case AArch64::UBFMWri:
3012 case AArch64::SBFMXri:
3013 case AArch64::UBFMXri:
3015 Opd0 =
N->getOperand(0);
3016 Immr =
N->getConstantOperandVal(1);
3017 Imms =
N->getConstantOperandVal(2);
3024bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3025 unsigned Opc, Immr, Imms;
3030 EVT VT =
N->getValueType(0);
3035 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3036 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3037 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3039 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3040 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3046 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3047 CurDAG->getTargetConstant(Imms, dl, VT)};
3048 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3057 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3058 assert((VT == MVT::i32 || VT == MVT::i64) &&
3059 "i32 or i64 mask type expected!");
3063 APInt SignificantDstMask =
3067 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3068 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3101 APInt OpUsefulBits(UsefulBits);
3105 OpUsefulBits <<= MSB - Imm + 1;
3110 OpUsefulBits <<= Imm;
3112 OpUsefulBits <<= MSB + 1;
3115 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3121 UsefulBits &= OpUsefulBits;
3138 APInt Mask(UsefulBits);
3139 Mask.clearAllBits();
3147 Mask.lshrInPlace(ShiftAmt);
3153 Mask.lshrInPlace(ShiftAmt);
3169 APInt OpUsefulBits(UsefulBits);
3183 OpUsefulBits <<= Width;
3186 if (
Op.getOperand(1) == Orig) {
3188 Mask = ResultUsefulBits & OpUsefulBits;
3192 if (
Op.getOperand(0) == Orig)
3194 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3200 OpUsefulBits <<= Width;
3202 OpUsefulBits <<= LSB;
3204 if (
Op.getOperand(1) == Orig) {
3206 Mask = ResultUsefulBits & OpUsefulBits;
3207 Mask.lshrInPlace(LSB);
3210 if (
Op.getOperand(0) == Orig)
3211 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3228 case AArch64::ANDSWri:
3229 case AArch64::ANDSXri:
3230 case AArch64::ANDWri:
3231 case AArch64::ANDXri:
3235 case AArch64::UBFMWri:
3236 case AArch64::UBFMXri:
3239 case AArch64::ORRWrs:
3240 case AArch64::ORRXrs:
3245 case AArch64::BFMWri:
3246 case AArch64::BFMXri:
3249 case AArch64::STRBBui:
3250 case AArch64::STURBBi:
3256 case AArch64::STRHHui:
3257 case AArch64::STURHHi:
3270 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3272 UsefulBits =
APInt(Bitwidth, 0);
3281 UsersUsefulBits |= UsefulBitsForUse;
3286 UsefulBits &= UsersUsefulBits;
3296 EVT VT =
Op.getValueType();
3299 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3302 if (ShlAmount > 0) {
3305 UBFMOpc, dl, VT,
Op,
3310 assert(ShlAmount < 0 &&
"expected right shift");
3311 int ShrAmount = -ShlAmount;
3323 const uint64_t NonZeroBits,
3330 const uint64_t NonZeroBits,
3337 bool BiggerPattern,
SDValue &Src,
3338 int &DstLSB,
int &Width) {
3339 EVT VT =
Op.getValueType();
3348 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3352 switch (
Op.getOpcode()) {
3357 NonZeroBits, Src, DstLSB, Width);
3360 NonZeroBits, Src, DstLSB, Width);
3373 EVT VT =
Op.getValueType();
3374 assert((VT == MVT::i32 || VT == MVT::i64) &&
3375 "Caller guarantees VT is one of i32 or i64");
3388 assert((~AndImm & NonZeroBits) == 0 &&
3389 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3418 if (!BiggerPattern && !AndOp0.
hasOneUse())
3437 <<
"Found large Width in bit-field-positioning -- this indicates no "
3438 "proper combining / constant folding was performed\n");
3447 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3462 "Op.getNode() should be a SHL node to call this function");
3464 "Op.getNode() should shift ShlImm to call this function");
3471 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3495 EVT VT =
Op.getValueType();
3496 assert((VT == MVT::i32 || VT == MVT::i64) &&
3497 "Caller guarantees that type is i32 or i64");
3504 if (!BiggerPattern && !
Op.hasOneUse())
3513 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3521 assert(VT == MVT::i32 || VT == MVT::i64);
3532 EVT VT =
N->getValueType(0);
3533 if (VT != MVT::i32 && VT != MVT::i64)
3551 if (!
And.hasOneUse() ||
3561 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3568 if ((OrImm & NotKnownZero) != 0) {
3580 unsigned ImmS = Width - 1;
3586 bool IsBFI = LSB != 0;
3591 unsigned OrChunks = 0, BFIChunks = 0;
3592 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3593 if (((OrImm >> Shift) & 0xFFFF) != 0)
3595 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3598 if (BFIChunks > OrChunks)
3604 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3612 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3621 if (!Dst.hasOneUse())
3624 EVT VT = Dst.getValueType();
3625 assert((VT == MVT::i32 || VT == MVT::i64) &&
3626 "Caller should guarantee that VT is one of i32 or i64");
3654 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3655 unsigned MaskWidth =
3658 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3664 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3665 ShiftedOperand =
SDValue(UBFMNode, 0);
3694 const bool BiggerPattern) {
3695 EVT VT =
N->getValueType(0);
3696 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3697 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3698 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3699 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3700 assert((VT == MVT::i32 || VT == MVT::i64) &&
3701 "Expect result type to be i32 or i64 since N is combinable to BFM");
3708 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3711 if (BiggerPattern) {
3734 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3796 EVT VT =
N->getValueType(0);
3797 if (VT != MVT::i32 && VT != MVT::i64)
3805 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3806 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3826 for (
int I = 0;
I < 4; ++
I) {
3829 unsigned ImmR, ImmS;
3830 bool BiggerPattern =
I / 2;
3831 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3833 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3839 NumberOfIgnoredLowBits, BiggerPattern)) {
3842 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3843 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3848 Width = ImmS - ImmR + 1;
3859 Src, DstLSB, Width)) {
3867 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3877 APInt BitsToBeInserted =
3880 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3904 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3937 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3939 if (Src->hasOneUse() &&
3942 Src = Src->getOperand(0);
3952 unsigned ImmS = Width - 1;
3958 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3966bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3975 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3988bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3992 EVT VT =
N->getValueType(0);
3993 if (VT != MVT::i32 && VT != MVT::i64)
3999 Op0, DstLSB, Width))
4005 unsigned ImmS = Width - 1;
4008 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4009 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4010 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4011 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4017bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4018 EVT VT =
N->getValueType(0);
4021 switch (
N->getOpcode()) {
4023 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4026 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4029 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4032 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4040 if (VT == MVT::i32) {
4043 }
else if (VT == MVT::i64) {
4049 SDValue ShiftAmt =
N->getOperand(1);
4069 (Add0Imm %
Size == 0)) {
4075 if (SubVT == MVT::i32) {
4076 NegOpc = AArch64::SUBWrr;
4077 ZeroReg = AArch64::WZR;
4079 assert(SubVT == MVT::i64);
4080 NegOpc = AArch64::SUBXrr;
4081 ZeroReg = AArch64::XZR;
4084 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4085 MachineSDNode *Neg =
4086 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4087 NewShiftAmt =
SDValue(Neg, 0);
4095 if (SubVT == MVT::i32) {
4096 NotOpc = AArch64::ORNWrr;
4097 ZeroReg = AArch64::WZR;
4099 assert(SubVT == MVT::i64);
4100 NotOpc = AArch64::ORNXrr;
4101 ZeroReg = AArch64::XZR;
4104 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4105 MachineSDNode *
Not =
4106 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4107 NewShiftAmt =
SDValue(Not, 0);
4128 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4129 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4130 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4131 NewShiftAmt, SubReg);
4132 NewShiftAmt =
SDValue(Ext, 0);
4136 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4143 bool isReciprocal) {
4146 FVal = CN->getValueAPF();
4149 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4159 if (
unsigned FBits =
4172 bool isReciprocal) {
4173 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4174 N.getValueType().getScalarSizeInBits() ==
4175 N.getOperand(0).getValueType().getScalarSizeInBits())
4176 N =
N.getOperand(0);
4178 auto ImmToFloat = [RegWidth](
APInt Imm) {
4192 switch (
N->getOpcode()) {
4193 case AArch64ISD::MOVIshift:
4194 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4195 <<
N.getConstantOperandVal(1)));
4197 case AArch64ISD::FMOV:
4198 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4200 case AArch64ISD::DUP:
4202 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4210 if (
unsigned FBits =
4219bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4220 unsigned RegWidth) {
4225bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4226 unsigned RegWidth) {
4228 CurDAG,
N, FixedPos, RegWidth,
false);
4231bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(
SDValue N,
4233 unsigned RegWidth) {
4235 CurDAG,
N, FixedPos, RegWidth,
true);
4238bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4240 unsigned RegWidth) {
4250 RegString.
split(Fields,
':');
4252 if (Fields.
size() == 1)
4256 &&
"Invalid number of fields in read register string");
4259 bool AllIntFields =
true;
4263 AllIntFields &= !
Field.getAsInteger(10, IntField);
4264 Ops.push_back(IntField);
4268 "Unexpected non-integer value in special register string.");
4273 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) | (
Ops[3] << 3) |
4281bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4283 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4286 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4288 unsigned Opcode64Bit = AArch64::MRS;
4293 const auto *TheReg =
4294 AArch64SysReg::lookupSysRegByName(RegString->getString());
4295 if (TheReg && TheReg->Readable &&
4296 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4297 Imm = TheReg->Encoding;
4303 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4304 Opcode64Bit = AArch64::ADR;
4313 RegString->getString());
4314 unsigned PseudoOp = 0;
4315 if (AArch64::GPR64RegClass.
contains(PReg))
4316 PseudoOp = AArch64::READ_REGISTER_GPR64;
4317 else if (AArch64::FPR64RegClass.
contains(PReg))
4318 PseudoOp = AArch64::READ_REGISTER_FPR64;
4319 if (!ReadIs128Bit && PseudoOp &&
N->getValueType(0) == MVT::i64) {
4320 CurDAG->SelectNodeTo(
N, PseudoOp, MVT::i64, MVT::Other,
4321 {CurDAG->getTargetConstant(PReg,
DL, MVT::i32),
4330 SDValue InChain =
N->getOperand(0);
4331 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4332 if (!ReadIs128Bit) {
4333 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4334 {SysRegImm, InChain});
4336 SDNode *MRRS = CurDAG->getMachineNode(
4338 {MVT::Untyped , MVT::Other },
4339 {SysRegImm, InChain});
4343 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4345 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4351 ReplaceUses(
SDValue(
N, 2), OutChain);
4360bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4362 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4365 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4367 if (!WriteIs128Bit) {
4373 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4376 "Expected a constant integer expression.");
4377 unsigned Reg = PMapper->Encoding;
4378 uint64_t Immed =
N->getConstantOperandVal(2);
4379 CurDAG->SelectNodeTo(
4380 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4381 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4387 if (trySelectPState(
4388 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4389 AArch64::MSRpstateImm4))
4391 if (trySelectPState(
4392 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4393 AArch64::MSRpstateImm1))
4402 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4403 if (TheReg && TheReg->Writeable &&
4404 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4405 Imm = TheReg->Encoding;
4415 RegString->getString());
4416 bool IsGPR = AArch64::GPR64RegClass.contains(PReg);
4417 bool IsFPR = AArch64::FPR64RegClass.contains(PReg);
4418 if (!WriteIs128Bit && (IsGPR || IsFPR) &&
4419 N->getOperand(2).getValueType() == MVT::i64) {
4421 CurDAG->getCopyToReg(
N->getOperand(0),
DL, PReg,
N->getOperand(2));
4422 SDValue RegOp = CurDAG->getRegister(PReg, MVT::i64);
4423 SDNode *FakeUse = CurDAG->getMachineNode(TargetOpcode::FAKE_USE,
DL,
4424 MVT::Other, {RegOp,
Copy});
4426 CurDAG->RemoveDeadNode(
N);
4434 if (!WriteIs128Bit) {
4435 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4436 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4437 N->getOperand(2), InChain);
4441 SDNode *Pair = CurDAG->getMachineNode(
4442 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4443 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4446 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4448 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4450 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4451 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4459bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4464 if (Subtarget->hasLSE())
return false;
4466 if (MemTy == MVT::i8)
4467 Opcode = AArch64::CMP_SWAP_8;
4468 else if (MemTy == MVT::i16)
4469 Opcode = AArch64::CMP_SWAP_16;
4470 else if (MemTy == MVT::i32)
4471 Opcode = AArch64::CMP_SWAP_32;
4472 else if (MemTy == MVT::i64)
4473 Opcode = AArch64::CMP_SWAP_64;
4477 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4478 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4480 SDNode *CmpSwap = CurDAG->getMachineNode(
4482 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4489 CurDAG->RemoveDeadNode(
N);
4494bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4495 SDValue &Shift,
bool Negate) {
4502 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4505bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4514 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4521 if ((Val & ~0xff) == 0) {
4522 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4527 if ((Val & ~0xff00) == 0) {
4528 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4540bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4564 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4565 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4572 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4573 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4577 if (Val <= 65280 && Val % 256 == 0) {
4578 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4579 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4590bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4600 int32_t ImmVal, ShiftVal;
4605 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4606 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4610bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4612 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4616bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4619 if (ImmVal >= -128 && ImmVal < 128) {
4620 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4626bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4628 uint64_t ImmVal = CNode->getZExtValue();
4638 ImmVal &= 0xFFFFFFFF;
4647 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4654bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4658 ImmVal = CI->getZExtValue();
4660 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4671 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4680bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4681 uint64_t
High,
bool AllowSaturation,
4684 uint64_t ImmVal = CN->getZExtValue();
4691 if (ImmVal >
High) {
4692 if (!AllowSaturation)
4697 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4704bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4718 const TargetLowering *TLI = getTargetLowering();
4721 SDValue FiOp = CurDAG->getTargetFrameIndex(
4723 int TagOffset =
N->getConstantOperandVal(3);
4725 SDNode *Out = CurDAG->getMachineNode(
4726 AArch64::TAGPstack,
DL, MVT::i64,
4727 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4728 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4729 ReplaceNode(
N, Out);
4733void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4735 "llvm.aarch64.tagp third argument must be an immediate");
4736 if (trySelectStackSlotTagP(
N))
4743 int TagOffset =
N->getConstantOperandVal(3);
4744 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4745 {
N->getOperand(1),
N->getOperand(2)});
4746 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4747 {
SDValue(N1, 0),
N->getOperand(2)});
4748 SDNode *N3 = CurDAG->getMachineNode(
4749 AArch64::ADDG,
DL, MVT::i64,
4750 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4751 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4755bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4759 if (
N->getConstantOperandVal(2) != 0)
4761 if (!
N->getOperand(0).isUndef())
4765 EVT VT =
N->getValueType(0);
4766 EVT InVT =
N->getOperand(1).getValueType();
4777 "Expected to insert into a packed scalable vector!");
4780 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4781 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4782 N->getOperand(1), RC));
4786bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4790 if (
N->getConstantOperandVal(1) != 0)
4794 EVT VT =
N->getValueType(0);
4795 EVT InVT =
N->getOperand(0).getValueType();
4806 "Expected to extract from a packed scalable vector!");
4809 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4810 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4811 N->getOperand(0), RC));
4815bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4821 EVT VT =
N->getValueType(0);
4834 (Subtarget->hasSVE2() ||
4835 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4836 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4839 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4843 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4844 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4845 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4852 bool IsXOROperand =
true;
4854 IsXOROperand =
false;
4860 APInt ShlAmt, ShrAmt;
4868 if (!IsXOROperand) {
4870 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4873 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4874 SDNode *SubRegToReg =
4875 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4886 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4887 AArch64::XAR_ZZZI_D})) {
4888 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4913 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4923 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4931 bool IsXOROperand =
true;
4933 IsXOROperand =
false;
4936 R1 =
XOR.getOperand(0);
4937 R2 =
XOR.getOperand(1);
4947 if (ShAmt + HsAmt != VTSizeInBits)
4950 if (!IsXOROperand) {
4953 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4962 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4968 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4969 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4971 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4974 if (
R2.getValueType() == VT)
4975 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4980 SDValue SubReg = CurDAG->getTargetConstant(
4983 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4988 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4994 SDNode *XAR =
nullptr;
4998 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4999 AArch64::XAR_ZZZI_D}))
5000 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
5002 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
5005 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
5011 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
5012 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
5015 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5016 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5019 SDValue SubReg = CurDAG->getTargetConstant(
5022 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5026 ReplaceNode(
N, XAR);
5030void AArch64DAGToDAGISel::Select(SDNode *Node) {
5032 if (
Node->isMachineOpcode()) {
5034 Node->setNodeId(-1);
5039 EVT VT =
Node->getValueType(0);
5041 switch (
Node->getOpcode()) {
5046 if (SelectCMP_SWAP(Node))
5051 case AArch64ISD::MRRS:
5052 if (tryReadRegister(Node))
5057 case AArch64ISD::MSRR:
5058 if (tryWriteRegister(Node))
5065 if (tryIndexedLoad(Node))
5074 if (tryBitfieldExtractOp(Node))
5076 if (tryBitfieldInsertInZeroOp(Node))
5081 if (tryShiftAmountMod(Node))
5086 if (tryBitfieldExtractOpFromSExt(Node))
5091 if (tryBitfieldInsertOp(Node))
5093 if (trySelectXAR(Node))
5098 if (trySelectCastScalableToFixedLengthVector(Node))
5104 if (trySelectCastFixedLengthToScalableVector(Node))
5113 if (ConstNode->
isZero()) {
5114 if (VT == MVT::i32) {
5116 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5117 ReplaceNode(Node,
New.getNode());
5119 }
else if (VT == MVT::i64) {
5121 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5122 ReplaceNode(Node,
New.getNode());
5133 const TargetLowering *TLI = getTargetLowering();
5134 SDValue TFI = CurDAG->getTargetFrameIndex(
5137 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5138 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5139 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5143 unsigned IntNo =
Node->getConstantOperandVal(1);
5147 case Intrinsic::aarch64_gcsss: {
5151 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5153 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5154 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5155 MVT::Other, Zero,
SDValue(SS1, 0));
5156 ReplaceNode(Node, SS2);
5159 case Intrinsic::aarch64_ldaxp:
5160 case Intrinsic::aarch64_ldxp: {
5162 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5167 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5168 MVT::Other, MemAddr, Chain);
5171 MachineMemOperand *MemOp =
5174 ReplaceNode(Node, Ld);
5177 case Intrinsic::aarch64_stlxp:
5178 case Intrinsic::aarch64_stxp: {
5180 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5188 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5190 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5192 MachineMemOperand *MemOp =
5196 ReplaceNode(Node, St);
5199 case Intrinsic::aarch64_neon_ld1x2:
5200 if (VT == MVT::v8i8) {
5201 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5203 }
else if (VT == MVT::v16i8) {
5204 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5206 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5207 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5209 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5210 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5212 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5213 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5215 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5216 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5218 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5219 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5221 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5222 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5226 case Intrinsic::aarch64_neon_ld1x3:
5227 if (VT == MVT::v8i8) {
5228 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5230 }
else if (VT == MVT::v16i8) {
5231 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5233 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5234 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5236 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5237 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5239 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5240 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5242 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5243 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5245 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5246 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5248 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5249 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5253 case Intrinsic::aarch64_neon_ld1x4:
5254 if (VT == MVT::v8i8) {
5255 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5257 }
else if (VT == MVT::v16i8) {
5258 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5260 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5261 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5263 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5264 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5266 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5267 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5269 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5270 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5272 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5273 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5275 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5276 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5280 case Intrinsic::aarch64_neon_ld2:
5281 if (VT == MVT::v8i8) {
5282 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5284 }
else if (VT == MVT::v16i8) {
5285 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5287 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5288 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5290 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5291 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5293 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5294 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5296 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5297 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5299 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5300 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5302 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5303 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5307 case Intrinsic::aarch64_neon_ld3:
5308 if (VT == MVT::v8i8) {
5309 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5311 }
else if (VT == MVT::v16i8) {
5312 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5314 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5315 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5317 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5318 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5320 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5321 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5323 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5324 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5326 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5327 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5329 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5330 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5334 case Intrinsic::aarch64_neon_ld4:
5335 if (VT == MVT::v8i8) {
5336 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5338 }
else if (VT == MVT::v16i8) {
5339 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5341 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5342 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5344 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5345 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5347 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5348 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5350 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5351 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5353 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5354 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5356 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5357 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5361 case Intrinsic::aarch64_neon_ld2r:
5362 if (VT == MVT::v8i8) {
5363 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5365 }
else if (VT == MVT::v16i8) {
5366 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5368 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5369 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5371 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5372 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5374 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5375 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5377 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5378 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5380 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5381 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5383 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5384 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5388 case Intrinsic::aarch64_neon_ld3r:
5389 if (VT == MVT::v8i8) {
5390 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5392 }
else if (VT == MVT::v16i8) {
5393 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5395 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5396 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5398 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5399 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5401 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5402 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5404 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5405 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5407 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5408 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5410 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5411 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5415 case Intrinsic::aarch64_neon_ld4r:
5416 if (VT == MVT::v8i8) {
5417 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5419 }
else if (VT == MVT::v16i8) {
5420 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5422 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5423 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5425 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5426 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5428 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5429 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5431 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5432 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5434 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5435 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5437 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5438 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5442 case Intrinsic::aarch64_neon_ld2lane:
5443 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5444 SelectLoadLane(Node, 2, AArch64::LD2i8);
5446 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5447 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5448 SelectLoadLane(Node, 2, AArch64::LD2i16);
5450 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5452 SelectLoadLane(Node, 2, AArch64::LD2i32);
5454 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5456 SelectLoadLane(Node, 2, AArch64::LD2i64);
5460 case Intrinsic::aarch64_neon_ld3lane:
5461 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5462 SelectLoadLane(Node, 3, AArch64::LD3i8);
5464 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5465 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5466 SelectLoadLane(Node, 3, AArch64::LD3i16);
5468 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5470 SelectLoadLane(Node, 3, AArch64::LD3i32);
5472 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5474 SelectLoadLane(Node, 3, AArch64::LD3i64);
5478 case Intrinsic::aarch64_neon_ld4lane:
5479 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5480 SelectLoadLane(Node, 4, AArch64::LD4i8);
5482 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5483 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5484 SelectLoadLane(Node, 4, AArch64::LD4i16);
5486 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5488 SelectLoadLane(Node, 4, AArch64::LD4i32);
5490 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5492 SelectLoadLane(Node, 4, AArch64::LD4i64);
5496 case Intrinsic::aarch64_ld64b:
5497 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5499 case Intrinsic::aarch64_sve_ld2q_sret: {
5500 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5503 case Intrinsic::aarch64_sve_ld3q_sret: {
5504 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5507 case Intrinsic::aarch64_sve_ld4q_sret: {
5508 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5511 case Intrinsic::aarch64_sve_ld2_sret: {
5512 if (VT == MVT::nxv16i8) {
5513 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5516 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5517 VT == MVT::nxv8bf16) {
5518 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5521 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5522 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5525 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5526 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5532 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5533 if (VT == MVT::nxv16i8) {
5534 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5535 SelectContiguousMultiVectorLoad(
5536 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5537 else if (Subtarget->hasSVE2p1())
5538 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5543 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5544 VT == MVT::nxv8bf16) {
5545 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5546 SelectContiguousMultiVectorLoad(
5547 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5548 else if (Subtarget->hasSVE2p1())
5549 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5554 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5555 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5556 SelectContiguousMultiVectorLoad(
5557 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5558 else if (Subtarget->hasSVE2p1())
5559 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5564 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5565 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5566 SelectContiguousMultiVectorLoad(
5567 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5568 else if (Subtarget->hasSVE2p1())
5569 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5577 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5578 if (VT == MVT::nxv16i8) {
5579 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5580 SelectContiguousMultiVectorLoad(
5581 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5582 else if (Subtarget->hasSVE2p1())
5583 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5588 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5589 VT == MVT::nxv8bf16) {
5590 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5591 SelectContiguousMultiVectorLoad(
5592 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5593 else if (Subtarget->hasSVE2p1())
5594 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5599 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5600 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5601 SelectContiguousMultiVectorLoad(
5602 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5603 else if (Subtarget->hasSVE2p1())
5604 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5609 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5610 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5611 SelectContiguousMultiVectorLoad(
5612 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5613 else if (Subtarget->hasSVE2p1())
5614 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5622 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5623 if (VT == MVT::nxv16i8) {
5624 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5625 SelectContiguousMultiVectorLoad(Node, 2, 0,
5626 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5627 AArch64::LDNT1B_2Z_PSEUDO);
5628 else if (Subtarget->hasSVE2p1())
5629 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5630 AArch64::LDNT1B_2Z);
5634 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5635 VT == MVT::nxv8bf16) {
5636 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5637 SelectContiguousMultiVectorLoad(Node, 2, 1,
5638 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5639 AArch64::LDNT1H_2Z_PSEUDO);
5640 else if (Subtarget->hasSVE2p1())
5641 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5642 AArch64::LDNT1H_2Z);
5646 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5647 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5648 SelectContiguousMultiVectorLoad(Node, 2, 2,
5649 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5650 AArch64::LDNT1W_2Z_PSEUDO);
5651 else if (Subtarget->hasSVE2p1())
5652 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5653 AArch64::LDNT1W_2Z);
5657 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5658 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5659 SelectContiguousMultiVectorLoad(Node, 2, 3,
5660 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5661 AArch64::LDNT1D_2Z_PSEUDO);
5662 else if (Subtarget->hasSVE2p1())
5663 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5664 AArch64::LDNT1D_2Z);
5671 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5672 if (VT == MVT::nxv16i8) {
5673 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5674 SelectContiguousMultiVectorLoad(Node, 4, 0,
5675 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5676 AArch64::LDNT1B_4Z_PSEUDO);
5677 else if (Subtarget->hasSVE2p1())
5678 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5679 AArch64::LDNT1B_4Z);
5683 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5684 VT == MVT::nxv8bf16) {
5685 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5686 SelectContiguousMultiVectorLoad(Node, 4, 1,
5687 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5688 AArch64::LDNT1H_4Z_PSEUDO);
5689 else if (Subtarget->hasSVE2p1())
5690 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5691 AArch64::LDNT1H_4Z);
5695 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5696 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5697 SelectContiguousMultiVectorLoad(Node, 4, 2,
5698 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5699 AArch64::LDNT1W_4Z_PSEUDO);
5700 else if (Subtarget->hasSVE2p1())
5701 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5702 AArch64::LDNT1W_4Z);
5706 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5707 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5708 SelectContiguousMultiVectorLoad(Node, 4, 3,
5709 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5710 AArch64::LDNT1D_4Z_PSEUDO);
5711 else if (Subtarget->hasSVE2p1())
5712 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5713 AArch64::LDNT1D_4Z);
5720 case Intrinsic::aarch64_sve_ld3_sret: {
5721 if (VT == MVT::nxv16i8) {
5722 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5725 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5726 VT == MVT::nxv8bf16) {
5727 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5730 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5731 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5734 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5735 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5741 case Intrinsic::aarch64_sve_ld4_sret: {
5742 if (VT == MVT::nxv16i8) {
5743 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5746 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5747 VT == MVT::nxv8bf16) {
5748 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5751 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5752 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5755 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5756 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5762 case Intrinsic::aarch64_sme_read_hor_vg2: {
5763 if (VT == MVT::nxv16i8) {
5764 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5765 AArch64::MOVA_2ZMXI_H_B);
5767 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5768 VT == MVT::nxv8bf16) {
5769 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5770 AArch64::MOVA_2ZMXI_H_H);
5772 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5773 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5774 AArch64::MOVA_2ZMXI_H_S);
5776 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5777 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5778 AArch64::MOVA_2ZMXI_H_D);
5783 case Intrinsic::aarch64_sme_read_ver_vg2: {
5784 if (VT == MVT::nxv16i8) {
5785 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5786 AArch64::MOVA_2ZMXI_V_B);
5788 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5789 VT == MVT::nxv8bf16) {
5790 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5791 AArch64::MOVA_2ZMXI_V_H);
5793 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5794 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5795 AArch64::MOVA_2ZMXI_V_S);
5797 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5798 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5799 AArch64::MOVA_2ZMXI_V_D);
5804 case Intrinsic::aarch64_sme_read_hor_vg4: {
5805 if (VT == MVT::nxv16i8) {
5806 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5807 AArch64::MOVA_4ZMXI_H_B);
5809 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5810 VT == MVT::nxv8bf16) {
5811 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5812 AArch64::MOVA_4ZMXI_H_H);
5814 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5815 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5816 AArch64::MOVA_4ZMXI_H_S);
5818 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5819 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5820 AArch64::MOVA_4ZMXI_H_D);
5825 case Intrinsic::aarch64_sme_read_ver_vg4: {
5826 if (VT == MVT::nxv16i8) {
5827 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5828 AArch64::MOVA_4ZMXI_V_B);
5830 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5831 VT == MVT::nxv8bf16) {
5832 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5833 AArch64::MOVA_4ZMXI_V_H);
5835 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5836 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5837 AArch64::MOVA_4ZMXI_V_S);
5839 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5840 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5841 AArch64::MOVA_4ZMXI_V_D);
5846 case Intrinsic::aarch64_sme_read_vg1x2: {
5847 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5848 AArch64::MOVA_VG2_2ZMXI);
5851 case Intrinsic::aarch64_sme_read_vg1x4: {
5852 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5853 AArch64::MOVA_VG4_4ZMXI);
5856 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5857 if (VT == MVT::nxv16i8) {
5858 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5860 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5861 VT == MVT::nxv8bf16) {
5862 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5864 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5865 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5867 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5868 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5873 case Intrinsic::aarch64_sme_readz_vert_x2: {
5874 if (VT == MVT::nxv16i8) {
5875 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5877 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5878 VT == MVT::nxv8bf16) {
5879 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5881 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5882 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5884 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5885 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5890 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5891 if (VT == MVT::nxv16i8) {
5892 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5894 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5895 VT == MVT::nxv8bf16) {
5896 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5898 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5899 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5901 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5902 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5907 case Intrinsic::aarch64_sme_readz_vert_x4: {
5908 if (VT == MVT::nxv16i8) {
5909 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5911 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5912 VT == MVT::nxv8bf16) {
5913 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5915 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5916 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5918 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5919 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5924 case Intrinsic::aarch64_sme_readz_x2: {
5925 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5929 case Intrinsic::aarch64_sme_readz_x4: {
5930 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5934 case Intrinsic::swift_async_context_addr: {
5937 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5939 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5940 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5941 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5943 ReplaceUses(
SDValue(Node, 0), Res);
5945 CurDAG->RemoveDeadNode(Node);
5947 auto &MF = CurDAG->getMachineFunction();
5948 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5949 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5952 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5954 Node->getValueType(0),
5955 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5956 AArch64::LUTI2_4ZTZI_S}))
5958 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5961 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5963 Node->getValueType(0),
5964 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5966 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5969 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5971 Node->getValueType(0),
5972 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5973 AArch64::LUTI2_2ZTZI_S}))
5975 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5978 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5980 Node->getValueType(0),
5981 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5982 AArch64::LUTI4_2ZTZI_S}))
5984 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5987 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5988 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5991 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5993 Node->getValueType(0),
5994 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5995 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5997 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5999 Node->getValueType(0),
6000 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
6001 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6003 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
6005 Node->getValueType(0),
6006 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
6007 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6009 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
6011 Node->getValueType(0),
6012 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
6013 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6015 case Intrinsic::ptrauth_resign_load_relative:
6016 SelectPtrauthResign(Node);
6021 unsigned IntNo =
Node->getConstantOperandVal(0);
6025 case Intrinsic::aarch64_tagp:
6029 case Intrinsic::ptrauth_auth:
6030 SelectPtrauthAuth(Node);
6033 case Intrinsic::ptrauth_resign:
6034 SelectPtrauthResign(Node);
6037 case Intrinsic::aarch64_neon_tbl2:
6038 SelectTable(Node, 2,
6039 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
6042 case Intrinsic::aarch64_neon_tbl3:
6043 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
6044 : AArch64::TBLv16i8Three,
6047 case Intrinsic::aarch64_neon_tbl4:
6048 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6049 : AArch64::TBLv16i8Four,
6052 case Intrinsic::aarch64_neon_tbx2:
6053 SelectTable(Node, 2,
6054 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6057 case Intrinsic::aarch64_neon_tbx3:
6058 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6059 : AArch64::TBXv16i8Three,
6062 case Intrinsic::aarch64_neon_tbx4:
6063 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6064 : AArch64::TBXv16i8Four,
6067 case Intrinsic::aarch64_sve_srshl_single_x2:
6069 Node->getValueType(0),
6070 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6071 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6072 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6074 case Intrinsic::aarch64_sve_srshl_single_x4:
6076 Node->getValueType(0),
6077 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6078 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6079 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6081 case Intrinsic::aarch64_sve_urshl_single_x2:
6083 Node->getValueType(0),
6084 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6085 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6086 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6088 case Intrinsic::aarch64_sve_urshl_single_x4:
6090 Node->getValueType(0),
6091 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6092 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6093 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6095 case Intrinsic::aarch64_sve_srshl_x2:
6097 Node->getValueType(0),
6098 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6099 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6100 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6102 case Intrinsic::aarch64_sve_srshl_x4:
6104 Node->getValueType(0),
6105 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6106 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6107 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6109 case Intrinsic::aarch64_sve_urshl_x2:
6111 Node->getValueType(0),
6112 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6113 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6114 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6116 case Intrinsic::aarch64_sve_urshl_x4:
6118 Node->getValueType(0),
6119 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6120 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6121 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6123 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6125 Node->getValueType(0),
6126 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6127 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6128 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6130 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6132 Node->getValueType(0),
6133 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6134 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6135 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6137 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6139 Node->getValueType(0),
6140 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6141 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6142 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6144 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6146 Node->getValueType(0),
6147 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6148 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6149 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6151 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6153 Node->getValueType(0),
6154 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6155 AArch64::FSCALE_2ZZ_D}))
6156 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6158 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6160 Node->getValueType(0),
6161 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6162 AArch64::FSCALE_4ZZ_D}))
6163 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6165 case Intrinsic::aarch64_sme_fp8_scale_x2:
6167 Node->getValueType(0),
6168 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6169 AArch64::FSCALE_2Z2Z_D}))
6170 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6172 case Intrinsic::aarch64_sme_fp8_scale_x4:
6174 Node->getValueType(0),
6175 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6176 AArch64::FSCALE_4Z4Z_D}))
6177 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6179 case Intrinsic::aarch64_sve_whilege_x2:
6181 Node->getValueType(0),
6182 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6183 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6184 SelectWhilePair(Node,
Op);
6186 case Intrinsic::aarch64_sve_whilegt_x2:
6188 Node->getValueType(0),
6189 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6190 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6191 SelectWhilePair(Node,
Op);
6193 case Intrinsic::aarch64_sve_whilehi_x2:
6195 Node->getValueType(0),
6196 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6197 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6198 SelectWhilePair(Node,
Op);
6200 case Intrinsic::aarch64_sve_whilehs_x2:
6202 Node->getValueType(0),
6203 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6204 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6205 SelectWhilePair(Node,
Op);
6207 case Intrinsic::aarch64_sve_whilele_x2:
6209 Node->getValueType(0),
6210 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6211 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6212 SelectWhilePair(Node,
Op);
6214 case Intrinsic::aarch64_sve_whilelo_x2:
6216 Node->getValueType(0),
6217 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6218 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6219 SelectWhilePair(Node,
Op);
6221 case Intrinsic::aarch64_sve_whilels_x2:
6223 Node->getValueType(0),
6224 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6225 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6226 SelectWhilePair(Node,
Op);
6228 case Intrinsic::aarch64_sve_whilelt_x2:
6230 Node->getValueType(0),
6231 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6232 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6233 SelectWhilePair(Node,
Op);
6235 case Intrinsic::aarch64_sve_smax_single_x2:
6237 Node->getValueType(0),
6238 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6239 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6240 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6242 case Intrinsic::aarch64_sve_umax_single_x2:
6244 Node->getValueType(0),
6245 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6246 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6247 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6249 case Intrinsic::aarch64_sve_fmax_single_x2:
6251 Node->getValueType(0),
6252 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6253 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6254 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6256 case Intrinsic::aarch64_sve_smax_single_x4:
6258 Node->getValueType(0),
6259 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6260 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6261 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6263 case Intrinsic::aarch64_sve_umax_single_x4:
6265 Node->getValueType(0),
6266 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6267 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6268 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6270 case Intrinsic::aarch64_sve_fmax_single_x4:
6272 Node->getValueType(0),
6273 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6274 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6275 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6277 case Intrinsic::aarch64_sve_smin_single_x2:
6279 Node->getValueType(0),
6280 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6281 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6282 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6284 case Intrinsic::aarch64_sve_umin_single_x2:
6286 Node->getValueType(0),
6287 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6288 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6289 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6291 case Intrinsic::aarch64_sve_fmin_single_x2:
6293 Node->getValueType(0),
6294 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6295 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6296 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6298 case Intrinsic::aarch64_sve_smin_single_x4:
6300 Node->getValueType(0),
6301 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6302 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6303 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6305 case Intrinsic::aarch64_sve_umin_single_x4:
6307 Node->getValueType(0),
6308 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6309 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6310 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6312 case Intrinsic::aarch64_sve_fmin_single_x4:
6314 Node->getValueType(0),
6315 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6316 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6317 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6319 case Intrinsic::aarch64_sve_smax_x2:
6321 Node->getValueType(0),
6322 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6323 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6324 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6326 case Intrinsic::aarch64_sve_umax_x2:
6328 Node->getValueType(0),
6329 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6330 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6331 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6333 case Intrinsic::aarch64_sve_fmax_x2:
6335 Node->getValueType(0),
6336 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6337 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6338 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6340 case Intrinsic::aarch64_sve_smax_x4:
6342 Node->getValueType(0),
6343 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6344 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6345 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6347 case Intrinsic::aarch64_sve_umax_x4:
6349 Node->getValueType(0),
6350 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6351 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6352 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6354 case Intrinsic::aarch64_sve_fmax_x4:
6356 Node->getValueType(0),
6357 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6358 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6359 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6361 case Intrinsic::aarch64_sme_famax_x2:
6363 Node->getValueType(0),
6364 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6365 AArch64::FAMAX_2Z2Z_D}))
6366 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6368 case Intrinsic::aarch64_sme_famax_x4:
6370 Node->getValueType(0),
6371 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6372 AArch64::FAMAX_4Z4Z_D}))
6373 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6375 case Intrinsic::aarch64_sme_famin_x2:
6377 Node->getValueType(0),
6378 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6379 AArch64::FAMIN_2Z2Z_D}))
6380 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6382 case Intrinsic::aarch64_sme_famin_x4:
6384 Node->getValueType(0),
6385 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6386 AArch64::FAMIN_4Z4Z_D}))
6387 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6389 case Intrinsic::aarch64_sve_smin_x2:
6391 Node->getValueType(0),
6392 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6393 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6394 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6396 case Intrinsic::aarch64_sve_umin_x2:
6398 Node->getValueType(0),
6399 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6400 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6401 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6403 case Intrinsic::aarch64_sve_fmin_x2:
6405 Node->getValueType(0),
6406 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6407 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6408 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6410 case Intrinsic::aarch64_sve_smin_x4:
6412 Node->getValueType(0),
6413 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6414 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6415 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6417 case Intrinsic::aarch64_sve_umin_x4:
6419 Node->getValueType(0),
6420 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6421 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6422 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6424 case Intrinsic::aarch64_sve_fmin_x4:
6426 Node->getValueType(0),
6427 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6428 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6429 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6431 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6433 Node->getValueType(0),
6434 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6435 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6436 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6438 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6440 Node->getValueType(0),
6441 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6442 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6443 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6445 case Intrinsic::aarch64_sve_fminnm_single_x2:
6447 Node->getValueType(0),
6448 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6449 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6450 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6452 case Intrinsic::aarch64_sve_fminnm_single_x4:
6454 Node->getValueType(0),
6455 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6456 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6457 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6459 case Intrinsic::aarch64_sve_fscale_single_x4:
6460 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6462 case Intrinsic::aarch64_sve_fscale_single_x2:
6463 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6465 case Intrinsic::aarch64_sve_fmul_single_x4:
6467 Node->getValueType(0),
6468 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6469 AArch64::FMUL_4ZZ_D}))
6470 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6472 case Intrinsic::aarch64_sve_fmul_single_x2:
6474 Node->getValueType(0),
6475 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6476 AArch64::FMUL_2ZZ_D}))
6477 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6479 case Intrinsic::aarch64_sve_fmaxnm_x2:
6481 Node->getValueType(0),
6482 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6483 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6484 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6486 case Intrinsic::aarch64_sve_fmaxnm_x4:
6488 Node->getValueType(0),
6489 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6490 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6491 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6493 case Intrinsic::aarch64_sve_fminnm_x2:
6495 Node->getValueType(0),
6496 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6497 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6498 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6500 case Intrinsic::aarch64_sve_fminnm_x4:
6502 Node->getValueType(0),
6503 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6504 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6505 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6507 case Intrinsic::aarch64_sve_aese_lane_x2:
6508 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6510 case Intrinsic::aarch64_sve_aesd_lane_x2:
6511 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6513 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6514 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6516 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6517 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6519 case Intrinsic::aarch64_sve_aese_lane_x4:
6520 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6522 case Intrinsic::aarch64_sve_aesd_lane_x4:
6523 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6525 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6526 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6528 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6529 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6531 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6532 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6534 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6538 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6540 for (
unsigned I = 0;
I < 2;
I++)
6542 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6544 CurDAG->RemoveDeadNode(Node);
6547 case Intrinsic::aarch64_sve_fscale_x4:
6548 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6550 case Intrinsic::aarch64_sve_fscale_x2:
6551 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6553 case Intrinsic::aarch64_sve_fmul_x4:
6555 Node->getValueType(0),
6556 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6557 AArch64::FMUL_4Z4Z_D}))
6558 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6560 case Intrinsic::aarch64_sve_fmul_x2:
6562 Node->getValueType(0),
6563 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6564 AArch64::FMUL_2Z2Z_D}))
6565 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6567 case Intrinsic::aarch64_sve_fcvtzs_x2:
6568 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6570 case Intrinsic::aarch64_sve_scvtf_x2:
6571 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6573 case Intrinsic::aarch64_sve_fcvtzu_x2:
6574 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6576 case Intrinsic::aarch64_sve_ucvtf_x2:
6577 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6579 case Intrinsic::aarch64_sve_fcvtzs_x4:
6580 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6582 case Intrinsic::aarch64_sve_scvtf_x4:
6583 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6585 case Intrinsic::aarch64_sve_fcvtzu_x4:
6586 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6588 case Intrinsic::aarch64_sve_ucvtf_x4:
6589 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6591 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6592 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6594 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6595 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6597 case Intrinsic::aarch64_sve_sclamp_single_x2:
6599 Node->getValueType(0),
6600 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6601 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6602 SelectClamp(Node, 2,
Op);
6604 case Intrinsic::aarch64_sve_uclamp_single_x2:
6606 Node->getValueType(0),
6607 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6608 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6609 SelectClamp(Node, 2,
Op);
6611 case Intrinsic::aarch64_sve_fclamp_single_x2:
6613 Node->getValueType(0),
6614 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6615 AArch64::FCLAMP_VG2_2Z2Z_D}))
6616 SelectClamp(Node, 2,
Op);
6618 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6619 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6621 case Intrinsic::aarch64_sve_sclamp_single_x4:
6623 Node->getValueType(0),
6624 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6625 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6626 SelectClamp(Node, 4,
Op);
6628 case Intrinsic::aarch64_sve_uclamp_single_x4:
6630 Node->getValueType(0),
6631 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6632 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6633 SelectClamp(Node, 4,
Op);
6635 case Intrinsic::aarch64_sve_fclamp_single_x4:
6637 Node->getValueType(0),
6638 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6639 AArch64::FCLAMP_VG4_4Z4Z_D}))
6640 SelectClamp(Node, 4,
Op);
6642 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6643 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6645 case Intrinsic::aarch64_sve_add_single_x2:
6647 Node->getValueType(0),
6648 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6649 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6650 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6652 case Intrinsic::aarch64_sve_add_single_x4:
6654 Node->getValueType(0),
6655 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6656 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6657 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6659 case Intrinsic::aarch64_sve_zip_x2:
6661 Node->getValueType(0),
6662 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6663 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6664 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6666 case Intrinsic::aarch64_sve_zipq_x2:
6667 SelectUnaryMultiIntrinsic(Node, 2,
false,
6668 AArch64::ZIP_VG2_2ZZZ_Q);
6670 case Intrinsic::aarch64_sve_zip_x4:
6672 Node->getValueType(0),
6673 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6674 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6675 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6677 case Intrinsic::aarch64_sve_zipq_x4:
6678 SelectUnaryMultiIntrinsic(Node, 4,
true,
6679 AArch64::ZIP_VG4_4Z4Z_Q);
6681 case Intrinsic::aarch64_sve_uzp_x2:
6683 Node->getValueType(0),
6684 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6685 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6686 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6688 case Intrinsic::aarch64_sve_uzpq_x2:
6689 SelectUnaryMultiIntrinsic(Node, 2,
false,
6690 AArch64::UZP_VG2_2ZZZ_Q);
6692 case Intrinsic::aarch64_sve_uzp_x4:
6694 Node->getValueType(0),
6695 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6696 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6697 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6699 case Intrinsic::aarch64_sve_uzpq_x4:
6700 SelectUnaryMultiIntrinsic(Node, 4,
true,
6701 AArch64::UZP_VG4_4Z4Z_Q);
6703 case Intrinsic::aarch64_sve_sel_x2:
6705 Node->getValueType(0),
6706 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6707 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6708 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6710 case Intrinsic::aarch64_sve_sel_x4:
6712 Node->getValueType(0),
6713 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6714 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6715 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6717 case Intrinsic::aarch64_sve_frinta_x2:
6718 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6720 case Intrinsic::aarch64_sve_frinta_x4:
6721 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6723 case Intrinsic::aarch64_sve_frintm_x2:
6724 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6726 case Intrinsic::aarch64_sve_frintm_x4:
6727 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6729 case Intrinsic::aarch64_sve_frintn_x2:
6730 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6732 case Intrinsic::aarch64_sve_frintn_x4:
6733 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6735 case Intrinsic::aarch64_sve_frintp_x2:
6736 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6738 case Intrinsic::aarch64_sve_frintp_x4:
6739 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6741 case Intrinsic::aarch64_sve_sunpk_x2:
6743 Node->getValueType(0),
6744 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6745 AArch64::SUNPK_VG2_2ZZ_D}))
6746 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6748 case Intrinsic::aarch64_sve_uunpk_x2:
6750 Node->getValueType(0),
6751 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6752 AArch64::UUNPK_VG2_2ZZ_D}))
6753 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6755 case Intrinsic::aarch64_sve_sunpk_x4:
6757 Node->getValueType(0),
6758 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6759 AArch64::SUNPK_VG4_4Z2Z_D}))
6760 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6762 case Intrinsic::aarch64_sve_uunpk_x4:
6764 Node->getValueType(0),
6765 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6766 AArch64::UUNPK_VG4_4Z2Z_D}))
6767 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6769 case Intrinsic::aarch64_sve_pext_x2: {
6771 Node->getValueType(0),
6772 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6773 AArch64::PEXT_2PCI_D}))
6774 SelectPExtPair(Node,
Op);
6781 unsigned IntNo =
Node->getConstantOperandVal(1);
6782 if (
Node->getNumOperands() >= 3)
6783 VT =
Node->getOperand(2)->getValueType(0);
6787 case Intrinsic::aarch64_neon_st1x2: {
6788 if (VT == MVT::v8i8) {
6789 SelectStore(Node, 2, AArch64::ST1Twov8b);
6791 }
else if (VT == MVT::v16i8) {
6792 SelectStore(Node, 2, AArch64::ST1Twov16b);
6794 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6795 VT == MVT::v4bf16) {
6796 SelectStore(Node, 2, AArch64::ST1Twov4h);
6798 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6799 VT == MVT::v8bf16) {
6800 SelectStore(Node, 2, AArch64::ST1Twov8h);
6802 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6803 SelectStore(Node, 2, AArch64::ST1Twov2s);
6805 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6806 SelectStore(Node, 2, AArch64::ST1Twov4s);
6808 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6809 SelectStore(Node, 2, AArch64::ST1Twov2d);
6811 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6812 SelectStore(Node, 2, AArch64::ST1Twov1d);
6817 case Intrinsic::aarch64_neon_st1x3: {
6818 if (VT == MVT::v8i8) {
6819 SelectStore(Node, 3, AArch64::ST1Threev8b);
6821 }
else if (VT == MVT::v16i8) {
6822 SelectStore(Node, 3, AArch64::ST1Threev16b);
6824 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6825 VT == MVT::v4bf16) {
6826 SelectStore(Node, 3, AArch64::ST1Threev4h);
6828 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6829 VT == MVT::v8bf16) {
6830 SelectStore(Node, 3, AArch64::ST1Threev8h);
6832 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6833 SelectStore(Node, 3, AArch64::ST1Threev2s);
6835 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6836 SelectStore(Node, 3, AArch64::ST1Threev4s);
6838 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6839 SelectStore(Node, 3, AArch64::ST1Threev2d);
6841 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6842 SelectStore(Node, 3, AArch64::ST1Threev1d);
6847 case Intrinsic::aarch64_neon_st1x4: {
6848 if (VT == MVT::v8i8) {
6849 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6851 }
else if (VT == MVT::v16i8) {
6852 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6854 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6855 VT == MVT::v4bf16) {
6856 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6858 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6859 VT == MVT::v8bf16) {
6860 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6862 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6863 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6865 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6866 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6868 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6869 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6871 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6872 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6877 case Intrinsic::aarch64_neon_st2: {
6878 if (VT == MVT::v8i8) {
6879 SelectStore(Node, 2, AArch64::ST2Twov8b);
6881 }
else if (VT == MVT::v16i8) {
6882 SelectStore(Node, 2, AArch64::ST2Twov16b);
6884 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6885 VT == MVT::v4bf16) {
6886 SelectStore(Node, 2, AArch64::ST2Twov4h);
6888 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6889 VT == MVT::v8bf16) {
6890 SelectStore(Node, 2, AArch64::ST2Twov8h);
6892 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6893 SelectStore(Node, 2, AArch64::ST2Twov2s);
6895 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6896 SelectStore(Node, 2, AArch64::ST2Twov4s);
6898 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6899 SelectStore(Node, 2, AArch64::ST2Twov2d);
6901 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6902 SelectStore(Node, 2, AArch64::ST1Twov1d);
6907 case Intrinsic::aarch64_neon_st3: {
6908 if (VT == MVT::v8i8) {
6909 SelectStore(Node, 3, AArch64::ST3Threev8b);
6911 }
else if (VT == MVT::v16i8) {
6912 SelectStore(Node, 3, AArch64::ST3Threev16b);
6914 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6915 VT == MVT::v4bf16) {
6916 SelectStore(Node, 3, AArch64::ST3Threev4h);
6918 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6919 VT == MVT::v8bf16) {
6920 SelectStore(Node, 3, AArch64::ST3Threev8h);
6922 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6923 SelectStore(Node, 3, AArch64::ST3Threev2s);
6925 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6926 SelectStore(Node, 3, AArch64::ST3Threev4s);
6928 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6929 SelectStore(Node, 3, AArch64::ST3Threev2d);
6931 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6932 SelectStore(Node, 3, AArch64::ST1Threev1d);
6937 case Intrinsic::aarch64_neon_st4: {
6938 if (VT == MVT::v8i8) {
6939 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6941 }
else if (VT == MVT::v16i8) {
6942 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6944 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6945 VT == MVT::v4bf16) {
6946 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6948 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6949 VT == MVT::v8bf16) {
6950 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6952 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6953 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6955 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6956 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6958 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6959 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6961 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6962 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6967 case Intrinsic::aarch64_neon_st2lane: {
6968 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6969 SelectStoreLane(Node, 2, AArch64::ST2i8);
6971 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6972 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6973 SelectStoreLane(Node, 2, AArch64::ST2i16);
6975 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6977 SelectStoreLane(Node, 2, AArch64::ST2i32);
6979 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6981 SelectStoreLane(Node, 2, AArch64::ST2i64);
6986 case Intrinsic::aarch64_neon_st3lane: {
6987 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6988 SelectStoreLane(Node, 3, AArch64::ST3i8);
6990 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6991 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6992 SelectStoreLane(Node, 3, AArch64::ST3i16);
6994 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6996 SelectStoreLane(Node, 3, AArch64::ST3i32);
6998 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7000 SelectStoreLane(Node, 3, AArch64::ST3i64);
7005 case Intrinsic::aarch64_neon_st4lane: {
7006 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7007 SelectStoreLane(Node, 4, AArch64::ST4i8);
7009 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7010 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7011 SelectStoreLane(Node, 4, AArch64::ST4i16);
7013 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7015 SelectStoreLane(Node, 4, AArch64::ST4i32);
7017 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7019 SelectStoreLane(Node, 4, AArch64::ST4i64);
7024 case Intrinsic::aarch64_sve_st2q: {
7025 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
7028 case Intrinsic::aarch64_sve_st3q: {
7029 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
7032 case Intrinsic::aarch64_sve_st4q: {
7033 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
7036 case Intrinsic::aarch64_sve_st2: {
7037 if (VT == MVT::nxv16i8) {
7038 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
7040 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7041 VT == MVT::nxv8bf16) {
7042 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
7044 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7045 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7047 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7048 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7053 case Intrinsic::aarch64_sve_st3: {
7054 if (VT == MVT::nxv16i8) {
7055 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7057 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7058 VT == MVT::nxv8bf16) {
7059 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7061 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7062 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7064 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7065 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7070 case Intrinsic::aarch64_sve_st4: {
7071 if (VT == MVT::nxv16i8) {
7072 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7074 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7075 VT == MVT::nxv8bf16) {
7076 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7078 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7079 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7081 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7082 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7090 case AArch64ISD::LD2post: {
7091 if (VT == MVT::v8i8) {
7092 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7094 }
else if (VT == MVT::v16i8) {
7095 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7097 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7098 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7100 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7101 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7103 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7104 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7106 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7107 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7109 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7110 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7112 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7113 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7118 case AArch64ISD::LD3post: {
7119 if (VT == MVT::v8i8) {
7120 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7122 }
else if (VT == MVT::v16i8) {
7123 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7125 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7126 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7128 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7129 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7131 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7132 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7134 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7135 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7137 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7138 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7140 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7141 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7146 case AArch64ISD::LD4post: {
7147 if (VT == MVT::v8i8) {
7148 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7150 }
else if (VT == MVT::v16i8) {
7151 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7153 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7154 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7156 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7157 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7159 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7160 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7162 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7163 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7165 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7166 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7168 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7169 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7174 case AArch64ISD::LD1x2post: {
7175 if (VT == MVT::v8i8) {
7176 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7178 }
else if (VT == MVT::v16i8) {
7179 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7181 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7182 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7184 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7185 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7187 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7188 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7190 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7191 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7193 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7194 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7196 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7197 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7202 case AArch64ISD::LD1x3post: {
7203 if (VT == MVT::v8i8) {
7204 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7206 }
else if (VT == MVT::v16i8) {
7207 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7209 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7210 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7212 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7213 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7215 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7216 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7218 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7219 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7221 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7222 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7224 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7225 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7230 case AArch64ISD::LD1x4post: {
7231 if (VT == MVT::v8i8) {
7232 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7234 }
else if (VT == MVT::v16i8) {
7235 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7237 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7238 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7240 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7241 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7243 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7244 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7246 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7247 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7249 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7250 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7252 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7253 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7258 case AArch64ISD::LD1DUPpost: {
7259 if (VT == MVT::v8i8) {
7260 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7262 }
else if (VT == MVT::v16i8) {
7263 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7265 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7266 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7268 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7269 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7271 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7272 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7274 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7275 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7277 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7278 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7280 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7281 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7286 case AArch64ISD::LD2DUPpost: {
7287 if (VT == MVT::v8i8) {
7288 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7290 }
else if (VT == MVT::v16i8) {
7291 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7293 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7294 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7296 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7297 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7299 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7300 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7302 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7303 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7305 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7306 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7308 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7309 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7314 case AArch64ISD::LD3DUPpost: {
7315 if (VT == MVT::v8i8) {
7316 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7318 }
else if (VT == MVT::v16i8) {
7319 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7321 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7322 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7324 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7325 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7327 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7328 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7330 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7331 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7333 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7334 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7336 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7337 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7342 case AArch64ISD::LD4DUPpost: {
7343 if (VT == MVT::v8i8) {
7344 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7346 }
else if (VT == MVT::v16i8) {
7347 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7349 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7350 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7352 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7353 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7355 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7356 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7358 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7359 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7361 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7362 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7364 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7365 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7370 case AArch64ISD::LD1LANEpost: {
7371 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7372 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7374 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7375 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7376 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7378 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7380 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7382 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7384 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7389 case AArch64ISD::LD2LANEpost: {
7390 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7391 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7393 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7394 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7395 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7397 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7399 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7401 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7403 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7408 case AArch64ISD::LD3LANEpost: {
7409 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7410 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7412 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7413 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7414 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7416 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7418 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7420 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7422 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7427 case AArch64ISD::LD4LANEpost: {
7428 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7429 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7431 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7432 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7433 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7435 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7437 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7439 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7441 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7446 case AArch64ISD::ST2post: {
7447 VT =
Node->getOperand(1).getValueType();
7448 if (VT == MVT::v8i8) {
7449 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7451 }
else if (VT == MVT::v16i8) {
7452 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7454 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7455 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7457 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7458 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7460 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7461 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7463 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7464 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7466 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7467 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7469 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7470 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7475 case AArch64ISD::ST3post: {
7476 VT =
Node->getOperand(1).getValueType();
7477 if (VT == MVT::v8i8) {
7478 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7480 }
else if (VT == MVT::v16i8) {
7481 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7483 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7484 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7486 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7487 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7489 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7490 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7492 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7493 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7495 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7496 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7498 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7499 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7504 case AArch64ISD::ST4post: {
7505 VT =
Node->getOperand(1).getValueType();
7506 if (VT == MVT::v8i8) {
7507 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7509 }
else if (VT == MVT::v16i8) {
7510 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7512 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7513 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7515 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7516 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7518 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7519 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7521 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7522 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7524 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7525 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7527 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7528 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7533 case AArch64ISD::ST1x2post: {
7534 VT =
Node->getOperand(1).getValueType();
7535 if (VT == MVT::v8i8) {
7536 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7538 }
else if (VT == MVT::v16i8) {
7539 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7541 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7542 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7544 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7545 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7547 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7548 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7550 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7551 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7553 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7554 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7556 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7557 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7562 case AArch64ISD::ST1x3post: {
7563 VT =
Node->getOperand(1).getValueType();
7564 if (VT == MVT::v8i8) {
7565 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7567 }
else if (VT == MVT::v16i8) {
7568 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7570 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7571 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7573 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7574 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7576 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7577 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7579 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7580 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7582 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7583 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7585 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7586 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7591 case AArch64ISD::ST1x4post: {
7592 VT =
Node->getOperand(1).getValueType();
7593 if (VT == MVT::v8i8) {
7594 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7596 }
else if (VT == MVT::v16i8) {
7597 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7599 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7600 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7602 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7603 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7605 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7606 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7608 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7609 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7611 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7612 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7614 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7615 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7620 case AArch64ISD::ST2LANEpost: {
7621 VT =
Node->getOperand(1).getValueType();
7622 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7623 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7625 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7626 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7627 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7629 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7631 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7633 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7635 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7640 case AArch64ISD::ST3LANEpost: {
7641 VT =
Node->getOperand(1).getValueType();
7642 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7643 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7645 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7646 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7647 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7649 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7651 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7653 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7655 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7660 case AArch64ISD::ST4LANEpost: {
7661 VT =
Node->getOperand(1).getValueType();
7662 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7663 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7665 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7666 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7667 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7669 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7671 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7673 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7675 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7690 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7702 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7706 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7707 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7722 return MemIntr->getMemoryVT();
7729 DataVT = Load->getValueType(0);
7731 DataVT = Load->getValueType(0);
7733 DataVT = Store->getValue().getValueType();
7735 DataVT = Store->getValue().getValueType();
7742 const unsigned Opcode = Root->
getOpcode();
7746 case AArch64ISD::LD1_MERGE_ZERO:
7747 case AArch64ISD::LD1S_MERGE_ZERO:
7748 case AArch64ISD::LDNF1_MERGE_ZERO:
7749 case AArch64ISD::LDNF1S_MERGE_ZERO:
7751 case AArch64ISD::ST1_PRED:
7763 case Intrinsic::aarch64_sme_ldr:
7764 case Intrinsic::aarch64_sme_str:
7765 return MVT::nxv16i8;
7766 case Intrinsic::aarch64_sve_prf:
7771 case Intrinsic::aarch64_sve_ld2_sret:
7772 case Intrinsic::aarch64_sve_ld2q_sret:
7775 case Intrinsic::aarch64_sve_st2q:
7778 case Intrinsic::aarch64_sve_ld3_sret:
7779 case Intrinsic::aarch64_sve_ld3q_sret:
7782 case Intrinsic::aarch64_sve_st3q:
7785 case Intrinsic::aarch64_sve_ld4_sret:
7786 case Intrinsic::aarch64_sve_ld4q_sret:
7789 case Intrinsic::aarch64_sve_st4q:
7792 case Intrinsic::aarch64_sve_ld1udq:
7793 case Intrinsic::aarch64_sve_st1dq:
7794 return EVT(MVT::nxv1i64);
7795 case Intrinsic::aarch64_sve_ld1uwq:
7796 case Intrinsic::aarch64_sve_st1wq:
7797 return EVT(MVT::nxv1i32);
7804template <
int64_t Min,
int64_t Max>
7805bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7809 const DataLayout &
DL = CurDAG->getDataLayout();
7810 const MachineFrameInfo &MFI = MF->getFrameInfo();
7818 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7832 int64_t MulImm = std::numeric_limits<int64_t>::max();
7836 int64_t ByteOffset =
C->getSExtValue();
7837 const auto KnownVScale =
7840 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7843 MulImm = ByteOffset / KnownVScale;
7850 if ((MulImm % MemWidthBytes) != 0)
7853 int64_t
Offset = MulImm / MemWidthBytes;
7857 Base =
N.getOperand(0);
7866 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7872bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7891 int64_t ImmOff =
C->getSExtValue();
7892 unsigned Size = 1 << Scale;
7901 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7903 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7914 if (
C->getZExtValue() == Scale) {
7923bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7924 const AArch64TargetLowering *TLI =
7925 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7930bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7931 return N.getValueType().isScalableVectorOf(MVT::i1);
7934bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7939 int64_t ImmOff =
C->getSExtValue();
7940 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7941 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7946 if (
SDValue C = MatchConstantOffset(
N)) {
7947 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7953 if (CurDAG->isBaseWithConstantOffset(
N)) {
7954 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7955 Base =
N.getOperand(0);
7963 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7967bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7987 uint64_t LowerBound = 0, UpperBound = 64;
8005 if (CN->getAPIntValue().uge(LowerBound) &&
8006 CN->getAPIntValue().ult(UpperBound)) {
8008 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
8016template <
bool MatchCBB>
8023 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
8025 Reg =
N.getOperand(0);
8027 SDLoc(
N), MVT::i32);
8035 Reg =
N.getOperand(0);
8055SDValue AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode &
N) {
8056 EVT VT =
N.getValueType(0);
8067 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8076 unsigned CondCode = CC->getZExtValue();
8079 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8081 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8082 else if (VT == MVT::f32)
8083 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8084 else if (VT == MVT::f64)
8085 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8093 if (TVal == CmpLHS && FVal == CmpRHS)
8095 else if (TVal == CmpRHS && FVal == CmpLHS)
8100 if (TVal == CmpLHS && FVal == CmpRHS)
8102 else if (TVal == CmpRHS && FVal == CmpLHS)
8111 unsigned Opc = getOpc(VT, isMax);
8117 if (!CFP || CFP->getValueAPF().isNaN())
8122 if (CFP->isZero() && !
N.getFlags().hasNoSignedZeros())
8128 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8134 return SDValue(CurDAG->getMachineNode(
Opc,
DL, VT, CmpLHS, CmpRHS), 0);
8137void AArch64DAGToDAGISel::PreprocessISelDAG() {
8138 bool MadeChange =
false;
8144 switch (
N.getOpcode()) {
8146 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8147 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8148 ScalarTy ==
N.getOperand(0).getValueType())
8153 case AArch64ISD::CSEL:
8154 Result = tryFoldCselToFMaxMin(
N);
8161 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8167 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8173 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
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const AArch64RegisterInfo * getRegisterInfo() const override
const AArch64TargetLowering * getTargetLowering() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
Register matchRegisterName(StringRef RegName) const
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static const fltSemantics & IEEEhalf()
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
static constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isScalableVectorOf(EVT EltVT) const
Return true if this is a scalable vector with matching element type.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.