22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
64 void PreprocessISelDAG()
override;
68 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
70 std::vector<SDValue> &OutOps)
override;
72 template <
signed Low,
signed High,
signed Scale>
75 template <
signed Low,
signed High>
83 return SelectShiftedRegister(
N,
false,
Reg, Shift);
86 return SelectShiftedRegister(
N,
true,
Reg, Shift);
89 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
95 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
98 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
101 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
104 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
107 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
116 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
119 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
122 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
131 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
134 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
137 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
139 template <
unsigned Size,
unsigned Max>
143 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
146 int64_t
C = CI->getSExtValue();
154 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
161 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
167 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
172 N =
N->getOperand(0);
176 EVT VT =
N->getValueType(0);
177 EVT LVT =
N->getOperand(0).getValueType();
178 unsigned Index =
N->getConstantOperandVal(1);
182 Res =
N->getOperand(0);
187 if (
N.getOpcode() != AArch64ISD::VLSHR)
190 EVT VT =
Op.getValueType();
191 unsigned ShtAmt =
N->getConstantOperandVal(1);
196 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
198 Op.getOperand(1).getConstantOperandVal(0)
199 <<
Op.getOperand(1).getConstantOperandVal(1));
200 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
203 Op.getOperand(1).getConstantOperandVal(0));
207 if (Imm != 1ULL << (ShtAmt - 1))
210 Res1 =
Op.getOperand(0);
211 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
215 bool SelectDupZeroOrUndef(
SDValue N) {
216 switch(
N->getOpcode()) {
219 case AArch64ISD::DUP:
221 auto Opnd0 =
N->getOperand(0);
235 bool SelectAny(
SDValue) {
return true; }
238 switch(
N->getOpcode()) {
239 case AArch64ISD::DUP:
241 auto Opnd0 =
N->getOperand(0);
253 template <MVT::SimpleValueType VT,
bool Negate>
255 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT>
265 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
268 template <MVT::SimpleValueType VT,
bool Invert = false>
270 return SelectSVELogicalImm(
N, VT, Imm, Invert);
273 template <MVT::SimpleValueType VT>
275 return SelectSVEArithImm(
N, VT, Imm);
278 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
280 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
287 EVT EltVT =
N->getValueType(0).getVectorElementType();
288 return SelectSVEShiftImm(
N->getOperand(0), 1,
294 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
301 MulImm = 1LL << MulImm;
303 if ((MulImm % std::abs(Scale)) != 0)
307 if ((MulImm >= Min) && (MulImm <= Max)) {
308 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
315 template <
signed Max,
signed Scale>
322 if (MulImm >= 0 && MulImm <= Max) {
324 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
331 template <
unsigned BaseReg,
unsigned Max>
339 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
362 const unsigned SubRegs[]);
364 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
366 bool tryIndexedLoad(
SDNode *
N);
368 void SelectPtrauthAuth(
SDNode *
N);
369 void SelectPtrauthResign(
SDNode *
N);
371 bool trySelectStackSlotTagP(
SDNode *
N);
374 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
376 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
380 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
381 unsigned Opc_rr,
unsigned Opc_ri,
382 bool IsIntr =
false);
383 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
384 unsigned Scale,
unsigned Opc_ri,
386 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
387 bool IsZmMulti,
unsigned Opcode,
388 bool HasPred =
false);
390 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
391 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
395 bool IsTupleInput,
unsigned Opc);
396 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 template <
unsigned MaxIdx,
unsigned Scale>
399 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
401 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
402 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
403 unsigned BaseReg = 0);
406 template <
int64_t Min,
int64_t Max>
410 template <
unsigned Scale>
412 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
415 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
420 template <
unsigned MaxIdx,
unsigned Scale>
425 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
430 unsigned Opc_rr,
unsigned Opc_ri);
431 std::tuple<unsigned, SDValue, SDValue>
432 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
436 bool tryBitfieldExtractOp(
SDNode *
N);
437 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
438 bool tryBitfieldInsertOp(
SDNode *
N);
439 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
440 bool tryShiftAmountMod(
SDNode *
N);
442 bool tryReadRegister(
SDNode *
N);
443 bool tryWriteRegister(
SDNode *
N);
445 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
446 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
451#include "AArch64GenDAGISel.inc"
459 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
461 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
474 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
475 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
476 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
479 template<
unsigned RegW
idth>
481 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
483 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
485 template <
unsigned RegW
idth>
487 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
489 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
491 template<
unsigned RegW
idth>
493 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
499 bool SelectCMP_SWAP(
SDNode *
N);
518 bool AllowSaturation,
SDValue &Imm);
526 bool SelectAllActivePredicate(
SDValue N);
531 template <
bool MatchCBB>
541 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
545char AArch64DAGToDAGISelLegacy::ID = 0;
553 auto getFloatVT = [&](
EVT VT) {
555 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
556 return VT.changeElementType(*(DAG.getContext()),
557 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
562 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
563 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
567 EVT OrigVT =
N.getValueType(0);
569 return DAG.getBitcast(OrigVT, OpNode);
576 Imm =
C->getZExtValue();
593 return N->getOpcode() ==
Opc &&
604 return Imm == ImmExpected;
609 assert(RegWidth == 32 || RegWidth == 64);
611 return APInt(RegWidth,
618 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
619 if (
N->getOpcode() == AArch64ISD::NVCAST)
620 N =
N->getOperand(0);
621 unsigned SplatWidth =
N.getScalarValueSizeInBits();
622 if (
N.getOpcode() == AArch64ISD::FMOV)
624 if (
N->getOpcode() == AArch64ISD::MOVI)
625 return APInt(SplatWidth,
N.getConstantOperandVal(0));
626 if (
N->getOpcode() == AArch64ISD::MOVIshift)
627 return APInt(SplatWidth,
N.getConstantOperandVal(0)
628 <<
N.getConstantOperandVal(1));
629 if (
N->getOpcode() == AArch64ISD::MVNIshift)
630 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
631 <<
N.getConstantOperandVal(1));
632 if (
N->getOpcode() == AArch64ISD::MOVIedit)
634 N.getConstantOperandVal(0)));
635 if (
N->getOpcode() == AArch64ISD::DUP)
637 return Const->getAPIntValue().trunc(SplatWidth);
646 unsigned SplatWidth =
N.getScalarValueSizeInBits();
648 if (SplatVal->getBitWidth() <= SplatWidth)
650 if (SplatVal->isSplat(SplatWidth))
651 return SplatVal->trunc(SplatWidth);
656bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
663 ImmVal->getZExtValue(), Encoding))
666 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
670bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(
SDValue N,
SDValue &Imm,
673 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
674 N.getValueType().getScalarType().getSimpleVT(),
680bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(
SDValue N,
683 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal, Imm);
687bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
689 std::vector<SDValue> &OutOps) {
690 switch(ConstraintID) {
693 case InlineAsm::ConstraintCode::m:
694 case InlineAsm::ConstraintCode::o:
695 case InlineAsm::ConstraintCode::Q:
699 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
701 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
703 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
704 dl,
Op.getValueType(),
706 OutOps.push_back(NewOp);
725 uint64_t Immed =
N.getNode()->getAsZExtVal();
728 if (Immed >> 12 == 0) {
730 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
738 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
739 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
756 uint64_t Immed =
N.getNode()->getAsZExtVal();
764 if (
N.getValueType() == MVT::i32)
765 Immed = ~((uint32_t)Immed) + 1;
767 Immed = ~Immed + 1ULL;
768 if (Immed & 0xFFFFFFFFFF000000ULL)
771 Immed &= 0xFFFFFFULL;
772 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
779 switch (
N.getOpcode()) {
805 unsigned ShiftVal = CSD->getZExtValue();
823bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
826 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
831 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
855 EVT VT =
N.getValueType();
856 if (VT != MVT::i32 && VT != MVT::i64)
859 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
865 unsigned LHSOpcode =
LHS->getOpcode();
879 unsigned LowZBits, MaskLen;
883 unsigned BitWidth =
N.getValueSizeInBits();
890 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
893 NewShiftC = LowZBits - ShiftAmtC;
894 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
900 NewShiftC = LowZBits + ShiftAmtC;
913 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
915 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
919 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
921 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
922 NewShiftAmt, BitWidthMinus1),
925 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
939 SrcVT =
N.getOperand(0).getValueType();
941 if (!IsLoadStore && SrcVT == MVT::i8)
943 else if (!IsLoadStore && SrcVT == MVT::i16)
945 else if (SrcVT == MVT::i32)
947 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
952 EVT SrcVT =
N.getOperand(0).getValueType();
953 if (!IsLoadStore && SrcVT == MVT::i8)
955 else if (!IsLoadStore && SrcVT == MVT::i16)
957 else if (SrcVT == MVT::i32)
959 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
987bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
990 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
995 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
996 V.getConstantOperandVal(1) <= 4 &&
1009bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
1011 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1021 unsigned BitSize =
N.getValueSizeInBits();
1022 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1025 Reg =
N.getOperand(0);
1026 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1027 return isWorthFoldingALU(
N,
true);
1038 if (
N.getValueType() == MVT::i32)
1046template<
signed Low,
signed High,
signed Scale>
1052 if ((MulImm % std::abs(Scale)) == 0) {
1053 int64_t RDVLImm = MulImm / Scale;
1054 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1055 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1064template <
signed Low,
signed High>
1065bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
1070 if (MulImm >=
Low && MulImm <=
High) {
1071 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1082 unsigned ShiftVal = 0;
1097 Reg =
N.getOperand(0).getOperand(0);
1109 Op =
Op->getOperand(0);
1111 Op.getOperand(0).getValueType().isFixedLengthVector())
1115 Reg =
N.getOperand(0);
1120 unsigned Opc =
N.getOpcode();
1138 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1140 return isWorthFoldingALU(
N);
1147 unsigned ShiftVal = 0;
1161 Reg =
N.getOperand(0);
1162 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1164 return isWorthFoldingALU(
N);
1173 for (
auto *
User :
N->users()) {
1200bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1201 unsigned BW,
unsigned Size,
1205 const DataLayout &
DL = CurDAG->getDataLayout();
1206 const TargetLowering *TLI = getTargetLowering();
1210 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1216 if (CurDAG->isBaseWithConstantOffset(
N)) {
1219 int64_t RHSC =
RHS->getSExtValue();
1221 int64_t
Range = 0x1LL << (BW - 1);
1223 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1224 RHSC < (
Range << Scale)) {
1225 Base =
N.getOperand(0);
1230 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1235 uint64_t RHSC =
RHS->getZExtValue();
1237 uint64_t
Range = 0x1ULL << BW;
1239 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1240 Base =
N.getOperand(0);
1245 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1256 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1263bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1266 const DataLayout &
DL = CurDAG->getDataLayout();
1267 const TargetLowering *TLI = getTargetLowering();
1271 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1276 GlobalAddressSDNode *GAN =
1278 Base =
N.getOperand(0);
1288 if (CurDAG->isBaseWithConstantOffset(
N)) {
1290 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1293 Base =
N.getOperand(0);
1298 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1306 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1314 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1323bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1326 if (!CurDAG->isBaseWithConstantOffset(
N))
1329 int64_t RHSC =
RHS->getSExtValue();
1330 if (RHSC >= -256 && RHSC < 256) {
1331 Base =
N.getOperand(0);
1334 const TargetLowering *TLI = getTargetLowering();
1335 Base = CurDAG->getTargetFrameIndex(
1338 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1348 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1355bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1375 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1381 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1384 return isWorthFoldingAddr(
N,
Size);
1387bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1405 const SDNode *
Node =
N.getNode();
1406 for (SDNode *UI :
Node->users()) {
1412 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1415 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1418 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1423 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1426 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1431 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1435 if (IsExtendedRegisterWorthFolding &&
1442 if (isWorthFoldingAddr(
LHS,
Size))
1447 if (IsExtendedRegisterWorthFolding &&
1454 if (isWorthFoldingAddr(
RHS,
Size))
1466 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1469 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1471 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1472 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1476bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1489 const SDNode *
Node =
N.getNode();
1490 for (SDNode *UI :
Node->users()) {
1507 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1517 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1524 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1527 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1530 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1535 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1538 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1545 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1546 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1552 static const unsigned RegClassIDs[] = {
1553 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1554 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1555 AArch64::dsub2, AArch64::dsub3};
1561 static const unsigned RegClassIDs[] = {
1562 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1563 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1564 AArch64::qsub2, AArch64::qsub3};
1570 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1571 AArch64::ZPR3RegClassID,
1572 AArch64::ZPR4RegClassID};
1573 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1574 AArch64::zsub2, AArch64::zsub3};
1584 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1585 AArch64::ZPR4Mul4RegClassID};
1586 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1587 AArch64::zsub2, AArch64::zsub3};
1592 const unsigned RegClassIDs[],
1593 const unsigned SubRegs[]) {
1596 if (Regs.
size() == 1)
1607 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1610 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1611 Ops.push_back(Regs[i]);
1612 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1616 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1620void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1623 EVT VT =
N->getValueType(0);
1625 unsigned ExtOff = isExt;
1628 unsigned Vec0Off = ExtOff + 1;
1634 Ops.push_back(
N->getOperand(1));
1635 Ops.push_back(RegSeq);
1636 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1637 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1640static std::tuple<SDValue, SDValue>
1661 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1666 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1668 return std::make_tuple(
1673void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1678 SDValue AUTDisc =
N->getOperand(3);
1681 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1683 SDValue AUTAddrDisc, AUTConstDisc;
1684 std::tie(AUTConstDisc, AUTAddrDisc) =
1688 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1690 if (
N->getNumOperands() > 4)
1691 Ops.push_back(
N->getOperand(4));
1694 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1695 ReplaceNode(
N, AUT);
1697 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1698 AArch64::X16, Val,
SDValue());
1701 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1702 ReplaceNode(
N, AUT);
1706void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1716 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1721 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1722 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1724 SDValue AUTAddrDisc, AUTConstDisc;
1725 std::tie(AUTConstDisc, AUTAddrDisc) =
1728 SDValue PACAddrDisc, PACConstDisc;
1729 std::tie(PACConstDisc, PACAddrDisc) =
1732 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1733 AArch64::X16, Val,
SDValue());
1736 SDValue Addend =
N->getOperand(OffsetBase + 6);
1737 SDValue IncomingChain =
N->getOperand(0);
1738 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1739 PACKey, PACConstDisc, PACAddrDisc,
1740 Addend, IncomingChain, X16Copy.
getValue(1)};
1742 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1743 MVT::i64, MVT::Other,
Ops);
1744 ReplaceNode(
N, AUTRELLOADPAC);
1746 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1747 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1749 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1750 ReplaceNode(
N, AUTPAC);
1754bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1756 if (
LD->isUnindexed())
1758 EVT VT =
LD->getMemoryVT();
1759 EVT DstVT =
N->getValueType(0);
1763 int OffsetVal = (int)
OffsetOp->getZExtValue();
1768 unsigned Opcode = 0;
1771 bool InsertTo64 =
false;
1773 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1774 else if (VT == MVT::i32) {
1776 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1778 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1780 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1786 }
else if (VT == MVT::i16) {
1788 if (DstVT == MVT::i64)
1789 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1791 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1793 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1794 InsertTo64 = DstVT == MVT::i64;
1799 }
else if (VT == MVT::i8) {
1801 if (DstVT == MVT::i64)
1802 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1804 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1806 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1807 InsertTo64 = DstVT == MVT::i64;
1812 }
else if (VT == MVT::f16) {
1813 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1814 }
else if (VT == MVT::bf16) {
1815 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1816 }
else if (VT == MVT::f32) {
1817 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1818 }
else if (VT == MVT::f64 ||
1820 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1822 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1824 if (IsPre || OffsetVal != 8)
1828 Opcode = AArch64::LD1Onev8b_POST;
1831 Opcode = AArch64::LD1Onev4h_POST;
1834 Opcode = AArch64::LD1Onev2s_POST;
1837 Opcode = AArch64::LD1Onev1d_POST;
1843 if (IsPre || OffsetVal != 16)
1847 Opcode = AArch64::LD1Onev16b_POST;
1850 Opcode = AArch64::LD1Onev8h_POST;
1853 Opcode = AArch64::LD1Onev4s_POST;
1856 Opcode = AArch64::LD1Onev2d_POST;
1868 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1869 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1871 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1881 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1882 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1883 MVT::i64, LoadedVal, SubReg),
1887 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1890 CurDAG->RemoveDeadNode(
N);
1894void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1895 unsigned SubRegIdx) {
1897 EVT VT =
N->getValueType(0);
1903 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1905 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1907 for (
unsigned i = 0; i < NumVecs; ++i)
1909 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1916 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1920 CurDAG->RemoveDeadNode(
N);
1923void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1924 unsigned Opc,
unsigned SubRegIdx) {
1926 EVT VT =
N->getValueType(0);
1933 const EVT ResTys[] = {MVT::i64,
1934 MVT::Untyped, MVT::Other};
1936 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1944 ReplaceUses(
SDValue(
N, 0), SuperReg);
1946 for (
unsigned i = 0; i < NumVecs; ++i)
1948 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1952 CurDAG->RemoveDeadNode(
N);
1958std::tuple<unsigned, SDValue, SDValue>
1959AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1965 SDValue NewOffset = OldOffset;
1967 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1968 N, OldBase, NewBase, NewOffset);
1972 const bool IsRegReg =
1973 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1976 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1989template <SelectTypeKind Kind>
2001 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2006 if (EltVT != MVT::i1)
2010 if (EltVT == MVT::bf16)
2012 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2042void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2045 if (
Imm->getZExtValue() > 1)
2049 EVT VT =
N->getValueType(0);
2051 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2054 for (
unsigned I = 0;
I < 2; ++
I)
2055 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2056 AArch64::psub0 +
I,
DL, VT, SuperReg));
2058 CurDAG->RemoveDeadNode(
N);
2061void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2063 EVT VT =
N->getValueType(0);
2067 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2070 for (
unsigned I = 0;
I < 2; ++
I)
2071 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2072 AArch64::psub0 +
I,
DL, VT, SuperReg));
2074 CurDAG->RemoveDeadNode(
N);
2077void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2079 EVT VT =
N->getValueType(0);
2083 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2085 for (
unsigned i = 0; i < NumVecs; ++i)
2086 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2087 AArch64::zsub0 + i,
DL, VT, SuperReg));
2089 CurDAG->RemoveDeadNode(
N);
2092void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2095 EVT VT =
N->getValueType(0);
2097 Ops.push_back(
N->getOperand(0));
2100 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2103 for (
unsigned i = 0; i < NumVecs; ++i)
2104 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2105 AArch64::zsub0 + i,
DL, VT, SuperReg));
2108 unsigned ChainIdx = NumVecs;
2110 CurDAG->RemoveDeadNode(
N);
2113void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2118 assert(Opcode != 0 &&
"Unexpected opcode");
2121 EVT VT =
N->getValueType(0);
2122 SDUse *OpsIter =
N->op_begin() + 1;
2125 auto GetMultiVecOperand = [&]() {
2128 return createZMulTuple(Regs);
2132 Ops.push_back(*OpsIter++);
2134 Ops.push_back(GetMultiVecOperand());
2136 Ops.push_back(GetMultiVecOperand());
2138 Ops.push_back(*OpsIter++);
2141 Ops.append(OpsIter,
N->op_end());
2143 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2145 for (
unsigned i = 0; i < NumVecs; ++i)
2146 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2147 AArch64::zsub0 + i,
DL, VT, SuperReg));
2149 CurDAG->RemoveDeadNode(
N);
2152void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2153 unsigned Scale,
unsigned Opc_ri,
2154 unsigned Opc_rr,
bool IsIntr) {
2155 assert(Scale < 5 &&
"Invalid scaling value.");
2157 EVT VT =
N->getValueType(0);
2164 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2165 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2171 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2173 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2175 for (
unsigned i = 0; i < NumVecs; ++i)
2176 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2177 AArch64::zsub0 + i,
DL, VT, SuperReg));
2180 unsigned ChainIdx = NumVecs;
2182 CurDAG->RemoveDeadNode(
N);
2185void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2190 assert(Scale < 4 &&
"Invalid scaling value.");
2192 EVT VT =
N->getValueType(0);
2200 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2206 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2208 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2210 for (
unsigned i = 0; i < NumVecs; ++i)
2211 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2212 AArch64::zsub0 + i,
DL, VT, SuperReg));
2215 unsigned ChainIdx = NumVecs;
2217 CurDAG->RemoveDeadNode(
N);
2220void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2222 if (
N->getValueType(0) != MVT::nxv4f32)
2224 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2227void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2228 unsigned NumOutVecs,
2232 if (
Imm->getZExtValue() > MaxImm)
2236 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2242 EVT VT =
Node->getValueType(0);
2245 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2248 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2249 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2250 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2253 unsigned ChainIdx = NumOutVecs;
2255 CurDAG->RemoveDeadNode(Node);
2258void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2259 unsigned NumOutVecs,
2262 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2267 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2271 EVT VT =
Node->getValueType(0);
2274 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2277 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2278 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2279 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2282 unsigned ChainIdx = NumOutVecs;
2284 CurDAG->RemoveDeadNode(Node);
2287void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2290 EVT VT =
N->getValueType(0);
2293 SDValue Zd = createZMulTuple(Regs);
2294 SDValue Zn =
N->getOperand(1 + NumVecs);
2295 SDValue Zm =
N->getOperand(2 + NumVecs);
2301 for (
unsigned i = 0; i < NumVecs; ++i)
2302 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2303 AArch64::zsub0 + i,
DL, VT, SuperReg));
2305 CurDAG->RemoveDeadNode(
N);
2335template <
unsigned MaxIdx,
unsigned Scale>
2336void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2337 unsigned BaseReg,
unsigned Op) {
2338 unsigned TileNum = 0;
2339 if (BaseReg != AArch64::ZA)
2340 TileNum =
N->getConstantOperandVal(2);
2346 if (BaseReg == AArch64::ZA)
2351 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2355 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2357 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2359 EVT VT =
N->getValueType(0);
2360 for (
unsigned I = 0;
I < NumVecs; ++
I)
2362 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2365 unsigned ChainIdx = NumVecs;
2367 CurDAG->RemoveDeadNode(
N);
2370void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2371 unsigned Op,
unsigned MaxIdx,
2372 unsigned Scale,
unsigned BaseReg) {
2377 if (BaseReg != AArch64::ZA)
2381 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2388 if (BaseReg != AArch64::ZA )
2389 Ops.push_back(
N->getOperand(2));
2392 Ops.push_back(
N->getOperand(0));
2393 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2395 EVT VT =
N->getValueType(0);
2396 for (
unsigned I = 0;
I < NumVecs; ++
I)
2398 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2402 unsigned ChainIdx = NumVecs;
2404 CurDAG->RemoveDeadNode(
N);
2407void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2408 unsigned NumOutVecs,
2412 EVT VT =
N->getValueType(0);
2413 unsigned NumInVecs =
N->getNumOperands() - 1;
2417 assert((NumInVecs == 2 || NumInVecs == 4) &&
2418 "Don't know how to handle multi-register input!");
2420 Ops.push_back(createZMulTuple(Regs));
2423 for (
unsigned I = 0;
I < NumInVecs;
I++)
2424 Ops.push_back(
N->getOperand(1 +
I));
2427 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2430 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2431 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2432 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2433 CurDAG->RemoveDeadNode(
N);
2436void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2439 EVT VT =
N->getOperand(2)->getValueType(0);
2447 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2456void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2457 unsigned Scale,
unsigned Opc_rr,
2463 SDValue RegSeq = createZTuple(Regs);
2469 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2470 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2476 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2484 const DataLayout &
DL = CurDAG->getDataLayout();
2485 const TargetLowering *TLI = getTargetLowering();
2489 int FI = FINode->getIndex();
2491 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2498void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2501 EVT VT =
N->getOperand(2)->getValueType(0);
2502 const EVT ResTys[] = {MVT::i64,
2514 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2554void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2557 EVT VT =
N->getValueType(0);
2569 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2571 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2573 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2575 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2579 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2580 AArch64::qsub2, AArch64::qsub3 };
2581 for (
unsigned i = 0; i < NumVecs; ++i) {
2582 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2589 CurDAG->RemoveDeadNode(
N);
2592void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2595 EVT VT =
N->getValueType(0);
2607 const EVT ResTys[] = {MVT::i64,
2610 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2613 CurDAG->getTargetConstant(LaneNo, dl,
2618 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2630 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2631 AArch64::qsub2, AArch64::qsub3 };
2632 for (
unsigned i = 0; i < NumVecs; ++i) {
2633 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2643 CurDAG->RemoveDeadNode(
N);
2646void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2649 EVT VT =
N->getOperand(2)->getValueType(0);
2661 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2663 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2665 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2674void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2677 EVT VT =
N->getOperand(2)->getValueType(0);
2689 const EVT ResTys[] = {MVT::i64,
2692 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2694 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2698 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2709 unsigned &LSB,
unsigned &MSB,
2710 unsigned NumberOfIgnoredLowBits,
2711 bool BiggerPattern) {
2713 "N must be a AND operation to call this function");
2715 EVT VT =
N->getValueType(0);
2720 assert((VT == MVT::i32 || VT == MVT::i64) &&
2721 "Type checking must have been done before calling this function");
2735 const SDNode *Op0 =
N->getOperand(0).getNode();
2742 if (AndImm & (AndImm + 1))
2745 bool ClampMSB =
false;
2765 ClampMSB = (VT == MVT::i32);
2766 }
else if (BiggerPattern) {
2772 Opd0 =
N->getOperand(0);
2778 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2781 <<
": Found large shift immediate, this should not happen\n"));
2795 MSB = MSB > 31 ? 31 : MSB;
2797 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2802 SDValue &Opd0,
unsigned &Immr,
2806 EVT VT =
N->getValueType(0);
2808 assert((VT == MVT::i32 || VT == MVT::i64) &&
2809 "Type checking must have been done before calling this function");
2813 Op =
Op->getOperand(0);
2814 VT =
Op->getValueType(0);
2823 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2827 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2828 Opd0 =
Op.getOperand(0);
2830 Imms = ShiftImm + Width - 1;
2858 Opd0 =
N->getOperand(0).getOperand(0);
2868 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2875 unsigned &Immr,
unsigned &Imms,
2876 bool BiggerPattern) {
2878 "N must be a SHR/SRA operation to call this function");
2880 EVT VT =
N->getValueType(0);
2885 assert((VT == MVT::i32 || VT == MVT::i64) &&
2886 "Type checking must have been done before calling this function");
2896 Opd0 =
N->getOperand(0).getOperand(0);
2897 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2903 Opd0 =
N->getOperand(0).getOperand(0);
2906 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2907 }
else if (BiggerPattern) {
2911 Opd0 =
N->getOperand(0);
2920 <<
": Found large shift immediate, this should not happen\n"));
2929 "bad amount in shift node!");
2930 int immr = SrlImm - ShlImm;
2935 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2937 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2941bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2944 EVT VT =
N->getValueType(0);
2945 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2946 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2957 unsigned Immr = ShiftImm;
2959 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2960 CurDAG->getTargetConstant(Imms, dl, VT)};
2961 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2966 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2967 unsigned NumberOfIgnoredLowBits = 0,
2968 bool BiggerPattern =
false) {
2969 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2972 switch (
N->getOpcode()) {
2974 if (!
N->isMachineOpcode())
2979 NumberOfIgnoredLowBits, BiggerPattern);
2988 unsigned NOpc =
N->getMachineOpcode();
2992 case AArch64::SBFMWri:
2993 case AArch64::UBFMWri:
2994 case AArch64::SBFMXri:
2995 case AArch64::UBFMXri:
2997 Opd0 =
N->getOperand(0);
2998 Immr =
N->getConstantOperandVal(1);
2999 Imms =
N->getConstantOperandVal(2);
3006bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3007 unsigned Opc, Immr, Imms;
3012 EVT VT =
N->getValueType(0);
3017 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3018 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3019 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3021 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3022 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3028 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3029 CurDAG->getTargetConstant(Imms, dl, VT)};
3030 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3039 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3040 assert((VT == MVT::i32 || VT == MVT::i64) &&
3041 "i32 or i64 mask type expected!");
3045 APInt SignificantDstMask =
3049 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3050 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3083 APInt OpUsefulBits(UsefulBits);
3087 OpUsefulBits <<= MSB - Imm + 1;
3092 OpUsefulBits <<= Imm;
3094 OpUsefulBits <<= MSB + 1;
3097 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3103 UsefulBits &= OpUsefulBits;
3120 APInt Mask(UsefulBits);
3121 Mask.clearAllBits();
3129 Mask.lshrInPlace(ShiftAmt);
3135 Mask.lshrInPlace(ShiftAmt);
3151 APInt OpUsefulBits(UsefulBits);
3165 OpUsefulBits <<= Width;
3168 if (
Op.getOperand(1) == Orig) {
3170 Mask = ResultUsefulBits & OpUsefulBits;
3174 if (
Op.getOperand(0) == Orig)
3176 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3182 OpUsefulBits <<= Width;
3184 OpUsefulBits <<= LSB;
3186 if (
Op.getOperand(1) == Orig) {
3188 Mask = ResultUsefulBits & OpUsefulBits;
3189 Mask.lshrInPlace(LSB);
3192 if (
Op.getOperand(0) == Orig)
3193 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3210 case AArch64::ANDSWri:
3211 case AArch64::ANDSXri:
3212 case AArch64::ANDWri:
3213 case AArch64::ANDXri:
3217 case AArch64::UBFMWri:
3218 case AArch64::UBFMXri:
3221 case AArch64::ORRWrs:
3222 case AArch64::ORRXrs:
3227 case AArch64::BFMWri:
3228 case AArch64::BFMXri:
3231 case AArch64::STRBBui:
3232 case AArch64::STURBBi:
3238 case AArch64::STRHHui:
3239 case AArch64::STURHHi:
3252 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3254 UsefulBits =
APInt(Bitwidth, 0);
3263 UsersUsefulBits |= UsefulBitsForUse;
3268 UsefulBits &= UsersUsefulBits;
3278 EVT VT =
Op.getValueType();
3281 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3284 if (ShlAmount > 0) {
3287 UBFMOpc, dl, VT,
Op,
3292 assert(ShlAmount < 0 &&
"expected right shift");
3293 int ShrAmount = -ShlAmount;
3305 const uint64_t NonZeroBits,
3312 const uint64_t NonZeroBits,
3319 bool BiggerPattern,
SDValue &Src,
3320 int &DstLSB,
int &Width) {
3321 EVT VT =
Op.getValueType();
3330 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3334 switch (
Op.getOpcode()) {
3339 NonZeroBits, Src, DstLSB, Width);
3342 NonZeroBits, Src, DstLSB, Width);
3355 EVT VT =
Op.getValueType();
3356 assert((VT == MVT::i32 || VT == MVT::i64) &&
3357 "Caller guarantees VT is one of i32 or i64");
3370 assert((~AndImm & NonZeroBits) == 0 &&
3371 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3400 if (!BiggerPattern && !AndOp0.
hasOneUse())
3419 <<
"Found large Width in bit-field-positioning -- this indicates no "
3420 "proper combining / constant folding was performed\n");
3429 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3444 "Op.getNode() should be a SHL node to call this function");
3446 "Op.getNode() should shift ShlImm to call this function");
3453 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3477 EVT VT =
Op.getValueType();
3478 assert((VT == MVT::i32 || VT == MVT::i64) &&
3479 "Caller guarantees that type is i32 or i64");
3486 if (!BiggerPattern && !
Op.hasOneUse())
3495 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3503 assert(VT == MVT::i32 || VT == MVT::i64);
3514 EVT VT =
N->getValueType(0);
3515 if (VT != MVT::i32 && VT != MVT::i64)
3533 if (!
And.hasOneUse() ||
3543 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3550 if ((OrImm & NotKnownZero) != 0) {
3562 unsigned ImmS = Width - 1;
3568 bool IsBFI = LSB != 0;
3573 unsigned OrChunks = 0, BFIChunks = 0;
3574 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3575 if (((OrImm >> Shift) & 0xFFFF) != 0)
3577 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3580 if (BFIChunks > OrChunks)
3586 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3594 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3603 if (!Dst.hasOneUse())
3606 EVT VT = Dst.getValueType();
3607 assert((VT == MVT::i32 || VT == MVT::i64) &&
3608 "Caller should guarantee that VT is one of i32 or i64");
3636 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3637 unsigned MaskWidth =
3640 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3646 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3647 ShiftedOperand =
SDValue(UBFMNode, 0);
3676 const bool BiggerPattern) {
3677 EVT VT =
N->getValueType(0);
3678 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3679 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3680 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3681 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3682 assert((VT == MVT::i32 || VT == MVT::i64) &&
3683 "Expect result type to be i32 or i64 since N is combinable to BFM");
3690 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3693 if (BiggerPattern) {
3716 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3778 EVT VT =
N->getValueType(0);
3779 if (VT != MVT::i32 && VT != MVT::i64)
3787 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3788 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3808 for (
int I = 0;
I < 4; ++
I) {
3811 unsigned ImmR, ImmS;
3812 bool BiggerPattern =
I / 2;
3813 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3815 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3821 NumberOfIgnoredLowBits, BiggerPattern)) {
3824 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3825 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3830 Width = ImmS - ImmR + 1;
3841 Src, DstLSB, Width)) {
3849 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3859 APInt BitsToBeInserted =
3862 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3886 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3919 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3921 if (Src->hasOneUse() &&
3924 Src = Src->getOperand(0);
3934 unsigned ImmS = Width - 1;
3940 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3948bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3957 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3970bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3974 EVT VT =
N->getValueType(0);
3975 if (VT != MVT::i32 && VT != MVT::i64)
3981 Op0, DstLSB, Width))
3987 unsigned ImmS = Width - 1;
3990 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3991 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3992 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3993 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3999bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4000 EVT VT =
N->getValueType(0);
4003 switch (
N->getOpcode()) {
4005 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4008 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4011 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4014 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4022 if (VT == MVT::i32) {
4025 }
else if (VT == MVT::i64) {
4031 SDValue ShiftAmt =
N->getOperand(1);
4051 (Add0Imm %
Size == 0)) {
4057 if (SubVT == MVT::i32) {
4058 NegOpc = AArch64::SUBWrr;
4059 ZeroReg = AArch64::WZR;
4061 assert(SubVT == MVT::i64);
4062 NegOpc = AArch64::SUBXrr;
4063 ZeroReg = AArch64::XZR;
4066 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4067 MachineSDNode *Neg =
4068 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4069 NewShiftAmt =
SDValue(Neg, 0);
4077 if (SubVT == MVT::i32) {
4078 NotOpc = AArch64::ORNWrr;
4079 ZeroReg = AArch64::WZR;
4081 assert(SubVT == MVT::i64);
4082 NotOpc = AArch64::ORNXrr;
4083 ZeroReg = AArch64::XZR;
4086 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4087 MachineSDNode *
Not =
4088 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4089 NewShiftAmt =
SDValue(Not, 0);
4110 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4111 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4112 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4113 NewShiftAmt, SubReg);
4114 NewShiftAmt =
SDValue(Ext, 0);
4118 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4125 bool isReciprocal) {
4128 FVal = CN->getValueAPF();
4131 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4141 if (
unsigned FBits =
4150bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4151 unsigned RegWidth) {
4156bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4157 unsigned RegWidth) {
4158 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4159 N.getValueType().getScalarSizeInBits() ==
4160 N.getOperand(0).getValueType().getScalarSizeInBits())
4161 N =
N.getOperand(0);
4163 auto ImmToFloat = [RegWidth](APInt
Imm) {
4166 return APFloat(APFloat::IEEEhalf(), Imm);
4168 return APFloat(APFloat::IEEEsingle(), Imm);
4170 return APFloat(APFloat::IEEEdouble(), Imm);
4177 switch (
N->getOpcode()) {
4178 case AArch64ISD::MOVIshift:
4179 FVal = ImmToFloat(APInt(RegWidth,
N.getConstantOperandVal(0)
4180 <<
N.getConstantOperandVal(1)));
4182 case AArch64ISD::FMOV:
4183 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4185 case AArch64ISD::DUP:
4187 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4197 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(
N), MVT::i32);
4204bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4206 unsigned RegWidth) {
4216 RegString.
split(Fields,
':');
4218 if (Fields.
size() == 1)
4222 &&
"Invalid number of fields in read register string");
4225 bool AllIntFields =
true;
4229 AllIntFields &= !
Field.getAsInteger(10, IntField);
4230 Ops.push_back(IntField);
4234 "Unexpected non-integer value in special register string.");
4239 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4240 (
Ops[3] << 3) | (
Ops[4]);
4247bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4249 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4252 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4254 unsigned Opcode64Bit = AArch64::MRS;
4259 const auto *TheReg =
4260 AArch64SysReg::lookupSysRegByName(RegString->getString());
4261 if (TheReg && TheReg->Readable &&
4262 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4263 Imm = TheReg->Encoding;
4269 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4270 Opcode64Bit = AArch64::ADR;
4278 SDValue InChain =
N->getOperand(0);
4279 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4280 if (!ReadIs128Bit) {
4281 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4282 {SysRegImm, InChain});
4284 SDNode *MRRS = CurDAG->getMachineNode(
4286 {MVT::Untyped , MVT::Other },
4287 {SysRegImm, InChain});
4291 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4293 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4299 ReplaceUses(
SDValue(
N, 2), OutChain);
4308bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4310 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4313 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4315 if (!WriteIs128Bit) {
4321 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4324 "Expected a constant integer expression.");
4325 unsigned Reg = PMapper->Encoding;
4326 uint64_t Immed =
N->getConstantOperandVal(2);
4327 CurDAG->SelectNodeTo(
4328 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4329 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4335 if (trySelectPState(
4336 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4337 AArch64::MSRpstateImm4))
4339 if (trySelectPState(
4340 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4341 AArch64::MSRpstateImm1))
4350 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4351 if (TheReg && TheReg->Writeable &&
4352 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4353 Imm = TheReg->Encoding;
4362 if (!WriteIs128Bit) {
4363 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4364 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4365 N->getOperand(2), InChain);
4369 SDNode *Pair = CurDAG->getMachineNode(
4370 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4371 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4374 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4376 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4378 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4379 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4387bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4392 if (Subtarget->hasLSE())
return false;
4394 if (MemTy == MVT::i8)
4395 Opcode = AArch64::CMP_SWAP_8;
4396 else if (MemTy == MVT::i16)
4397 Opcode = AArch64::CMP_SWAP_16;
4398 else if (MemTy == MVT::i32)
4399 Opcode = AArch64::CMP_SWAP_32;
4400 else if (MemTy == MVT::i64)
4401 Opcode = AArch64::CMP_SWAP_64;
4405 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4406 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4408 SDNode *CmpSwap = CurDAG->getMachineNode(
4410 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4417 CurDAG->RemoveDeadNode(
N);
4422bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4423 SDValue &Shift,
bool Negate) {
4430 return SelectSVEAddSubImm(SDLoc(
N), Val, VT, Imm, Shift, Negate);
4433bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4442 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4449 if ((Val & ~0xff) == 0) {
4450 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4455 if ((Val & ~0xff00) == 0) {
4456 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4468bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4492 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4493 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4500 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4501 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4505 if (Val <= 65280 && Val % 256 == 0) {
4506 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4507 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4518bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4528 int32_t ImmVal, ShiftVal;
4533 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4534 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4538bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4540 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(), Imm);
4544bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4547 if (ImmVal >= -128 && ImmVal < 128) {
4548 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4554bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4556 uint64_t ImmVal = CNode->getZExtValue();
4566 ImmVal &= 0xFFFFFFFF;
4575 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4582bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4586 ImmVal = CI->getZExtValue();
4588 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4599 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4608bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4609 uint64_t
High,
bool AllowSaturation,
4612 uint64_t ImmVal = CN->getZExtValue();
4619 if (ImmVal >
High) {
4620 if (!AllowSaturation)
4625 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4632bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4646 const TargetLowering *TLI = getTargetLowering();
4649 SDValue FiOp = CurDAG->getTargetFrameIndex(
4651 int TagOffset =
N->getConstantOperandVal(3);
4653 SDNode *Out = CurDAG->getMachineNode(
4654 AArch64::TAGPstack,
DL, MVT::i64,
4655 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4656 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4657 ReplaceNode(
N, Out);
4661void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4663 "llvm.aarch64.tagp third argument must be an immediate");
4664 if (trySelectStackSlotTagP(
N))
4671 int TagOffset =
N->getConstantOperandVal(3);
4672 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4673 {
N->getOperand(1),
N->getOperand(2)});
4674 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4675 {
SDValue(N1, 0),
N->getOperand(2)});
4676 SDNode *N3 = CurDAG->getMachineNode(
4677 AArch64::ADDG,
DL, MVT::i64,
4678 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4679 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4683bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4687 if (
N->getConstantOperandVal(2) != 0)
4689 if (!
N->getOperand(0).isUndef())
4693 EVT VT =
N->getValueType(0);
4694 EVT InVT =
N->getOperand(1).getValueType();
4705 "Expected to insert into a packed scalable vector!");
4708 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4709 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4710 N->getOperand(1), RC));
4714bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4718 if (
N->getConstantOperandVal(1) != 0)
4722 EVT VT =
N->getValueType(0);
4723 EVT InVT =
N->getOperand(0).getValueType();
4734 "Expected to extract from a packed scalable vector!");
4737 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4738 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4739 N->getOperand(0), RC));
4743bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4749 EVT VT =
N->getValueType(0);
4762 (Subtarget->hasSVE2() ||
4763 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4764 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4767 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4771 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4772 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4773 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4780 bool IsXOROperand =
true;
4782 IsXOROperand =
false;
4788 APInt ShlAmt, ShrAmt;
4796 if (!IsXOROperand) {
4798 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4801 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4802 SDNode *SubRegToReg =
4803 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4814 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4815 AArch64::XAR_ZZZI_D})) {
4816 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4841 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4851 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4859 bool IsXOROperand =
true;
4861 IsXOROperand =
false;
4864 R1 =
XOR.getOperand(0);
4865 R2 =
XOR.getOperand(1);
4875 if (ShAmt + HsAmt != VTSizeInBits)
4878 if (!IsXOROperand) {
4881 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4890 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4896 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4897 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4899 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4902 if (
R2.getValueType() == VT)
4903 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4908 SDValue SubReg = CurDAG->getTargetConstant(
4911 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4916 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4922 SDNode *XAR =
nullptr;
4926 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4927 AArch64::XAR_ZZZI_D}))
4928 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4930 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4933 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4939 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4940 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4943 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4944 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4947 SDValue SubReg = CurDAG->getTargetConstant(
4950 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4954 ReplaceNode(
N, XAR);
4958void AArch64DAGToDAGISel::Select(SDNode *Node) {
4960 if (
Node->isMachineOpcode()) {
4962 Node->setNodeId(-1);
4967 EVT VT =
Node->getValueType(0);
4969 switch (
Node->getOpcode()) {
4974 if (SelectCMP_SWAP(Node))
4979 case AArch64ISD::MRRS:
4980 if (tryReadRegister(Node))
4985 case AArch64ISD::MSRR:
4986 if (tryWriteRegister(Node))
4993 if (tryIndexedLoad(Node))
5002 if (tryBitfieldExtractOp(Node))
5004 if (tryBitfieldInsertInZeroOp(Node))
5009 if (tryShiftAmountMod(Node))
5014 if (tryBitfieldExtractOpFromSExt(Node))
5019 if (tryBitfieldInsertOp(Node))
5021 if (trySelectXAR(Node))
5026 if (trySelectCastScalableToFixedLengthVector(Node))
5032 if (trySelectCastFixedLengthToScalableVector(Node))
5041 if (ConstNode->
isZero()) {
5042 if (VT == MVT::i32) {
5044 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
5045 ReplaceNode(Node,
New.getNode());
5047 }
else if (VT == MVT::i64) {
5049 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
5050 ReplaceNode(Node,
New.getNode());
5061 const TargetLowering *TLI = getTargetLowering();
5062 SDValue TFI = CurDAG->getTargetFrameIndex(
5065 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5066 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5067 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5071 unsigned IntNo =
Node->getConstantOperandVal(1);
5075 case Intrinsic::aarch64_gcsss: {
5079 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5081 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5082 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5083 MVT::Other, Zero,
SDValue(SS1, 0));
5084 ReplaceNode(Node, SS2);
5087 case Intrinsic::aarch64_ldaxp:
5088 case Intrinsic::aarch64_ldxp: {
5090 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5095 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5096 MVT::Other, MemAddr, Chain);
5099 MachineMemOperand *MemOp =
5102 ReplaceNode(Node, Ld);
5105 case Intrinsic::aarch64_stlxp:
5106 case Intrinsic::aarch64_stxp: {
5108 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5116 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5118 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5120 MachineMemOperand *MemOp =
5124 ReplaceNode(Node, St);
5127 case Intrinsic::aarch64_neon_ld1x2:
5128 if (VT == MVT::v8i8) {
5129 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5131 }
else if (VT == MVT::v16i8) {
5132 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5134 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5135 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5137 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5138 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5140 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5141 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5143 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5144 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5146 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5147 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5149 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5150 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5154 case Intrinsic::aarch64_neon_ld1x3:
5155 if (VT == MVT::v8i8) {
5156 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5158 }
else if (VT == MVT::v16i8) {
5159 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5161 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5162 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5164 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5165 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5167 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5168 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5170 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5171 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5173 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5174 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5176 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5177 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5181 case Intrinsic::aarch64_neon_ld1x4:
5182 if (VT == MVT::v8i8) {
5183 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5185 }
else if (VT == MVT::v16i8) {
5186 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5188 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5189 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5191 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5192 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5194 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5195 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5197 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5198 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5200 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5201 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5203 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5204 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5208 case Intrinsic::aarch64_neon_ld2:
5209 if (VT == MVT::v8i8) {
5210 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5212 }
else if (VT == MVT::v16i8) {
5213 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5215 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5216 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5218 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5219 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5221 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5222 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5224 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5225 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5227 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5228 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5230 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5231 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5235 case Intrinsic::aarch64_neon_ld3:
5236 if (VT == MVT::v8i8) {
5237 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5239 }
else if (VT == MVT::v16i8) {
5240 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5242 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5243 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5245 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5246 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5248 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5249 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5251 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5252 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5254 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5255 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5257 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5258 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5262 case Intrinsic::aarch64_neon_ld4:
5263 if (VT == MVT::v8i8) {
5264 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5266 }
else if (VT == MVT::v16i8) {
5267 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5269 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5270 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5272 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5273 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5275 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5276 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5278 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5279 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5281 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5282 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5284 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5285 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5289 case Intrinsic::aarch64_neon_ld2r:
5290 if (VT == MVT::v8i8) {
5291 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5293 }
else if (VT == MVT::v16i8) {
5294 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5296 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5297 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5299 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5300 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5302 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5303 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5305 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5306 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5308 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5309 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5311 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5312 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5316 case Intrinsic::aarch64_neon_ld3r:
5317 if (VT == MVT::v8i8) {
5318 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5320 }
else if (VT == MVT::v16i8) {
5321 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5323 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5324 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5326 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5327 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5329 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5330 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5332 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5333 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5335 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5336 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5338 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5339 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5343 case Intrinsic::aarch64_neon_ld4r:
5344 if (VT == MVT::v8i8) {
5345 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5347 }
else if (VT == MVT::v16i8) {
5348 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5350 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5351 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5353 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5354 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5356 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5357 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5359 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5360 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5362 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5363 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5365 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5366 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5370 case Intrinsic::aarch64_neon_ld2lane:
5371 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5372 SelectLoadLane(Node, 2, AArch64::LD2i8);
5374 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5375 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5376 SelectLoadLane(Node, 2, AArch64::LD2i16);
5378 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5380 SelectLoadLane(Node, 2, AArch64::LD2i32);
5382 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5384 SelectLoadLane(Node, 2, AArch64::LD2i64);
5388 case Intrinsic::aarch64_neon_ld3lane:
5389 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5390 SelectLoadLane(Node, 3, AArch64::LD3i8);
5392 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5393 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5394 SelectLoadLane(Node, 3, AArch64::LD3i16);
5396 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5398 SelectLoadLane(Node, 3, AArch64::LD3i32);
5400 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5402 SelectLoadLane(Node, 3, AArch64::LD3i64);
5406 case Intrinsic::aarch64_neon_ld4lane:
5407 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5408 SelectLoadLane(Node, 4, AArch64::LD4i8);
5410 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5411 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5412 SelectLoadLane(Node, 4, AArch64::LD4i16);
5414 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5416 SelectLoadLane(Node, 4, AArch64::LD4i32);
5418 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5420 SelectLoadLane(Node, 4, AArch64::LD4i64);
5424 case Intrinsic::aarch64_ld64b:
5425 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5427 case Intrinsic::aarch64_sve_ld2q_sret: {
5428 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5431 case Intrinsic::aarch64_sve_ld3q_sret: {
5432 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5435 case Intrinsic::aarch64_sve_ld4q_sret: {
5436 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5439 case Intrinsic::aarch64_sve_ld2_sret: {
5440 if (VT == MVT::nxv16i8) {
5441 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5444 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5445 VT == MVT::nxv8bf16) {
5446 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5449 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5450 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5453 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5454 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5460 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5461 if (VT == MVT::nxv16i8) {
5462 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5463 SelectContiguousMultiVectorLoad(
5464 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5465 else if (Subtarget->hasSVE2p1())
5466 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5471 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5472 VT == MVT::nxv8bf16) {
5473 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5474 SelectContiguousMultiVectorLoad(
5475 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5476 else if (Subtarget->hasSVE2p1())
5477 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5482 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5483 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5484 SelectContiguousMultiVectorLoad(
5485 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5486 else if (Subtarget->hasSVE2p1())
5487 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5492 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5493 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5494 SelectContiguousMultiVectorLoad(
5495 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5496 else if (Subtarget->hasSVE2p1())
5497 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5505 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5506 if (VT == MVT::nxv16i8) {
5507 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5508 SelectContiguousMultiVectorLoad(
5509 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5510 else if (Subtarget->hasSVE2p1())
5511 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5516 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5517 VT == MVT::nxv8bf16) {
5518 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5519 SelectContiguousMultiVectorLoad(
5520 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5521 else if (Subtarget->hasSVE2p1())
5522 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5527 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5528 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5529 SelectContiguousMultiVectorLoad(
5530 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5531 else if (Subtarget->hasSVE2p1())
5532 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5537 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5538 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5539 SelectContiguousMultiVectorLoad(
5540 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5541 else if (Subtarget->hasSVE2p1())
5542 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5550 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5551 if (VT == MVT::nxv16i8) {
5552 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5553 SelectContiguousMultiVectorLoad(Node, 2, 0,
5554 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5555 AArch64::LDNT1B_2Z_PSEUDO);
5556 else if (Subtarget->hasSVE2p1())
5557 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5558 AArch64::LDNT1B_2Z);
5562 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5563 VT == MVT::nxv8bf16) {
5564 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5565 SelectContiguousMultiVectorLoad(Node, 2, 1,
5566 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5567 AArch64::LDNT1H_2Z_PSEUDO);
5568 else if (Subtarget->hasSVE2p1())
5569 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5570 AArch64::LDNT1H_2Z);
5574 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5575 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5576 SelectContiguousMultiVectorLoad(Node, 2, 2,
5577 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5578 AArch64::LDNT1W_2Z_PSEUDO);
5579 else if (Subtarget->hasSVE2p1())
5580 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5581 AArch64::LDNT1W_2Z);
5585 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5586 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5587 SelectContiguousMultiVectorLoad(Node, 2, 3,
5588 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5589 AArch64::LDNT1D_2Z_PSEUDO);
5590 else if (Subtarget->hasSVE2p1())
5591 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5592 AArch64::LDNT1D_2Z);
5599 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5600 if (VT == MVT::nxv16i8) {
5601 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5602 SelectContiguousMultiVectorLoad(Node, 4, 0,
5603 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5604 AArch64::LDNT1B_4Z_PSEUDO);
5605 else if (Subtarget->hasSVE2p1())
5606 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5607 AArch64::LDNT1B_4Z);
5611 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5612 VT == MVT::nxv8bf16) {
5613 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5614 SelectContiguousMultiVectorLoad(Node, 4, 1,
5615 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5616 AArch64::LDNT1H_4Z_PSEUDO);
5617 else if (Subtarget->hasSVE2p1())
5618 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5619 AArch64::LDNT1H_4Z);
5623 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5624 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5625 SelectContiguousMultiVectorLoad(Node, 4, 2,
5626 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5627 AArch64::LDNT1W_4Z_PSEUDO);
5628 else if (Subtarget->hasSVE2p1())
5629 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5630 AArch64::LDNT1W_4Z);
5634 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5635 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5636 SelectContiguousMultiVectorLoad(Node, 4, 3,
5637 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5638 AArch64::LDNT1D_4Z_PSEUDO);
5639 else if (Subtarget->hasSVE2p1())
5640 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5641 AArch64::LDNT1D_4Z);
5648 case Intrinsic::aarch64_sve_ld3_sret: {
5649 if (VT == MVT::nxv16i8) {
5650 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5653 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5654 VT == MVT::nxv8bf16) {
5655 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5658 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5659 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5662 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5663 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5669 case Intrinsic::aarch64_sve_ld4_sret: {
5670 if (VT == MVT::nxv16i8) {
5671 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5674 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5675 VT == MVT::nxv8bf16) {
5676 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5679 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5680 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5683 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5684 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5690 case Intrinsic::aarch64_sme_read_hor_vg2: {
5691 if (VT == MVT::nxv16i8) {
5692 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5693 AArch64::MOVA_2ZMXI_H_B);
5695 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5696 VT == MVT::nxv8bf16) {
5697 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5698 AArch64::MOVA_2ZMXI_H_H);
5700 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5701 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5702 AArch64::MOVA_2ZMXI_H_S);
5704 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5705 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5706 AArch64::MOVA_2ZMXI_H_D);
5711 case Intrinsic::aarch64_sme_read_ver_vg2: {
5712 if (VT == MVT::nxv16i8) {
5713 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5714 AArch64::MOVA_2ZMXI_V_B);
5716 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5717 VT == MVT::nxv8bf16) {
5718 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5719 AArch64::MOVA_2ZMXI_V_H);
5721 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5722 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5723 AArch64::MOVA_2ZMXI_V_S);
5725 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5726 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5727 AArch64::MOVA_2ZMXI_V_D);
5732 case Intrinsic::aarch64_sme_read_hor_vg4: {
5733 if (VT == MVT::nxv16i8) {
5734 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5735 AArch64::MOVA_4ZMXI_H_B);
5737 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5738 VT == MVT::nxv8bf16) {
5739 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5740 AArch64::MOVA_4ZMXI_H_H);
5742 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5743 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5744 AArch64::MOVA_4ZMXI_H_S);
5746 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5747 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5748 AArch64::MOVA_4ZMXI_H_D);
5753 case Intrinsic::aarch64_sme_read_ver_vg4: {
5754 if (VT == MVT::nxv16i8) {
5755 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5756 AArch64::MOVA_4ZMXI_V_B);
5758 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5759 VT == MVT::nxv8bf16) {
5760 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5761 AArch64::MOVA_4ZMXI_V_H);
5763 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5764 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5765 AArch64::MOVA_4ZMXI_V_S);
5767 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5768 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5769 AArch64::MOVA_4ZMXI_V_D);
5774 case Intrinsic::aarch64_sme_read_vg1x2: {
5775 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5776 AArch64::MOVA_VG2_2ZMXI);
5779 case Intrinsic::aarch64_sme_read_vg1x4: {
5780 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5781 AArch64::MOVA_VG4_4ZMXI);
5784 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5785 if (VT == MVT::nxv16i8) {
5786 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5788 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5789 VT == MVT::nxv8bf16) {
5790 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5792 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5793 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5795 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5796 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5801 case Intrinsic::aarch64_sme_readz_vert_x2: {
5802 if (VT == MVT::nxv16i8) {
5803 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5805 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5806 VT == MVT::nxv8bf16) {
5807 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5809 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5810 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5812 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5813 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5818 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5819 if (VT == MVT::nxv16i8) {
5820 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5822 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5823 VT == MVT::nxv8bf16) {
5824 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5826 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5827 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5829 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5830 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5835 case Intrinsic::aarch64_sme_readz_vert_x4: {
5836 if (VT == MVT::nxv16i8) {
5837 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5839 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5840 VT == MVT::nxv8bf16) {
5841 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5843 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5844 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5846 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5847 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5852 case Intrinsic::aarch64_sme_readz_x2: {
5853 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5857 case Intrinsic::aarch64_sme_readz_x4: {
5858 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5862 case Intrinsic::swift_async_context_addr: {
5865 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5867 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5868 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5869 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5871 ReplaceUses(
SDValue(Node, 0), Res);
5873 CurDAG->RemoveDeadNode(Node);
5875 auto &MF = CurDAG->getMachineFunction();
5876 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5877 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5880 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5882 Node->getValueType(0),
5883 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5884 AArch64::LUTI2_4ZTZI_S}))
5886 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5889 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5891 Node->getValueType(0),
5892 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5894 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5897 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5899 Node->getValueType(0),
5900 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5901 AArch64::LUTI2_2ZTZI_S}))
5903 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5906 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5908 Node->getValueType(0),
5909 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5910 AArch64::LUTI4_2ZTZI_S}))
5912 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5915 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5916 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5919 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5921 Node->getValueType(0),
5922 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5923 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5925 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5927 Node->getValueType(0),
5928 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5929 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5931 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5933 Node->getValueType(0),
5934 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5935 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5937 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5939 Node->getValueType(0),
5940 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5941 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5943 case Intrinsic::ptrauth_resign_load_relative:
5944 SelectPtrauthResign(Node);
5949 unsigned IntNo =
Node->getConstantOperandVal(0);
5953 case Intrinsic::aarch64_tagp:
5957 case Intrinsic::ptrauth_auth:
5958 SelectPtrauthAuth(Node);
5961 case Intrinsic::ptrauth_resign:
5962 SelectPtrauthResign(Node);
5965 case Intrinsic::aarch64_neon_tbl2:
5966 SelectTable(Node, 2,
5967 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5970 case Intrinsic::aarch64_neon_tbl3:
5971 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5972 : AArch64::TBLv16i8Three,
5975 case Intrinsic::aarch64_neon_tbl4:
5976 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5977 : AArch64::TBLv16i8Four,
5980 case Intrinsic::aarch64_neon_tbx2:
5981 SelectTable(Node, 2,
5982 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5985 case Intrinsic::aarch64_neon_tbx3:
5986 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5987 : AArch64::TBXv16i8Three,
5990 case Intrinsic::aarch64_neon_tbx4:
5991 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5992 : AArch64::TBXv16i8Four,
5995 case Intrinsic::aarch64_sve_srshl_single_x2:
5997 Node->getValueType(0),
5998 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5999 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6000 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6002 case Intrinsic::aarch64_sve_srshl_single_x4:
6004 Node->getValueType(0),
6005 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6006 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6007 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6009 case Intrinsic::aarch64_sve_urshl_single_x2:
6011 Node->getValueType(0),
6012 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6013 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6014 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6016 case Intrinsic::aarch64_sve_urshl_single_x4:
6018 Node->getValueType(0),
6019 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6020 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6021 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6023 case Intrinsic::aarch64_sve_srshl_x2:
6025 Node->getValueType(0),
6026 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6027 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6028 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6030 case Intrinsic::aarch64_sve_srshl_x4:
6032 Node->getValueType(0),
6033 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6034 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6035 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6037 case Intrinsic::aarch64_sve_urshl_x2:
6039 Node->getValueType(0),
6040 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6041 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6042 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6044 case Intrinsic::aarch64_sve_urshl_x4:
6046 Node->getValueType(0),
6047 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6048 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6049 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6051 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6053 Node->getValueType(0),
6054 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6055 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6056 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6058 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6060 Node->getValueType(0),
6061 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6062 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6063 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6065 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6067 Node->getValueType(0),
6068 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6069 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6070 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6072 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6074 Node->getValueType(0),
6075 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6076 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6077 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6079 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6081 Node->getValueType(0),
6082 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6083 AArch64::FSCALE_2ZZ_D}))
6084 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6086 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6088 Node->getValueType(0),
6089 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6090 AArch64::FSCALE_4ZZ_D}))
6091 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6093 case Intrinsic::aarch64_sme_fp8_scale_x2:
6095 Node->getValueType(0),
6096 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6097 AArch64::FSCALE_2Z2Z_D}))
6098 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6100 case Intrinsic::aarch64_sme_fp8_scale_x4:
6102 Node->getValueType(0),
6103 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6104 AArch64::FSCALE_4Z4Z_D}))
6105 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6107 case Intrinsic::aarch64_sve_whilege_x2:
6109 Node->getValueType(0),
6110 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6111 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6112 SelectWhilePair(Node,
Op);
6114 case Intrinsic::aarch64_sve_whilegt_x2:
6116 Node->getValueType(0),
6117 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6118 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6119 SelectWhilePair(Node,
Op);
6121 case Intrinsic::aarch64_sve_whilehi_x2:
6123 Node->getValueType(0),
6124 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6125 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6126 SelectWhilePair(Node,
Op);
6128 case Intrinsic::aarch64_sve_whilehs_x2:
6130 Node->getValueType(0),
6131 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6132 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6133 SelectWhilePair(Node,
Op);
6135 case Intrinsic::aarch64_sve_whilele_x2:
6137 Node->getValueType(0),
6138 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6139 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6140 SelectWhilePair(Node,
Op);
6142 case Intrinsic::aarch64_sve_whilelo_x2:
6144 Node->getValueType(0),
6145 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6146 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6147 SelectWhilePair(Node,
Op);
6149 case Intrinsic::aarch64_sve_whilels_x2:
6151 Node->getValueType(0),
6152 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6153 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6154 SelectWhilePair(Node,
Op);
6156 case Intrinsic::aarch64_sve_whilelt_x2:
6158 Node->getValueType(0),
6159 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6160 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6161 SelectWhilePair(Node,
Op);
6163 case Intrinsic::aarch64_sve_smax_single_x2:
6165 Node->getValueType(0),
6166 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6167 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6168 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6170 case Intrinsic::aarch64_sve_umax_single_x2:
6172 Node->getValueType(0),
6173 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6174 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6175 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6177 case Intrinsic::aarch64_sve_fmax_single_x2:
6179 Node->getValueType(0),
6180 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6181 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6182 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6184 case Intrinsic::aarch64_sve_smax_single_x4:
6186 Node->getValueType(0),
6187 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6188 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6189 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6191 case Intrinsic::aarch64_sve_umax_single_x4:
6193 Node->getValueType(0),
6194 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6195 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6196 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6198 case Intrinsic::aarch64_sve_fmax_single_x4:
6200 Node->getValueType(0),
6201 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6202 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6203 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6205 case Intrinsic::aarch64_sve_smin_single_x2:
6207 Node->getValueType(0),
6208 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6209 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6210 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6212 case Intrinsic::aarch64_sve_umin_single_x2:
6214 Node->getValueType(0),
6215 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6216 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6217 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6219 case Intrinsic::aarch64_sve_fmin_single_x2:
6221 Node->getValueType(0),
6222 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6223 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6224 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6226 case Intrinsic::aarch64_sve_smin_single_x4:
6228 Node->getValueType(0),
6229 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6230 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6231 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6233 case Intrinsic::aarch64_sve_umin_single_x4:
6235 Node->getValueType(0),
6236 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6237 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6238 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6240 case Intrinsic::aarch64_sve_fmin_single_x4:
6242 Node->getValueType(0),
6243 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6244 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6245 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6247 case Intrinsic::aarch64_sve_smax_x2:
6249 Node->getValueType(0),
6250 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6251 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6252 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6254 case Intrinsic::aarch64_sve_umax_x2:
6256 Node->getValueType(0),
6257 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6258 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6259 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6261 case Intrinsic::aarch64_sve_fmax_x2:
6263 Node->getValueType(0),
6264 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6265 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6266 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6268 case Intrinsic::aarch64_sve_smax_x4:
6270 Node->getValueType(0),
6271 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6272 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6273 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6275 case Intrinsic::aarch64_sve_umax_x4:
6277 Node->getValueType(0),
6278 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6279 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6280 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6282 case Intrinsic::aarch64_sve_fmax_x4:
6284 Node->getValueType(0),
6285 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6286 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6287 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6289 case Intrinsic::aarch64_sme_famax_x2:
6291 Node->getValueType(0),
6292 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6293 AArch64::FAMAX_2Z2Z_D}))
6294 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6296 case Intrinsic::aarch64_sme_famax_x4:
6298 Node->getValueType(0),
6299 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6300 AArch64::FAMAX_4Z4Z_D}))
6301 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6303 case Intrinsic::aarch64_sme_famin_x2:
6305 Node->getValueType(0),
6306 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6307 AArch64::FAMIN_2Z2Z_D}))
6308 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6310 case Intrinsic::aarch64_sme_famin_x4:
6312 Node->getValueType(0),
6313 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6314 AArch64::FAMIN_4Z4Z_D}))
6315 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6317 case Intrinsic::aarch64_sve_smin_x2:
6319 Node->getValueType(0),
6320 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6321 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6322 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6324 case Intrinsic::aarch64_sve_umin_x2:
6326 Node->getValueType(0),
6327 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6328 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6329 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6331 case Intrinsic::aarch64_sve_fmin_x2:
6333 Node->getValueType(0),
6334 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6335 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6336 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6338 case Intrinsic::aarch64_sve_smin_x4:
6340 Node->getValueType(0),
6341 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6342 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6343 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6345 case Intrinsic::aarch64_sve_umin_x4:
6347 Node->getValueType(0),
6348 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6349 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6350 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6352 case Intrinsic::aarch64_sve_fmin_x4:
6354 Node->getValueType(0),
6355 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6356 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6357 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6359 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6361 Node->getValueType(0),
6362 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6363 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6364 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6366 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6368 Node->getValueType(0),
6369 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6370 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6371 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6373 case Intrinsic::aarch64_sve_fminnm_single_x2:
6375 Node->getValueType(0),
6376 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6377 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6378 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6380 case Intrinsic::aarch64_sve_fminnm_single_x4:
6382 Node->getValueType(0),
6383 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6384 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6385 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6387 case Intrinsic::aarch64_sve_fscale_single_x4:
6388 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6390 case Intrinsic::aarch64_sve_fscale_single_x2:
6391 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6393 case Intrinsic::aarch64_sve_fmul_single_x4:
6395 Node->getValueType(0),
6396 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6397 AArch64::FMUL_4ZZ_D}))
6398 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6400 case Intrinsic::aarch64_sve_fmul_single_x2:
6402 Node->getValueType(0),
6403 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6404 AArch64::FMUL_2ZZ_D}))
6405 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6407 case Intrinsic::aarch64_sve_fmaxnm_x2:
6409 Node->getValueType(0),
6410 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6411 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6412 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6414 case Intrinsic::aarch64_sve_fmaxnm_x4:
6416 Node->getValueType(0),
6417 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6418 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6419 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6421 case Intrinsic::aarch64_sve_fminnm_x2:
6423 Node->getValueType(0),
6424 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6425 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6426 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6428 case Intrinsic::aarch64_sve_fminnm_x4:
6430 Node->getValueType(0),
6431 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6432 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6433 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6435 case Intrinsic::aarch64_sve_aese_lane_x2:
6436 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6438 case Intrinsic::aarch64_sve_aesd_lane_x2:
6439 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6441 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6442 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6444 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6445 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6447 case Intrinsic::aarch64_sve_aese_lane_x4:
6448 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6450 case Intrinsic::aarch64_sve_aesd_lane_x4:
6451 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6453 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6454 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6456 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6457 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6459 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6460 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6462 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6466 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6468 for (
unsigned I = 0;
I < 2;
I++)
6470 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6472 CurDAG->RemoveDeadNode(Node);
6475 case Intrinsic::aarch64_sve_fscale_x4:
6476 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6478 case Intrinsic::aarch64_sve_fscale_x2:
6479 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6481 case Intrinsic::aarch64_sve_fmul_x4:
6483 Node->getValueType(0),
6484 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6485 AArch64::FMUL_4Z4Z_D}))
6486 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6488 case Intrinsic::aarch64_sve_fmul_x2:
6490 Node->getValueType(0),
6491 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6492 AArch64::FMUL_2Z2Z_D}))
6493 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6495 case Intrinsic::aarch64_sve_fcvtzs_x2:
6496 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6498 case Intrinsic::aarch64_sve_scvtf_x2:
6499 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6501 case Intrinsic::aarch64_sve_fcvtzu_x2:
6502 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6504 case Intrinsic::aarch64_sve_ucvtf_x2:
6505 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6507 case Intrinsic::aarch64_sve_fcvtzs_x4:
6508 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6510 case Intrinsic::aarch64_sve_scvtf_x4:
6511 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6513 case Intrinsic::aarch64_sve_fcvtzu_x4:
6514 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6516 case Intrinsic::aarch64_sve_ucvtf_x4:
6517 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6519 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6520 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6522 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6523 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6525 case Intrinsic::aarch64_sve_sclamp_single_x2:
6527 Node->getValueType(0),
6528 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6529 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6530 SelectClamp(Node, 2,
Op);
6532 case Intrinsic::aarch64_sve_uclamp_single_x2:
6534 Node->getValueType(0),
6535 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6536 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6537 SelectClamp(Node, 2,
Op);
6539 case Intrinsic::aarch64_sve_fclamp_single_x2:
6541 Node->getValueType(0),
6542 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6543 AArch64::FCLAMP_VG2_2Z2Z_D}))
6544 SelectClamp(Node, 2,
Op);
6546 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6547 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6549 case Intrinsic::aarch64_sve_sclamp_single_x4:
6551 Node->getValueType(0),
6552 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6553 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6554 SelectClamp(Node, 4,
Op);
6556 case Intrinsic::aarch64_sve_uclamp_single_x4:
6558 Node->getValueType(0),
6559 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6560 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6561 SelectClamp(Node, 4,
Op);
6563 case Intrinsic::aarch64_sve_fclamp_single_x4:
6565 Node->getValueType(0),
6566 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6567 AArch64::FCLAMP_VG4_4Z4Z_D}))
6568 SelectClamp(Node, 4,
Op);
6570 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6571 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6573 case Intrinsic::aarch64_sve_add_single_x2:
6575 Node->getValueType(0),
6576 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6577 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6578 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6580 case Intrinsic::aarch64_sve_add_single_x4:
6582 Node->getValueType(0),
6583 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6584 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6585 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6587 case Intrinsic::aarch64_sve_zip_x2:
6589 Node->getValueType(0),
6590 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6591 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6592 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6594 case Intrinsic::aarch64_sve_zipq_x2:
6595 SelectUnaryMultiIntrinsic(Node, 2,
false,
6596 AArch64::ZIP_VG2_2ZZZ_Q);
6598 case Intrinsic::aarch64_sve_zip_x4:
6600 Node->getValueType(0),
6601 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6602 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6603 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6605 case Intrinsic::aarch64_sve_zipq_x4:
6606 SelectUnaryMultiIntrinsic(Node, 4,
true,
6607 AArch64::ZIP_VG4_4Z4Z_Q);
6609 case Intrinsic::aarch64_sve_uzp_x2:
6611 Node->getValueType(0),
6612 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6613 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6614 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6616 case Intrinsic::aarch64_sve_uzpq_x2:
6617 SelectUnaryMultiIntrinsic(Node, 2,
false,
6618 AArch64::UZP_VG2_2ZZZ_Q);
6620 case Intrinsic::aarch64_sve_uzp_x4:
6622 Node->getValueType(0),
6623 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6624 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6625 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6627 case Intrinsic::aarch64_sve_uzpq_x4:
6628 SelectUnaryMultiIntrinsic(Node, 4,
true,
6629 AArch64::UZP_VG4_4Z4Z_Q);
6631 case Intrinsic::aarch64_sve_sel_x2:
6633 Node->getValueType(0),
6634 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6635 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6636 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6638 case Intrinsic::aarch64_sve_sel_x4:
6640 Node->getValueType(0),
6641 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6642 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6643 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6645 case Intrinsic::aarch64_sve_frinta_x2:
6646 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6648 case Intrinsic::aarch64_sve_frinta_x4:
6649 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6651 case Intrinsic::aarch64_sve_frintm_x2:
6652 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6654 case Intrinsic::aarch64_sve_frintm_x4:
6655 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6657 case Intrinsic::aarch64_sve_frintn_x2:
6658 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6660 case Intrinsic::aarch64_sve_frintn_x4:
6661 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6663 case Intrinsic::aarch64_sve_frintp_x2:
6664 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6666 case Intrinsic::aarch64_sve_frintp_x4:
6667 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6669 case Intrinsic::aarch64_sve_sunpk_x2:
6671 Node->getValueType(0),
6672 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6673 AArch64::SUNPK_VG2_2ZZ_D}))
6674 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6676 case Intrinsic::aarch64_sve_uunpk_x2:
6678 Node->getValueType(0),
6679 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6680 AArch64::UUNPK_VG2_2ZZ_D}))
6681 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6683 case Intrinsic::aarch64_sve_sunpk_x4:
6685 Node->getValueType(0),
6686 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6687 AArch64::SUNPK_VG4_4Z2Z_D}))
6688 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6690 case Intrinsic::aarch64_sve_uunpk_x4:
6692 Node->getValueType(0),
6693 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6694 AArch64::UUNPK_VG4_4Z2Z_D}))
6695 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6697 case Intrinsic::aarch64_sve_pext_x2: {
6699 Node->getValueType(0),
6700 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6701 AArch64::PEXT_2PCI_D}))
6702 SelectPExtPair(Node,
Op);
6709 unsigned IntNo =
Node->getConstantOperandVal(1);
6710 if (
Node->getNumOperands() >= 3)
6711 VT =
Node->getOperand(2)->getValueType(0);
6715 case Intrinsic::aarch64_neon_st1x2: {
6716 if (VT == MVT::v8i8) {
6717 SelectStore(Node, 2, AArch64::ST1Twov8b);
6719 }
else if (VT == MVT::v16i8) {
6720 SelectStore(Node, 2, AArch64::ST1Twov16b);
6722 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6723 VT == MVT::v4bf16) {
6724 SelectStore(Node, 2, AArch64::ST1Twov4h);
6726 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6727 VT == MVT::v8bf16) {
6728 SelectStore(Node, 2, AArch64::ST1Twov8h);
6730 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6731 SelectStore(Node, 2, AArch64::ST1Twov2s);
6733 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6734 SelectStore(Node, 2, AArch64::ST1Twov4s);
6736 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6737 SelectStore(Node, 2, AArch64::ST1Twov2d);
6739 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6740 SelectStore(Node, 2, AArch64::ST1Twov1d);
6745 case Intrinsic::aarch64_neon_st1x3: {
6746 if (VT == MVT::v8i8) {
6747 SelectStore(Node, 3, AArch64::ST1Threev8b);
6749 }
else if (VT == MVT::v16i8) {
6750 SelectStore(Node, 3, AArch64::ST1Threev16b);
6752 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6753 VT == MVT::v4bf16) {
6754 SelectStore(Node, 3, AArch64::ST1Threev4h);
6756 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6757 VT == MVT::v8bf16) {
6758 SelectStore(Node, 3, AArch64::ST1Threev8h);
6760 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6761 SelectStore(Node, 3, AArch64::ST1Threev2s);
6763 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6764 SelectStore(Node, 3, AArch64::ST1Threev4s);
6766 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6767 SelectStore(Node, 3, AArch64::ST1Threev2d);
6769 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6770 SelectStore(Node, 3, AArch64::ST1Threev1d);
6775 case Intrinsic::aarch64_neon_st1x4: {
6776 if (VT == MVT::v8i8) {
6777 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6779 }
else if (VT == MVT::v16i8) {
6780 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6782 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6783 VT == MVT::v4bf16) {
6784 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6786 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6787 VT == MVT::v8bf16) {
6788 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6790 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6791 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6793 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6794 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6796 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6797 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6799 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6800 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6805 case Intrinsic::aarch64_neon_st2: {
6806 if (VT == MVT::v8i8) {
6807 SelectStore(Node, 2, AArch64::ST2Twov8b);
6809 }
else if (VT == MVT::v16i8) {
6810 SelectStore(Node, 2, AArch64::ST2Twov16b);
6812 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6813 VT == MVT::v4bf16) {
6814 SelectStore(Node, 2, AArch64::ST2Twov4h);
6816 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6817 VT == MVT::v8bf16) {
6818 SelectStore(Node, 2, AArch64::ST2Twov8h);
6820 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6821 SelectStore(Node, 2, AArch64::ST2Twov2s);
6823 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6824 SelectStore(Node, 2, AArch64::ST2Twov4s);
6826 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6827 SelectStore(Node, 2, AArch64::ST2Twov2d);
6829 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6830 SelectStore(Node, 2, AArch64::ST1Twov1d);
6835 case Intrinsic::aarch64_neon_st3: {
6836 if (VT == MVT::v8i8) {
6837 SelectStore(Node, 3, AArch64::ST3Threev8b);
6839 }
else if (VT == MVT::v16i8) {
6840 SelectStore(Node, 3, AArch64::ST3Threev16b);
6842 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6843 VT == MVT::v4bf16) {
6844 SelectStore(Node, 3, AArch64::ST3Threev4h);
6846 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6847 VT == MVT::v8bf16) {
6848 SelectStore(Node, 3, AArch64::ST3Threev8h);
6850 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6851 SelectStore(Node, 3, AArch64::ST3Threev2s);
6853 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6854 SelectStore(Node, 3, AArch64::ST3Threev4s);
6856 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6857 SelectStore(Node, 3, AArch64::ST3Threev2d);
6859 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6860 SelectStore(Node, 3, AArch64::ST1Threev1d);
6865 case Intrinsic::aarch64_neon_st4: {
6866 if (VT == MVT::v8i8) {
6867 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6869 }
else if (VT == MVT::v16i8) {
6870 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6872 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6873 VT == MVT::v4bf16) {
6874 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6876 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6877 VT == MVT::v8bf16) {
6878 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6880 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6881 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6883 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6884 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6886 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6887 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6889 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6890 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6895 case Intrinsic::aarch64_neon_st2lane: {
6896 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6897 SelectStoreLane(Node, 2, AArch64::ST2i8);
6899 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6900 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6901 SelectStoreLane(Node, 2, AArch64::ST2i16);
6903 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6905 SelectStoreLane(Node, 2, AArch64::ST2i32);
6907 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6909 SelectStoreLane(Node, 2, AArch64::ST2i64);
6914 case Intrinsic::aarch64_neon_st3lane: {
6915 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6916 SelectStoreLane(Node, 3, AArch64::ST3i8);
6918 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6919 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6920 SelectStoreLane(Node, 3, AArch64::ST3i16);
6922 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6924 SelectStoreLane(Node, 3, AArch64::ST3i32);
6926 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6928 SelectStoreLane(Node, 3, AArch64::ST3i64);
6933 case Intrinsic::aarch64_neon_st4lane: {
6934 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6935 SelectStoreLane(Node, 4, AArch64::ST4i8);
6937 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6938 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6939 SelectStoreLane(Node, 4, AArch64::ST4i16);
6941 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6943 SelectStoreLane(Node, 4, AArch64::ST4i32);
6945 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6947 SelectStoreLane(Node, 4, AArch64::ST4i64);
6952 case Intrinsic::aarch64_sve_st2q: {
6953 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6956 case Intrinsic::aarch64_sve_st3q: {
6957 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6960 case Intrinsic::aarch64_sve_st4q: {
6961 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6964 case Intrinsic::aarch64_sve_st2: {
6965 if (VT == MVT::nxv16i8) {
6966 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6968 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6969 VT == MVT::nxv8bf16) {
6970 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6972 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6973 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6975 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6976 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6981 case Intrinsic::aarch64_sve_st3: {
6982 if (VT == MVT::nxv16i8) {
6983 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6985 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6986 VT == MVT::nxv8bf16) {
6987 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6989 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6990 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6992 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6993 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6998 case Intrinsic::aarch64_sve_st4: {
6999 if (VT == MVT::nxv16i8) {
7000 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7002 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7003 VT == MVT::nxv8bf16) {
7004 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7006 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7007 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7009 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7010 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7018 case AArch64ISD::LD2post: {
7019 if (VT == MVT::v8i8) {
7020 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7022 }
else if (VT == MVT::v16i8) {
7023 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7025 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7026 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7028 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7029 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7031 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7032 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7034 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7035 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7037 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7038 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7040 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7041 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7046 case AArch64ISD::LD3post: {
7047 if (VT == MVT::v8i8) {
7048 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7050 }
else if (VT == MVT::v16i8) {
7051 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7053 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7054 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7056 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7057 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7059 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7060 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7062 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7063 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7065 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7066 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7068 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7069 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7074 case AArch64ISD::LD4post: {
7075 if (VT == MVT::v8i8) {
7076 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7078 }
else if (VT == MVT::v16i8) {
7079 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7081 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7082 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7084 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7085 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7087 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7088 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7090 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7091 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7093 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7094 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7096 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7097 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7102 case AArch64ISD::LD1x2post: {
7103 if (VT == MVT::v8i8) {
7104 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7106 }
else if (VT == MVT::v16i8) {
7107 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7109 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7110 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7112 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7113 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7115 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7116 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7118 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7119 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7121 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7122 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7124 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7125 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7130 case AArch64ISD::LD1x3post: {
7131 if (VT == MVT::v8i8) {
7132 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7134 }
else if (VT == MVT::v16i8) {
7135 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7137 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7138 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7140 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7141 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7143 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7144 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7146 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7147 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7149 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7150 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7152 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7153 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7158 case AArch64ISD::LD1x4post: {
7159 if (VT == MVT::v8i8) {
7160 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7162 }
else if (VT == MVT::v16i8) {
7163 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7165 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7166 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7168 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7169 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7171 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7172 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7174 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7175 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7177 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7178 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7180 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7181 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7186 case AArch64ISD::LD1DUPpost: {
7187 if (VT == MVT::v8i8) {
7188 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7190 }
else if (VT == MVT::v16i8) {
7191 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7193 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7194 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7196 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7197 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7199 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7200 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7202 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7203 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7205 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7206 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7208 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7209 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7214 case AArch64ISD::LD2DUPpost: {
7215 if (VT == MVT::v8i8) {
7216 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7218 }
else if (VT == MVT::v16i8) {
7219 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7221 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7222 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7224 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7225 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7227 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7228 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7230 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7231 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7233 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7234 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7236 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7237 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7242 case AArch64ISD::LD3DUPpost: {
7243 if (VT == MVT::v8i8) {
7244 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7246 }
else if (VT == MVT::v16i8) {
7247 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7249 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7250 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7252 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7253 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7255 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7256 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7258 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7259 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7261 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7262 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7264 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7265 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7270 case AArch64ISD::LD4DUPpost: {
7271 if (VT == MVT::v8i8) {
7272 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7274 }
else if (VT == MVT::v16i8) {
7275 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7277 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7278 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7280 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7281 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7283 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7284 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7286 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7287 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7289 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7290 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7292 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7293 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7298 case AArch64ISD::LD1LANEpost: {
7299 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7300 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7302 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7303 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7304 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7306 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7308 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7310 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7312 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7317 case AArch64ISD::LD2LANEpost: {
7318 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7319 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7321 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7322 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7323 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7325 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7327 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7329 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7331 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7336 case AArch64ISD::LD3LANEpost: {
7337 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7338 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7340 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7341 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7342 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7344 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7346 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7348 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7350 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7355 case AArch64ISD::LD4LANEpost: {
7356 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7357 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7359 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7360 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7361 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7363 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7365 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7367 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7369 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7374 case AArch64ISD::ST2post: {
7375 VT =
Node->getOperand(1).getValueType();
7376 if (VT == MVT::v8i8) {
7377 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7379 }
else if (VT == MVT::v16i8) {
7380 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7382 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7383 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7385 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7386 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7388 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7389 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7391 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7392 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7394 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7395 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7397 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7398 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7403 case AArch64ISD::ST3post: {
7404 VT =
Node->getOperand(1).getValueType();
7405 if (VT == MVT::v8i8) {
7406 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7408 }
else if (VT == MVT::v16i8) {
7409 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7411 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7412 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7414 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7415 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7417 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7418 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7420 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7421 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7423 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7424 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7426 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7427 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7432 case AArch64ISD::ST4post: {
7433 VT =
Node->getOperand(1).getValueType();
7434 if (VT == MVT::v8i8) {
7435 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7437 }
else if (VT == MVT::v16i8) {
7438 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7440 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7441 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7443 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7444 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7446 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7447 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7449 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7450 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7452 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7453 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7455 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7456 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7461 case AArch64ISD::ST1x2post: {
7462 VT =
Node->getOperand(1).getValueType();
7463 if (VT == MVT::v8i8) {
7464 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7466 }
else if (VT == MVT::v16i8) {
7467 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7469 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7470 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7472 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7473 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7475 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7476 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7478 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7479 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7481 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7482 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7484 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7485 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7490 case AArch64ISD::ST1x3post: {
7491 VT =
Node->getOperand(1).getValueType();
7492 if (VT == MVT::v8i8) {
7493 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7495 }
else if (VT == MVT::v16i8) {
7496 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7498 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7499 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7501 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7502 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7504 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7505 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7507 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7508 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7510 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7511 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7513 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7514 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7519 case AArch64ISD::ST1x4post: {
7520 VT =
Node->getOperand(1).getValueType();
7521 if (VT == MVT::v8i8) {
7522 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7524 }
else if (VT == MVT::v16i8) {
7525 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7527 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7528 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7530 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7531 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7533 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7534 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7536 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7537 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7539 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7540 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7542 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7543 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7548 case AArch64ISD::ST2LANEpost: {
7549 VT =
Node->getOperand(1).getValueType();
7550 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7551 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7553 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7554 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7555 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7557 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7559 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7561 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7563 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7568 case AArch64ISD::ST3LANEpost: {
7569 VT =
Node->getOperand(1).getValueType();
7570 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7571 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7573 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7574 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7575 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7577 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7579 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7581 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7583 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7588 case AArch64ISD::ST4LANEpost: {
7589 VT =
Node->getOperand(1).getValueType();
7590 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7591 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7593 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7594 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7595 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7597 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7599 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7601 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7603 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7618 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7630 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7634 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7635 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7650 return MemIntr->getMemoryVT();
7657 DataVT = Load->getValueType(0);
7659 DataVT = Load->getValueType(0);
7661 DataVT = Store->getValue().getValueType();
7663 DataVT = Store->getValue().getValueType();
7670 const unsigned Opcode = Root->
getOpcode();
7674 case AArch64ISD::LD1_MERGE_ZERO:
7675 case AArch64ISD::LD1S_MERGE_ZERO:
7676 case AArch64ISD::LDNF1_MERGE_ZERO:
7677 case AArch64ISD::LDNF1S_MERGE_ZERO:
7679 case AArch64ISD::ST1_PRED:
7691 case Intrinsic::aarch64_sme_ldr:
7692 case Intrinsic::aarch64_sme_str:
7693 return MVT::nxv16i8;
7694 case Intrinsic::aarch64_sve_prf:
7699 case Intrinsic::aarch64_sve_ld2_sret:
7700 case Intrinsic::aarch64_sve_ld2q_sret:
7703 case Intrinsic::aarch64_sve_st2q:
7706 case Intrinsic::aarch64_sve_ld3_sret:
7707 case Intrinsic::aarch64_sve_ld3q_sret:
7710 case Intrinsic::aarch64_sve_st3q:
7713 case Intrinsic::aarch64_sve_ld4_sret:
7714 case Intrinsic::aarch64_sve_ld4q_sret:
7717 case Intrinsic::aarch64_sve_st4q:
7720 case Intrinsic::aarch64_sve_ld1udq:
7721 case Intrinsic::aarch64_sve_st1dq:
7722 return EVT(MVT::nxv1i64);
7723 case Intrinsic::aarch64_sve_ld1uwq:
7724 case Intrinsic::aarch64_sve_st1wq:
7725 return EVT(MVT::nxv1i32);
7732template <
int64_t Min,
int64_t Max>
7733bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7737 const DataLayout &
DL = CurDAG->getDataLayout();
7738 const MachineFrameInfo &MFI = MF->getFrameInfo();
7746 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7760 int64_t MulImm = std::numeric_limits<int64_t>::max();
7764 int64_t ByteOffset =
C->getSExtValue();
7765 const auto KnownVScale =
7768 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7771 MulImm = ByteOffset / KnownVScale;
7778 if ((MulImm % MemWidthBytes) != 0)
7781 int64_t
Offset = MulImm / MemWidthBytes;
7785 Base =
N.getOperand(0);
7794 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7800bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7819 int64_t ImmOff =
C->getSExtValue();
7820 unsigned Size = 1 << Scale;
7829 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7831 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7842 if (
C->getZExtValue() == Scale) {
7851bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7852 const AArch64TargetLowering *TLI =
7853 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7858bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7859 EVT VT =
N.getValueType();
7863bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7868 int64_t ImmOff =
C->getSExtValue();
7869 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7870 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7875 if (
SDValue C = MatchConstantOffset(
N)) {
7876 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7882 if (CurDAG->isBaseWithConstantOffset(
N)) {
7883 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7884 Base =
N.getOperand(0);
7892 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7896bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7916 uint64_t LowerBound = 0, UpperBound = 64;
7934 if (CN->getAPIntValue().uge(LowerBound) &&
7935 CN->getAPIntValue().ult(UpperBound)) {
7937 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7945template <
bool MatchCBB>
7952 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7954 Reg =
N.getOperand(0);
7956 SDLoc(
N), MVT::i32);
7964 Reg =
N.getOperand(0);
7973void AArch64DAGToDAGISel::PreprocessISelDAG() {
7974 bool MadeChange =
false;
7980 switch (
N.getOpcode()) {
7982 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
7983 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
7984 ScalarTy ==
N.getOperand(0).getValueType())
7994 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8000 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
8006 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 isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static APInt DecodeFMOVImm(uint64_t Imm, unsigned RegWidth)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const AArch64RegisterInfo * getRegisterInfo() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static 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.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.