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;
69 std::vector<SDValue> &OutOps)
override;
71 template <
signed Low,
signed High,
signed Scale>
79 return SelectShiftedRegister(
N,
false, Reg, Shift);
82 return SelectShiftedRegister(
N,
true, Reg, Shift);
85 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
88 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
91 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
94 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
97 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
100 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
103 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
106 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
109 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
112 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
115 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
118 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
121 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
124 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
127 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
130 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
133 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
135 template <
unsigned Size,
unsigned Max>
139 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
141 if (
auto *CI = dyn_cast<ConstantSDNode>(OffImm)) {
142 int64_t
C = CI->getSExtValue();
150 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
157 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
163 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
168 N =
N->getOperand(0);
170 !isa<ConstantSDNode>(
N->getOperand(1)))
172 EVT VT =
N->getValueType(0);
173 EVT LVT =
N->getOperand(0).getValueType();
174 unsigned Index =
N->getConstantOperandVal(1);
178 Res =
N->getOperand(0);
183 if (
N.getOpcode() != AArch64ISD::VLSHR)
186 EVT VT =
Op.getValueType();
187 unsigned ShtAmt =
N->getConstantOperandVal(1);
192 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
194 Op.getOperand(1).getConstantOperandVal(0)
195 <<
Op.getOperand(1).getConstantOperandVal(1));
196 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
197 isa<ConstantSDNode>(
Op.getOperand(1).getOperand(0)))
199 Op.getOperand(1).getConstantOperandVal(0));
203 if (Imm != 1ULL << (ShtAmt - 1))
206 Res1 =
Op.getOperand(0);
207 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
211 bool SelectDupZeroOrUndef(
SDValue N) {
212 switch(
N->getOpcode()) {
215 case AArch64ISD::DUP:
217 auto Opnd0 =
N->getOperand(0);
231 bool SelectAny(
SDValue) {
return true; }
234 switch(
N->getOpcode()) {
235 case AArch64ISD::DUP:
237 auto Opnd0 =
N->getOperand(0);
249 template<MVT::SimpleValueType VT>
251 return SelectSVEAddSubImm(
N, VT, Imm, Shift);
254 template <MVT::SimpleValueType VT,
bool Negate>
256 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
259 template <MVT::SimpleValueType VT>
261 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
264 template <MVT::SimpleValueType VT,
bool Invert = false>
266 return SelectSVELogicalImm(
N, VT, Imm, Invert);
269 template <MVT::SimpleValueType VT>
271 return SelectSVEArithImm(
N, VT, Imm);
274 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
276 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
283 EVT EltVT =
N->getValueType(0).getVectorElementType();
284 return SelectSVEShiftImm(
N->getOperand(0), 1,
290 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
292 if (!isa<ConstantSDNode>(
N))
295 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
297 MulImm = 1LL << MulImm;
299 if ((MulImm % std::abs(Scale)) != 0)
303 if ((MulImm >= Min) && (MulImm <= Max)) {
304 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
311 template <
signed Max,
signed Scale>
313 if (!isa<ConstantSDNode>(
N))
316 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
318 if (MulImm >= 0 && MulImm <= Max) {
320 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
327 template <
unsigned BaseReg,
unsigned Max>
329 if (
auto *CI = dyn_cast<ConstantSDNode>(
N)) {
335 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
358 const unsigned SubRegs[]);
360 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
362 bool tryIndexedLoad(
SDNode *
N);
364 void SelectPtrauthAuth(
SDNode *
N);
365 void SelectPtrauthResign(
SDNode *
N);
367 bool trySelectStackSlotTagP(
SDNode *
N);
370 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
372 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
374 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
375 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
376 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
377 unsigned Opc_rr,
unsigned Opc_ri,
378 bool IsIntr =
false);
379 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
380 unsigned Scale,
unsigned Opc_ri,
382 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
383 bool IsZmMulti,
unsigned Opcode,
384 bool HasPred =
false);
386 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
387 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
388 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
389 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
390 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
391 bool IsTupleInput,
unsigned Opc);
392 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 template <
unsigned MaxIdx,
unsigned Scale>
395 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
397 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
398 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
399 unsigned BaseReg = 0);
402 template <
int64_t Min,
int64_t Max>
406 template <
unsigned Scale>
408 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
411 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
414 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
416 template <
unsigned MaxIdx,
unsigned Scale>
421 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
422 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
423 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
424 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
425 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
426 unsigned Opc_rr,
unsigned Opc_ri);
427 std::tuple<unsigned, SDValue, SDValue>
428 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
432 bool tryBitfieldExtractOp(
SDNode *
N);
433 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
434 bool tryBitfieldInsertOp(
SDNode *
N);
435 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
436 bool tryShiftAmountMod(
SDNode *
N);
438 bool tryReadRegister(
SDNode *
N);
439 bool tryWriteRegister(
SDNode *
N);
441 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
442 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
447#include "AArch64GenDAGISel.inc"
455 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
457 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
470 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
471 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
472 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
475 template<
unsigned RegW
idth>
477 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
480 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
482 template<
unsigned RegW
idth>
484 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
490 bool SelectCMP_SWAP(
SDNode *
N);
500 bool AllowSaturation,
SDValue &Imm);
508 bool SelectAllActivePredicate(
SDValue N);
520 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
524char AArch64DAGToDAGISelLegacy::ID = 0;
532 Imm =
C->getZExtValue();
549 return N->getOpcode() ==
Opc &&
560 return Imm == ImmExpected;
564bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
566 std::vector<SDValue> &OutOps) {
567 switch(ConstraintID) {
570 case InlineAsm::ConstraintCode::m:
571 case InlineAsm::ConstraintCode::o:
572 case InlineAsm::ConstraintCode::Q:
578 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
580 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
581 dl,
Op.getValueType(),
583 OutOps.push_back(NewOp);
599 if (!isa<ConstantSDNode>(
N.getNode()))
602 uint64_t Immed =
N.getNode()->getAsZExtVal();
605 if (Immed >> 12 == 0) {
607 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
615 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
616 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
629 if (!isa<ConstantSDNode>(
N.getNode()))
633 uint64_t Immed =
N.getNode()->getAsZExtVal();
641 if (
N.getValueType() == MVT::i32)
644 Immed = ~Immed + 1ULL;
645 if (Immed & 0xFFFFFFFFFF000000ULL)
648 Immed &= 0xFFFFFFULL;
649 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(
N), MVT::i32), Val,
656 switch (
N.getOpcode()) {
671 return isa<MemSDNode>(*
N) ||
N->getOpcode() == AArch64ISD::PREFETCH;
679 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
682 unsigned ShiftVal = CSD->getZExtValue();
700bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
703 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
708 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
730bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(
SDValue N,
SDValue &Reg,
732 EVT VT =
N.getValueType();
733 if (VT != MVT::i32 && VT != MVT::i64)
736 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
742 unsigned LHSOpcode =
LHS->getOpcode();
756 unsigned LowZBits, MaskLen;
760 unsigned BitWidth =
N.getValueSizeInBits();
767 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
770 NewShiftC = LowZBits - ShiftAmtC;
771 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
777 NewShiftC = LowZBits + ShiftAmtC;
790 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
792 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
796 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
798 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
799 NewShiftAmt, BitWidthMinus1),
802 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
814 SrcVT = cast<VTSDNode>(
N.getOperand(1))->getVT();
816 SrcVT =
N.getOperand(0).getValueType();
818 if (!IsLoadStore && SrcVT == MVT::i8)
820 else if (!IsLoadStore && SrcVT == MVT::i16)
822 else if (SrcVT == MVT::i32)
824 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
829 EVT SrcVT =
N.getOperand(0).getValueType();
830 if (!IsLoadStore && SrcVT == MVT::i8)
832 else if (!IsLoadStore && SrcVT == MVT::i16)
834 else if (SrcVT == MVT::i32)
836 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
864bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
867 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
872 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
873 V.getConstantOperandVal(1) <= 4 &&
886bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
888 if (SelectShiftedRegisterFromAnd(
N, Reg, Shift))
898 unsigned BitSize =
N.getValueSizeInBits();
899 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
902 Reg =
N.getOperand(0);
903 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(
N), MVT::i32);
904 return isWorthFoldingALU(
N,
true);
915 if (
N.getValueType() == MVT::i32)
923template<
signed Low,
signed High,
signed Scale>
925 if (!isa<ConstantSDNode>(
N))
928 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
929 if ((MulImm % std::abs(Scale)) == 0) {
930 int64_t RDVLImm = MulImm / Scale;
931 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
932 Imm = CurDAG->getSignedTargetConstant(RDVLImm,
SDLoc(
N), MVT::i32);
942bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
944 unsigned ShiftVal = 0;
959 Reg =
N.getOperand(0).getOperand(0);
965 Reg =
N.getOperand(0);
970 unsigned Opc =
N.getOpcode();
988 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
990 return isWorthFoldingALU(
N);
995bool AArch64DAGToDAGISel::SelectArithUXTXRegister(
SDValue N,
SDValue &Reg,
997 unsigned ShiftVal = 0;
1011 Reg =
N.getOperand(0);
1012 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
1014 return isWorthFoldingALU(
N);
1023 for (
auto *
User :
N->users()) {
1050bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1051 unsigned BW,
unsigned Size,
1058 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1060 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1066 if (CurDAG->isBaseWithConstantOffset(
N)) {
1067 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1069 int64_t RHSC =
RHS->getSExtValue();
1071 int64_t
Range = 0x1LL << (BW - 1);
1073 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1074 RHSC < (
Range << Scale)) {
1075 Base =
N.getOperand(0);
1077 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1080 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1089 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1090 Base =
N.getOperand(0);
1092 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1095 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1106 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1113bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1119 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1121 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1127 dyn_cast<GlobalAddressSDNode>(
N.getOperand(1).getNode());
1128 Base =
N.getOperand(0);
1129 OffImm =
N.getOperand(1);
1138 if (CurDAG->isBaseWithConstantOffset(
N)) {
1139 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1140 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1143 Base =
N.getOperand(0);
1145 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1148 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1156 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1164 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1173bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1176 if (!CurDAG->isBaseWithConstantOffset(
N))
1178 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1179 int64_t RHSC =
RHS->getSExtValue();
1180 if (RHSC >= -256 && RHSC < 256) {
1181 Base =
N.getOperand(0);
1183 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1185 Base = CurDAG->getTargetFrameIndex(
1188 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(
N), MVT::i64);
1198 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1205bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1225 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1231 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1234 return isWorthFoldingAddr(
N,
Size);
1237bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1249 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1262 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1265 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1266 SelectExtendedSHL(RHS,
Size,
true,
Offset, SignExtend)) {
1268 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1273 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1274 SelectExtendedSHL(LHS,
Size,
true,
Offset, SignExtend)) {
1276 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1281 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1285 if (IsExtendedRegisterWorthFolding &&
1292 if (isWorthFoldingAddr(LHS,
Size))
1297 if (IsExtendedRegisterWorthFolding &&
1304 if (isWorthFoldingAddr(RHS,
Size))
1316 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1319 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1321 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1322 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1326bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1356 if (isa<ConstantSDNode>(RHS)) {
1357 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1367 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
1370 N = CurDAG->getNode(
ISD::ADD,
DL, MVT::i64, LHS, MOVIV);
1374 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1377 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1378 SelectExtendedSHL(RHS,
Size,
false,
Offset, SignExtend)) {
1380 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1385 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1386 SelectExtendedSHL(LHS,
Size,
false,
Offset, SignExtend)) {
1388 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1395 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1396 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1402 static const unsigned RegClassIDs[] = {
1403 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1404 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1405 AArch64::dsub2, AArch64::dsub3};
1411 static const unsigned RegClassIDs[] = {
1412 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1413 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1414 AArch64::qsub2, AArch64::qsub3};
1420 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1421 AArch64::ZPR3RegClassID,
1422 AArch64::ZPR4RegClassID};
1423 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1424 AArch64::zsub2, AArch64::zsub3};
1434 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1435 AArch64::ZPR4Mul4RegClassID};
1436 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1437 AArch64::zsub2, AArch64::zsub3};
1442 const unsigned RegClassIDs[],
1443 const unsigned SubRegs[]) {
1446 if (Regs.
size() == 1)
1457 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1460 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1462 Ops.
push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1466 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped, Ops);
1470void AArch64DAGToDAGISel::SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1473 EVT VT =
N->getValueType(0);
1475 unsigned ExtOff = isExt;
1478 unsigned Vec0Off = ExtOff + 1;
1486 Ops.
push_back(
N->getOperand(NumVecs + ExtOff + 1));
1487 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT, Ops));
1490static std::tuple<SDValue, SDValue>
1510 auto *ConstDiscN = dyn_cast<ConstantSDNode>(ConstDisc);
1511 if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue()))
1516 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1518 return std::make_tuple(
1523void AArch64DAGToDAGISel::SelectPtrauthAuth(
SDNode *
N) {
1528 SDValue AUTDisc =
N->getOperand(3);
1530 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1531 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1533 SDValue AUTAddrDisc, AUTConstDisc;
1534 std::tie(AUTConstDisc, AUTAddrDisc) =
1537 if (!Subtarget->isX16X17Safer()) {
1538 SDValue Ops[] = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1541 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64, Ops);
1542 ReplaceNode(
N, AUT);
1544 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1545 AArch64::X16, Val,
SDValue());
1546 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1548 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64, Ops);
1549 ReplaceNode(
N, AUT);
1553void AArch64DAGToDAGISel::SelectPtrauthResign(
SDNode *
N) {
1558 SDValue AUTDisc =
N->getOperand(3);
1560 SDValue PACDisc =
N->getOperand(5);
1562 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1563 unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
1565 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1566 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1568 SDValue AUTAddrDisc, AUTConstDisc;
1569 std::tie(AUTConstDisc, AUTAddrDisc) =
1572 SDValue PACAddrDisc, PACConstDisc;
1573 std::tie(PACConstDisc, PACAddrDisc) =
1576 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1577 AArch64::X16, Val,
SDValue());
1579 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1580 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1582 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64, Ops);
1583 ReplaceNode(
N, AUTPAC);
1586bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
1588 if (
LD->isUnindexed())
1590 EVT VT =
LD->getMemoryVT();
1591 EVT DstVT =
N->getValueType(0);
1595 int OffsetVal = (int)
OffsetOp->getZExtValue();
1600 unsigned Opcode = 0;
1603 bool InsertTo64 =
false;
1605 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1606 else if (VT == MVT::i32) {
1608 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1610 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1612 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1618 }
else if (VT == MVT::i16) {
1620 if (DstVT == MVT::i64)
1621 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1623 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1625 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1626 InsertTo64 = DstVT == MVT::i64;
1631 }
else if (VT == MVT::i8) {
1633 if (DstVT == MVT::i64)
1634 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1636 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1638 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1639 InsertTo64 = DstVT == MVT::i64;
1644 }
else if (VT == MVT::f16) {
1645 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1646 }
else if (VT == MVT::bf16) {
1647 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1648 }
else if (VT == MVT::f32) {
1649 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1650 }
else if (VT == MVT::f64 ||
1652 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1654 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1656 if (IsPre || OffsetVal != 8)
1660 Opcode = AArch64::LD1Onev8b_POST;
1663 Opcode = AArch64::LD1Onev4h_POST;
1666 Opcode = AArch64::LD1Onev2s_POST;
1669 Opcode = AArch64::LD1Onev1d_POST;
1675 if (IsPre || OffsetVal != 16)
1679 Opcode = AArch64::LD1Onev16b_POST;
1682 Opcode = AArch64::LD1Onev8h_POST;
1685 Opcode = AArch64::LD1Onev4s_POST;
1688 Opcode = AArch64::LD1Onev2d_POST;
1700 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1701 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1703 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1708 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {
MemOp});
1713 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1715 SDValue(CurDAG->getMachineNode(
1716 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1717 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1722 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1725 CurDAG->RemoveDeadNode(
N);
1729void AArch64DAGToDAGISel::SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1730 unsigned SubRegIdx) {
1732 EVT VT =
N->getValueType(0);
1738 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1740 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
1742 for (
unsigned i = 0; i < NumVecs; ++i)
1744 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1750 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(
N)) {
1752 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
1755 CurDAG->RemoveDeadNode(
N);
1758void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
1759 unsigned Opc,
unsigned SubRegIdx) {
1761 EVT VT =
N->getValueType(0);
1768 const EVT ResTys[] = {MVT::i64,
1769 MVT::Untyped, MVT::Other};
1771 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
1779 ReplaceUses(
SDValue(
N, 0), SuperReg);
1781 for (
unsigned i = 0; i < NumVecs; ++i)
1783 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1787 CurDAG->RemoveDeadNode(
N);
1793std::tuple<unsigned, SDValue, SDValue>
1794AArch64DAGToDAGISel::findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
1800 SDValue NewOffset = OldOffset;
1802 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1803 N, OldBase, NewBase, NewOffset);
1807 const bool IsRegReg =
1808 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1811 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1824template <SelectTypeKind Kind>
1836 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1841 if (EltVT != MVT::i1)
1845 if (EltVT == MVT::bf16)
1847 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1877void AArch64DAGToDAGISel::SelectPExtPair(
SDNode *
N,
unsigned Opc) {
1880 if (
Imm->getZExtValue() > 1)
1884 EVT VT =
N->getValueType(0);
1885 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1886 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
1889 for (
unsigned I = 0;
I < 2; ++
I)
1890 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1891 AArch64::psub0 +
I,
DL, VT, SuperReg));
1893 CurDAG->RemoveDeadNode(
N);
1896void AArch64DAGToDAGISel::SelectWhilePair(
SDNode *
N,
unsigned Opc) {
1898 EVT VT =
N->getValueType(0);
1900 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1902 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
1905 for (
unsigned I = 0;
I < 2; ++
I)
1906 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1907 AArch64::psub0 +
I,
DL, VT, SuperReg));
1909 CurDAG->RemoveDeadNode(
N);
1912void AArch64DAGToDAGISel::SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
1914 EVT VT =
N->getValueType(0);
1916 SDValue Ops = createZTuple(Regs);
1920 for (
unsigned i = 0; i < NumVecs; ++i)
1921 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1922 AArch64::zsub0 + i,
DL, VT, SuperReg));
1924 CurDAG->RemoveDeadNode(
N);
1927void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
1930 EVT VT =
N->getValueType(0);
1932 Ops.push_back(
N->getOperand(0));
1935 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other}, Ops);
1938 for (
unsigned i = 0; i < NumVecs; ++i)
1939 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1940 AArch64::zsub0 + i,
DL, VT, SuperReg));
1943 unsigned ChainIdx = NumVecs;
1945 CurDAG->RemoveDeadNode(
N);
1948void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(
SDNode *
N,
1953 assert(Opcode != 0 &&
"Unexpected opcode");
1956 EVT VT =
N->getValueType(0);
1957 unsigned FirstVecIdx = HasPred ? 2 : 1;
1959 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1961 return createZMulTuple(Regs);
1964 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1968 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1970 Zm =
N->getOperand(NumVecs + FirstVecIdx);
1974 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1975 N->getOperand(1), Zdn, Zm);
1977 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
1979 for (
unsigned i = 0; i < NumVecs; ++i)
1980 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1981 AArch64::zsub0 + i,
DL, VT, SuperReg));
1983 CurDAG->RemoveDeadNode(
N);
1986void AArch64DAGToDAGISel::SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
1987 unsigned Scale,
unsigned Opc_ri,
1988 unsigned Opc_rr,
bool IsIntr) {
1989 assert(Scale < 5 &&
"Invalid scaling value.");
1991 EVT VT =
N->getValueType(0);
1998 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
1999 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2001 SDValue Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
2005 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2009 for (
unsigned i = 0; i < NumVecs; ++i)
2010 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2011 AArch64::zsub0 + i,
DL, VT, SuperReg));
2014 unsigned ChainIdx = NumVecs;
2016 CurDAG->RemoveDeadNode(
N);
2019void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(
SDNode *
N,
2024 assert(Scale < 4 &&
"Invalid scaling value.");
2026 EVT VT =
N->getValueType(0);
2034 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2040 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2044 for (
unsigned i = 0; i < NumVecs; ++i)
2045 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2046 AArch64::zsub0 + i,
DL, VT, SuperReg));
2049 unsigned ChainIdx = NumVecs;
2051 CurDAG->RemoveDeadNode(
N);
2054void AArch64DAGToDAGISel::SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
2056 if (
N->getValueType(0) != MVT::nxv4f32)
2058 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2061void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(
SDNode *
Node,
2062 unsigned NumOutVecs,
2066 if (
Imm->getZExtValue() > MaxImm)
2070 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2075 EVT VT =
Node->getValueType(0);
2078 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2081 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2082 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2083 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2086 unsigned ChainIdx = NumOutVecs;
2088 CurDAG->RemoveDeadNode(
Node);
2091void AArch64DAGToDAGISel::SelectMultiVectorLuti(
SDNode *
Node,
2092 unsigned NumOutVecs,
2097 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2103 EVT VT =
Node->getValueType(0);
2106 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2109 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2110 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2111 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2114 unsigned ChainIdx = NumOutVecs;
2116 CurDAG->RemoveDeadNode(
Node);
2119void AArch64DAGToDAGISel::SelectClamp(
SDNode *
N,
unsigned NumVecs,
2122 EVT VT =
N->getValueType(0);
2125 SDValue Zd = createZMulTuple(Regs);
2126 SDValue Zn =
N->getOperand(1 + NumVecs);
2127 SDValue Zm =
N->getOperand(2 + NumVecs);
2133 for (
unsigned i = 0; i < NumVecs; ++i)
2134 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2135 AArch64::zsub0 + i,
DL, VT, SuperReg));
2137 CurDAG->RemoveDeadNode(
N);
2167template <
unsigned MaxIdx,
unsigned Scale>
2168void AArch64DAGToDAGISel::SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
2169 unsigned BaseReg,
unsigned Op) {
2170 unsigned TileNum = 0;
2171 if (BaseReg != AArch64::ZA)
2172 TileNum =
N->getConstantOperandVal(2);
2178 if (BaseReg == AArch64::ZA)
2179 SliceBase =
N->getOperand(2);
2181 SliceBase =
N->getOperand(3);
2183 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2189 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2191 EVT VT =
N->getValueType(0);
2192 for (
unsigned I = 0;
I < NumVecs; ++
I)
2194 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2197 unsigned ChainIdx = NumVecs;
2199 CurDAG->RemoveDeadNode(
N);
2202void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
2203 unsigned Op,
unsigned MaxIdx,
2204 unsigned Scale,
unsigned BaseReg) {
2208 SDValue SliceBase =
N->getOperand(2);
2209 if (BaseReg != AArch64::ZA)
2210 SliceBase =
N->getOperand(3);
2213 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2220 if (BaseReg != AArch64::ZA )
2225 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2227 EVT VT =
N->getValueType(0);
2228 for (
unsigned I = 0;
I < NumVecs; ++
I)
2230 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2234 unsigned ChainIdx = NumVecs;
2236 CurDAG->RemoveDeadNode(
N);
2239void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(
SDNode *
N,
2240 unsigned NumOutVecs,
2244 EVT VT =
N->getValueType(0);
2245 unsigned NumInVecs =
N->getNumOperands() - 1;
2249 assert((NumInVecs == 2 || NumInVecs == 4) &&
2250 "Don't know how to handle multi-register input!");
2255 for (
unsigned I = 0;
I < NumInVecs;
I++)
2259 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
2262 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2263 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2264 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2265 CurDAG->RemoveDeadNode(
N);
2268void AArch64DAGToDAGISel::SelectStore(
SDNode *
N,
unsigned NumVecs,
2271 EVT VT =
N->getOperand(2)->getValueType(0);
2278 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
N->getOperand(0)};
2279 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), Ops);
2283 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2288void AArch64DAGToDAGISel::SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
2289 unsigned Scale,
unsigned Opc_rr,
2295 SDValue RegSeq = createZTuple(Regs);
2301 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2302 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2304 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
2308 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), Ops);
2320 if (
auto FINode = dyn_cast<FrameIndexSDNode>(
N)) {
2321 int FI = FINode->getIndex();
2323 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2330void AArch64DAGToDAGISel::SelectPostStore(
SDNode *
N,
unsigned NumVecs,
2333 EVT VT =
N->getOperand(2)->getValueType(0);
2334 const EVT ResTys[] = {MVT::i64,
2343 N->getOperand(NumVecs + 1),
2344 N->getOperand(NumVecs + 2),
2346 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2386void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
2389 EVT VT =
N->getValueType(0);
2397 WidenVector(*CurDAG));
2401 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2403 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2405 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2406 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2407 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2411 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2412 AArch64::qsub2, AArch64::qsub3 };
2413 for (
unsigned i = 0; i < NumVecs; ++i) {
2414 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2421 CurDAG->RemoveDeadNode(
N);
2424void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
2427 EVT VT =
N->getValueType(0);
2435 WidenVector(*CurDAG));
2439 const EVT ResTys[] = {MVT::i64,
2442 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2445 CurDAG->getTargetConstant(LaneNo, dl,
2447 N->getOperand(NumVecs + 2),
2448 N->getOperand(NumVecs + 3),
2450 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2462 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2463 AArch64::qsub2, AArch64::qsub3 };
2464 for (
unsigned i = 0; i < NumVecs; ++i) {
2465 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2475 CurDAG->RemoveDeadNode(
N);
2478void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
2481 EVT VT =
N->getOperand(2)->getValueType(0);
2489 WidenVector(*CurDAG));
2493 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2495 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2496 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2497 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other, Ops);
2501 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2506void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
2509 EVT VT =
N->getOperand(2)->getValueType(0);
2517 WidenVector(*CurDAG));
2521 const EVT ResTys[] = {MVT::i64,
2524 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2526 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2527 N->getOperand(NumVecs + 2),
2528 N->getOperand(NumVecs + 3),
2530 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2534 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2541 unsigned &LSB,
unsigned &MSB,
2542 unsigned NumberOfIgnoredLowBits,
2543 bool BiggerPattern) {
2545 "N must be a AND operation to call this function");
2547 EVT VT =
N->getValueType(0);
2552 assert((VT == MVT::i32 || VT == MVT::i64) &&
2553 "Type checking must have been done before calling this function");
2567 const SDNode *Op0 =
N->getOperand(0).getNode();
2571 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
2574 if (AndImm & (AndImm + 1))
2577 bool ClampMSB =
false;
2597 ClampMSB = (VT == MVT::i32);
2598 }
else if (BiggerPattern) {
2604 Opd0 =
N->getOperand(0);
2610 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2613 <<
": Found large shift immediate, this should not happen\n"));
2619 (VT == MVT::i32 ? llvm::countr_one<uint32_t>(AndImm)
2620 : llvm::countr_one<uint64_t>(AndImm)) -
2627 MSB = MSB > 31 ? 31 : MSB;
2629 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2634 SDValue &Opd0,
unsigned &Immr,
2638 EVT VT =
N->getValueType(0);
2640 assert((VT == MVT::i32 || VT == MVT::i64) &&
2641 "Type checking must have been done before calling this function");
2645 Op =
Op->getOperand(0);
2646 VT =
Op->getValueType(0);
2655 unsigned Width = cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2659 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2660 Opd0 =
Op.getOperand(0);
2662 Imms = ShiftImm + Width - 1;
2690 Opd0 =
N->getOperand(0).getOperand(0);
2700 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2707 unsigned &Immr,
unsigned &Imms,
2708 bool BiggerPattern) {
2710 "N must be a SHR/SRA operation to call this function");
2712 EVT VT =
N->getValueType(0);
2717 assert((VT == MVT::i32 || VT == MVT::i64) &&
2718 "Type checking must have been done before calling this function");
2728 Opd0 =
N->getOperand(0).getOperand(0);
2729 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2735 Opd0 =
N->getOperand(0).getOperand(0);
2738 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2739 }
else if (BiggerPattern) {
2743 Opd0 =
N->getOperand(0);
2752 <<
": Found large shift immediate, this should not happen\n"));
2761 "bad amount in shift node!");
2762 int immr = SrlImm - ShlImm;
2767 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2769 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2773bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *
N) {
2776 EVT VT =
N->getValueType(0);
2777 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2778 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2789 unsigned Immr = ShiftImm;
2791 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2792 CurDAG->getTargetConstant(Imms, dl, VT)};
2793 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT, Ops);
2798 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2799 unsigned NumberOfIgnoredLowBits = 0,
2800 bool BiggerPattern =
false) {
2801 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2804 switch (
N->getOpcode()) {
2806 if (!
N->isMachineOpcode())
2811 NumberOfIgnoredLowBits, BiggerPattern);
2820 unsigned NOpc =
N->getMachineOpcode();
2824 case AArch64::SBFMWri:
2825 case AArch64::UBFMWri:
2826 case AArch64::SBFMXri:
2827 case AArch64::UBFMXri:
2829 Opd0 =
N->getOperand(0);
2830 Immr =
N->getConstantOperandVal(1);
2831 Imms =
N->getConstantOperandVal(2);
2838bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *
N) {
2839 unsigned Opc, Immr, Imms;
2844 EVT VT =
N->getValueType(0);
2849 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2850 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2851 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2853 SDNode *
BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
2854 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2860 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2861 CurDAG->getTargetConstant(Imms, dl, VT)};
2862 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
2871 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2872 assert((VT == MVT::i32 || VT == MVT::i64) &&
2873 "i32 or i64 mask type expected!");
2877 APInt SignificantDstMask =
2881 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2882 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2905 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2915 APInt OpUsefulBits(UsefulBits);
2919 OpUsefulBits <<= MSB - Imm + 1;
2924 OpUsefulBits <<= Imm;
2926 OpUsefulBits <<= MSB + 1;
2929 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2935 UsefulBits &= OpUsefulBits;
2941 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2943 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2951 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2952 APInt Mask(UsefulBits);
2953 Mask.clearAllBits();
2961 Mask.lshrInPlace(ShiftAmt);
2967 Mask.lshrInPlace(ShiftAmt);
2979 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2981 cast<const ConstantSDNode>(
Op.getOperand(3).getNode())->getZExtValue();
2983 APInt OpUsefulBits(UsefulBits);
2997 OpUsefulBits <<= Width;
3000 if (
Op.getOperand(1) == Orig) {
3002 Mask = ResultUsefulBits & OpUsefulBits;
3006 if (
Op.getOperand(0) == Orig)
3008 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3014 OpUsefulBits <<= Width;
3016 OpUsefulBits <<= LSB;
3018 if (
Op.getOperand(1) == Orig) {
3020 Mask = ResultUsefulBits & OpUsefulBits;
3021 Mask.lshrInPlace(LSB);
3024 if (
Op.getOperand(0) == Orig)
3025 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3042 case AArch64::ANDSWri:
3043 case AArch64::ANDSXri:
3044 case AArch64::ANDWri:
3045 case AArch64::ANDXri:
3049 case AArch64::UBFMWri:
3050 case AArch64::UBFMXri:
3053 case AArch64::ORRWrs:
3054 case AArch64::ORRXrs:
3059 case AArch64::BFMWri:
3060 case AArch64::BFMXri:
3063 case AArch64::STRBBui:
3064 case AArch64::STURBBi:
3070 case AArch64::STRHHui:
3071 case AArch64::STURHHi:
3084 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3086 UsefulBits =
APInt(Bitwidth, 0);
3095 UsersUsefulBits |= UsefulBitsForUse;
3100 UsefulBits &= UsersUsefulBits;
3110 EVT VT =
Op.getValueType();
3113 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3116 if (ShlAmount > 0) {
3119 UBFMOpc, dl, VT,
Op,
3124 assert(ShlAmount < 0 &&
"expected right shift");
3125 int ShrAmount = -ShlAmount;
3151 bool BiggerPattern,
SDValue &Src,
3152 int &DstLSB,
int &Width) {
3153 EVT VT =
Op.getValueType();
3162 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3166 switch (
Op.getOpcode()) {
3171 NonZeroBits, Src, DstLSB, Width);
3174 NonZeroBits, Src, DstLSB, Width);
3187 EVT VT =
Op.getValueType();
3188 assert((VT == MVT::i32 || VT == MVT::i64) &&
3189 "Caller guarantees VT is one of i32 or i64");
3202 assert((~AndImm & NonZeroBits) == 0 &&
3203 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3232 if (!BiggerPattern && !AndOp0.
hasOneUse())
3251 <<
"Found large Width in bit-field-positioning -- this indicates no "
3252 "proper combining / constant folding was performed\n");
3261 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3276 "Op.getNode() should be a SHL node to call this function");
3278 "Op.getNode() should shift ShlImm to call this function");
3285 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3309 EVT VT =
Op.getValueType();
3310 assert((VT == MVT::i32 || VT == MVT::i64) &&
3311 "Caller guarantees that type is i32 or i64");
3318 if (!BiggerPattern && !
Op.hasOneUse())
3327 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3335 assert(VT == MVT::i32 || VT == MVT::i64);
3346 EVT VT =
N->getValueType(0);
3347 if (VT != MVT::i32 && VT != MVT::i64)
3365 if (!
And.hasOneUse() ||
3375 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3382 if ((OrImm & NotKnownZero) != 0) {
3394 unsigned ImmS = Width - 1;
3400 bool IsBFI = LSB != 0;
3405 unsigned OrChunks = 0, BFIChunks = 0;
3406 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3407 if (((OrImm >> Shift) & 0xFFFF) != 0)
3409 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3412 if (BFIChunks > OrChunks)
3418 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3426 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3435 if (!Dst.hasOneUse())
3438 EVT VT = Dst.getValueType();
3439 assert((VT == MVT::i32 || VT == MVT::i64) &&
3440 "Caller should guarantee that VT is one of i32 or i64");
3448 SDValue DstOp0 = Dst.getOperand(0);
3468 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3469 unsigned MaskWidth =
3472 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3478 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3479 ShiftedOperand =
SDValue(UBFMNode, 0);
3489 ShiftedOperand = Dst.getOperand(0);
3496 ShiftedOperand = Dst.getOperand(0);
3508 const bool BiggerPattern) {
3509 EVT VT =
N->getValueType(0);
3510 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3511 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3512 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3513 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3514 assert((VT == MVT::i32 || VT == MVT::i64) &&
3515 "Expect result type to be i32 or i64 since N is combinable to BFM");
3522 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3525 if (BiggerPattern) {
3539 SDValue Ops[] = {OrOpd0, ShiftedOperand,
3548 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3610 EVT VT =
N->getValueType(0);
3611 if (VT != MVT::i32 && VT != MVT::i64)
3619 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3620 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3640 for (
int I = 0;
I < 4; ++
I) {
3643 unsigned ImmR, ImmS;
3644 bool BiggerPattern =
I / 2;
3645 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3647 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3653 NumberOfIgnoredLowBits, BiggerPattern)) {
3656 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3657 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3662 Width = ImmS - ImmR + 1;
3673 Src, DstLSB, Width)) {
3681 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3691 APInt BitsToBeInserted =
3694 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3718 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3751 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3753 if (Src->hasOneUse() &&
3756 Src = Src->getOperand(0);
3766 unsigned ImmS = Width - 1;
3772 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3780bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *
N) {
3789 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3802bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *
N) {
3806 EVT VT =
N->getValueType(0);
3807 if (VT != MVT::i32 && VT != MVT::i64)
3813 Op0, DstLSB, Width))
3819 unsigned ImmS = Width - 1;
3822 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3823 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3824 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3825 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
3831bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
3832 EVT VT =
N->getValueType(0);
3835 switch (
N->getOpcode()) {
3837 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3840 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3843 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3846 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3854 if (VT == MVT::i32) {
3857 }
else if (VT == MVT::i64) {
3863 SDValue ShiftAmt =
N->getOperand(1);
3883 (Add0Imm %
Size == 0)) {
3889 if (SubVT == MVT::i32) {
3890 NegOpc = AArch64::SUBWrr;
3891 ZeroReg = AArch64::WZR;
3893 assert(SubVT == MVT::i64);
3894 NegOpc = AArch64::SUBXrr;
3895 ZeroReg = AArch64::XZR;
3898 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3900 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3901 NewShiftAmt =
SDValue(Neg, 0);
3909 if (SubVT == MVT::i32) {
3910 NotOpc = AArch64::ORNWrr;
3911 ZeroReg = AArch64::WZR;
3913 assert(SubVT == MVT::i64);
3914 NotOpc = AArch64::ORNXrr;
3915 ZeroReg = AArch64::XZR;
3918 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3920 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3921 NewShiftAmt =
SDValue(Not, 0);
3942 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3943 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3945 AArch64::SUBREG_TO_REG,
DL, VT,
3946 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3947 NewShiftAmt =
SDValue(Ext, 0);
3950 SDValue Ops[] = {
N->getOperand(0), NewShiftAmt};
3951 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
3958 bool isReciprocal) {
3961 FVal = CN->getValueAPF();
3962 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(
N)) {
3964 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
3965 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
3969 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
3970 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
3993 if (!IsExact || !IntVal.isPowerOf2())
3995 unsigned FBits = IntVal.logBase2();
3999 if (FBits == 0 || FBits > RegWidth)
return false;
4005bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4006 unsigned RegWidth) {
4011bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4013 unsigned RegWidth) {
4023 RegString.
split(Fields,
':');
4025 if (Fields.
size() == 1)
4029 &&
"Invalid number of fields in read register string");
4032 bool AllIntFields =
true;
4036 AllIntFields &= !
Field.getAsInteger(10, IntField);
4041 "Unexpected non-integer value in special register string.");
4046 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
4047 (Ops[3] << 3) | (Ops[4]);
4054bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *
N) {
4055 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4056 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4059 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4061 unsigned Opcode64Bit = AArch64::MRS;
4066 const auto *TheReg =
4067 AArch64SysReg::lookupSysRegByName(RegString->getString());
4068 if (TheReg && TheReg->Readable &&
4069 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4070 Imm = TheReg->Encoding;
4076 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4077 Opcode64Bit = AArch64::ADR;
4085 SDValue InChain =
N->getOperand(0);
4086 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4087 if (!ReadIs128Bit) {
4088 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4089 {SysRegImm, InChain});
4091 SDNode *MRRS = CurDAG->getMachineNode(
4093 {MVT::Untyped , MVT::Other },
4094 {SysRegImm, InChain});
4098 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4100 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4106 ReplaceUses(
SDValue(
N, 2), OutChain);
4115bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *
N) {
4116 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4117 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4120 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4122 if (!WriteIs128Bit) {
4128 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4130 assert(isa<ConstantSDNode>(
N->getOperand(2)) &&
4131 "Expected a constant integer expression.");
4132 unsigned Reg = PMapper->Encoding;
4133 uint64_t Immed =
N->getConstantOperandVal(2);
4134 CurDAG->SelectNodeTo(
4135 N, State, MVT::Other, CurDAG->getTargetConstant(Reg,
DL, MVT::i32),
4136 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4142 if (trySelectPState(
4143 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4144 AArch64::MSRpstateImm4))
4146 if (trySelectPState(
4147 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4148 AArch64::MSRpstateImm1))
4157 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4158 if (TheReg && TheReg->Writeable &&
4159 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4160 Imm = TheReg->Encoding;
4168 SDValue InChain =
N->getOperand(0);
4169 if (!WriteIs128Bit) {
4170 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4171 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4172 N->getOperand(2), InChain);
4176 SDNode *Pair = CurDAG->getMachineNode(
4177 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4178 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4181 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4183 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4185 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4186 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4194bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *
N) {
4196 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
4199 if (Subtarget->hasLSE())
return false;
4201 if (MemTy == MVT::i8)
4202 Opcode = AArch64::CMP_SWAP_8;
4203 else if (MemTy == MVT::i16)
4204 Opcode = AArch64::CMP_SWAP_16;
4205 else if (MemTy == MVT::i32)
4206 Opcode = AArch64::CMP_SWAP_32;
4207 else if (MemTy == MVT::i64)
4208 Opcode = AArch64::CMP_SWAP_64;
4212 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4213 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4215 SDNode *CmpSwap = CurDAG->getMachineNode(
4217 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
4220 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {
MemOp});
4224 CurDAG->RemoveDeadNode(
N);
4231 if (!isa<ConstantSDNode>(
N))
4243 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4244 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4251 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4252 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4256 if (Val <= 65280 && Val % 256 == 0) {
4257 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4258 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4269bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N,
MVT VT,
4272 if (!isa<ConstantSDNode>(
N))
4276 int64_t Val = cast<ConstantSDNode>(
N)
4293 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4294 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4301 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4302 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4306 if (Val <= 65280 && Val % 256 == 0) {
4307 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4308 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4321 if (!isa<ConstantSDNode>(
N))
4325 int64_t Val = cast<ConstantSDNode>(
N)
4333 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4334 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4340 if (Val >= -128 && Val <= 127) {
4341 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4342 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4346 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) {
4347 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4348 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF,
DL, MVT::i32);
4359bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4360 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4361 int64_t ImmVal = CNode->getSExtValue();
4363 if (ImmVal >= -128 && ImmVal < 128) {
4364 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4372 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4373 uint64_t ImmVal = CNode->getZExtValue();
4383 ImmVal &= 0xFFFFFFFF;
4392 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4401 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4402 uint64_t ImmVal = CNode->getZExtValue();
4412 ImmVal |= ImmVal << 8;
4413 ImmVal |= ImmVal << 16;
4414 ImmVal |= ImmVal << 32;
4418 ImmVal |= ImmVal << 16;
4419 ImmVal |= ImmVal << 32;
4422 ImmVal &= 0xFFFFFFFF;
4423 ImmVal |= ImmVal << 32;
4433 Imm = CurDAG->getTargetConstant(encoding,
DL, MVT::i64);
4448 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
4449 uint64_t ImmVal = CN->getZExtValue();
4456 if (ImmVal >
High) {
4457 if (!AllowSaturation)
4462 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4469bool AArch64DAGToDAGISel::trySelectStackSlotTagP(
SDNode *
N) {
4473 if (!(isa<FrameIndexSDNode>(
N->getOperand(1)))) {
4485 int FI = cast<FrameIndexSDNode>(
N->getOperand(1))->getIndex();
4486 SDValue FiOp = CurDAG->getTargetFrameIndex(
4488 int TagOffset =
N->getConstantOperandVal(3);
4490 SDNode *Out = CurDAG->getMachineNode(
4491 AArch64::TAGPstack,
DL, MVT::i64,
4492 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->getOperand(2),
4493 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4494 ReplaceNode(
N, Out);
4498void AArch64DAGToDAGISel::SelectTagP(
SDNode *
N) {
4499 assert(isa<ConstantSDNode>(
N->getOperand(3)) &&
4500 "llvm.aarch64.tagp third argument must be an immediate");
4501 if (trySelectStackSlotTagP(
N))
4508 int TagOffset =
N->getConstantOperandVal(3);
4509 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4510 {
N->getOperand(1),
N->getOperand(2)});
4511 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4512 {
SDValue(N1, 0),
N->getOperand(2)});
4513 SDNode *N3 = CurDAG->getMachineNode(
4514 AArch64::ADDG,
DL, MVT::i64,
4515 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4516 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4520bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(
SDNode *
N) {
4524 if (
N->getConstantOperandVal(2) != 0)
4526 if (!
N->getOperand(0).isUndef())
4530 EVT VT =
N->getValueType(0);
4531 EVT InVT =
N->getOperand(1).getValueType();
4542 "Expected to insert into a packed scalable vector!");
4545 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4546 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4547 N->getOperand(1), RC));
4551bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(
SDNode *
N) {
4555 if (
N->getConstantOperandVal(1) != 0)
4559 EVT VT =
N->getValueType(0);
4560 EVT InVT =
N->getOperand(0).getValueType();
4571 "Expected to extract from a packed scalable vector!");
4574 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4575 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4576 N->getOperand(0), RC));
4580bool AArch64DAGToDAGISel::trySelectXAR(
SDNode *
N) {
4586 EVT VT =
N->getValueType(0);
4599 (Subtarget->hasSVE2() ||
4600 (Subtarget->hasSME() && Subtarget->isStreaming()))) {
4601 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4604 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4609 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4610 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4617 bool IsXOROperand =
true;
4619 IsXOROperand =
false;
4625 APInt ShlAmt, ShrAmt;
4633 if (!IsXOROperand) {
4635 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4638 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4639 SDNode *SubRegToReg = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL,
4640 VT, Zero, MOVIV, ZSub);
4650 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4651 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4652 AArch64::XAR_ZZZI_D})) {
4653 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
4678 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4688 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4696 bool IsXOROperand =
true;
4698 IsXOROperand =
false;
4701 R1 =
XOR.getOperand(0);
4702 R2 =
XOR.getOperand(1);
4712 if (ShAmt + HsAmt != VTSizeInBits)
4715 if (!IsXOROperand) {
4718 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4727 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4733 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4734 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4736 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4739 if (
R2.getValueType() == VT)
4740 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4748 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT, Undef,
4753 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4762 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4763 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4764 AArch64::XAR_ZZZI_D}))
4765 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT, Ops);
4767 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT, Ops);
4770 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4776 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4777 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4780 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4781 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4787 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4791 ReplaceNode(
N, XAR);
4795void AArch64DAGToDAGISel::Select(
SDNode *
Node) {
4797 if (
Node->isMachineOpcode()) {
4799 Node->setNodeId(-1);
4804 EVT VT =
Node->getValueType(0);
4806 switch (
Node->getOpcode()) {
4811 if (SelectCMP_SWAP(
Node))
4816 case AArch64ISD::MRRS:
4817 if (tryReadRegister(
Node))
4822 case AArch64ISD::MSRR:
4823 if (tryWriteRegister(
Node))
4830 if (tryIndexedLoad(
Node))
4839 if (tryBitfieldExtractOp(
Node))
4841 if (tryBitfieldInsertInZeroOp(
Node))
4846 if (tryShiftAmountMod(
Node))
4851 if (tryBitfieldExtractOpFromSExt(
Node))
4856 if (tryBitfieldInsertOp(
Node))
4858 if (trySelectXAR(
Node))
4863 if (trySelectCastScalableToFixedLengthVector(
Node))
4869 if (trySelectCastFixedLengthToScalableVector(
Node))
4878 if (ConstNode->
isZero()) {
4879 if (VT == MVT::i32) {
4881 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::WZR, MVT::i32);
4882 ReplaceNode(
Node,
New.getNode());
4884 }
else if (VT == MVT::i64) {
4886 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::XZR, MVT::i64);
4887 ReplaceNode(
Node,
New.getNode());
4896 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
4899 SDValue TFI = CurDAG->getTargetFrameIndex(
4902 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4903 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4904 CurDAG->SelectNodeTo(
Node, AArch64::ADDXri, MVT::i64, Ops);
4908 unsigned IntNo =
Node->getConstantOperandVal(1);
4912 case Intrinsic::aarch64_gcsss: {
4916 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4918 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4919 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4920 MVT::Other, Zero,
SDValue(SS1, 0));
4921 ReplaceNode(
Node, SS2);
4924 case Intrinsic::aarch64_ldaxp:
4925 case Intrinsic::aarch64_ldxp: {
4927 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4932 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4933 MVT::Other, MemAddr, Chain);
4937 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4938 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
4939 ReplaceNode(
Node, Ld);
4942 case Intrinsic::aarch64_stlxp:
4943 case Intrinsic::aarch64_stxp: {
4945 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4953 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4955 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other, Ops);
4958 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4959 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
4961 ReplaceNode(
Node, St);
4964 case Intrinsic::aarch64_neon_ld1x2:
4965 if (VT == MVT::v8i8) {
4966 SelectLoad(
Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4968 }
else if (VT == MVT::v16i8) {
4969 SelectLoad(
Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4971 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4972 SelectLoad(
Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4974 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4975 SelectLoad(
Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4977 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4978 SelectLoad(
Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4980 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4981 SelectLoad(
Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4983 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4984 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4986 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4987 SelectLoad(
Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4991 case Intrinsic::aarch64_neon_ld1x3:
4992 if (VT == MVT::v8i8) {
4993 SelectLoad(
Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
4995 }
else if (VT == MVT::v16i8) {
4996 SelectLoad(
Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
4998 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4999 SelectLoad(
Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5001 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5002 SelectLoad(
Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5004 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5005 SelectLoad(
Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5007 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5008 SelectLoad(
Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5010 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5011 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5013 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5014 SelectLoad(
Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5018 case Intrinsic::aarch64_neon_ld1x4:
5019 if (VT == MVT::v8i8) {
5020 SelectLoad(
Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5022 }
else if (VT == MVT::v16i8) {
5023 SelectLoad(
Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5025 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5026 SelectLoad(
Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5028 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5029 SelectLoad(
Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5031 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5032 SelectLoad(
Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5034 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5035 SelectLoad(
Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5037 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5038 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5040 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5041 SelectLoad(
Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5045 case Intrinsic::aarch64_neon_ld2:
5046 if (VT == MVT::v8i8) {
5047 SelectLoad(
Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5049 }
else if (VT == MVT::v16i8) {
5050 SelectLoad(
Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5052 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5053 SelectLoad(
Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5055 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5056 SelectLoad(
Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5058 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5059 SelectLoad(
Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5061 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5062 SelectLoad(
Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5064 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5065 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5067 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5068 SelectLoad(
Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5072 case Intrinsic::aarch64_neon_ld3:
5073 if (VT == MVT::v8i8) {
5074 SelectLoad(
Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5076 }
else if (VT == MVT::v16i8) {
5077 SelectLoad(
Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5079 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5080 SelectLoad(
Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5082 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5083 SelectLoad(
Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5085 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5086 SelectLoad(
Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5088 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5089 SelectLoad(
Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5091 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5092 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5094 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5095 SelectLoad(
Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5099 case Intrinsic::aarch64_neon_ld4:
5100 if (VT == MVT::v8i8) {
5101 SelectLoad(
Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5103 }
else if (VT == MVT::v16i8) {
5104 SelectLoad(
Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5106 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5107 SelectLoad(
Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5109 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5110 SelectLoad(
Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5112 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5113 SelectLoad(
Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5115 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5116 SelectLoad(
Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5118 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5119 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5121 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5122 SelectLoad(
Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5126 case Intrinsic::aarch64_neon_ld2r:
5127 if (VT == MVT::v8i8) {
5128 SelectLoad(
Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5130 }
else if (VT == MVT::v16i8) {
5131 SelectLoad(
Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5133 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5134 SelectLoad(
Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5136 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5137 SelectLoad(
Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5139 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5140 SelectLoad(
Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5142 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5143 SelectLoad(
Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5145 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5146 SelectLoad(
Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5148 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5149 SelectLoad(
Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5153 case Intrinsic::aarch64_neon_ld3r:
5154 if (VT == MVT::v8i8) {
5155 SelectLoad(
Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5157 }
else if (VT == MVT::v16i8) {
5158 SelectLoad(
Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5160 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5161 SelectLoad(
Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5163 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5164 SelectLoad(
Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5166 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5167 SelectLoad(
Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5169 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5170 SelectLoad(
Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5172 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5173 SelectLoad(
Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5175 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5176 SelectLoad(
Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5180 case Intrinsic::aarch64_neon_ld4r:
5181 if (VT == MVT::v8i8) {
5182 SelectLoad(
Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5184 }
else if (VT == MVT::v16i8) {
5185 SelectLoad(
Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5187 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5188 SelectLoad(
Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5190 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5191 SelectLoad(
Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5193 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5194 SelectLoad(
Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5196 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5197 SelectLoad(
Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5199 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5200 SelectLoad(
Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5202 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5203 SelectLoad(
Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5207 case Intrinsic::aarch64_neon_ld2lane:
5208 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5209 SelectLoadLane(
Node, 2, AArch64::LD2i8);
5211 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5212 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5213 SelectLoadLane(
Node, 2, AArch64::LD2i16);
5215 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5217 SelectLoadLane(
Node, 2, AArch64::LD2i32);
5219 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5221 SelectLoadLane(
Node, 2, AArch64::LD2i64);
5225 case Intrinsic::aarch64_neon_ld3lane:
5226 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5227 SelectLoadLane(
Node, 3, AArch64::LD3i8);
5229 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5230 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5231 SelectLoadLane(
Node, 3, AArch64::LD3i16);
5233 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5235 SelectLoadLane(
Node, 3, AArch64::LD3i32);
5237 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5239 SelectLoadLane(
Node, 3, AArch64::LD3i64);
5243 case Intrinsic::aarch64_neon_ld4lane:
5244 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5245 SelectLoadLane(
Node, 4, AArch64::LD4i8);
5247 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5248 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5249 SelectLoadLane(
Node, 4, AArch64::LD4i16);
5251 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5253 SelectLoadLane(
Node, 4, AArch64::LD4i32);
5255 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5257 SelectLoadLane(
Node, 4, AArch64::LD4i64);
5261 case Intrinsic::aarch64_ld64b:
5262 SelectLoad(
Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5264 case Intrinsic::aarch64_sve_ld2q_sret: {
5265 SelectPredicatedLoad(
Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5268 case Intrinsic::aarch64_sve_ld3q_sret: {
5269 SelectPredicatedLoad(
Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5272 case Intrinsic::aarch64_sve_ld4q_sret: {
5273 SelectPredicatedLoad(
Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5276 case Intrinsic::aarch64_sve_ld2_sret: {
5277 if (VT == MVT::nxv16i8) {
5278 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5281 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5282 VT == MVT::nxv8bf16) {
5283 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5286 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5287 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5290 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5291 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5297 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5298 if (VT == MVT::nxv16i8) {
5299 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5300 SelectContiguousMultiVectorLoad(
5301 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5302 else if (Subtarget->hasSVE2p1())
5303 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LD1B_2Z_IMM,
5308 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5309 VT == MVT::nxv8bf16) {
5310 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5311 SelectContiguousMultiVectorLoad(
5312 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5313 else if (Subtarget->hasSVE2p1())
5314 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LD1H_2Z_IMM,
5319 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5320 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5321 SelectContiguousMultiVectorLoad(
5322 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5323 else if (Subtarget->hasSVE2p1())
5324 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LD1W_2Z_IMM,
5329 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5330 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5331 SelectContiguousMultiVectorLoad(
5332 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5333 else if (Subtarget->hasSVE2p1())
5334 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LD1D_2Z_IMM,
5342 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5343 if (VT == MVT::nxv16i8) {
5344 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5345 SelectContiguousMultiVectorLoad(
5346 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5347 else if (Subtarget->hasSVE2p1())
5348 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LD1B_4Z_IMM,
5353 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5354 VT == MVT::nxv8bf16) {
5355 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5356 SelectContiguousMultiVectorLoad(
5357 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5358 else if (Subtarget->hasSVE2p1())
5359 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LD1H_4Z_IMM,
5364 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5365 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5366 SelectContiguousMultiVectorLoad(
5367 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5368 else if (Subtarget->hasSVE2p1())
5369 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LD1W_4Z_IMM,
5374 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5375 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5376 SelectContiguousMultiVectorLoad(
5377 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5378 else if (Subtarget->hasSVE2p1())
5379 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LD1D_4Z_IMM,
5387 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5388 if (VT == MVT::nxv16i8) {
5389 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5390 SelectContiguousMultiVectorLoad(
Node, 2, 0,
5391 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5392 AArch64::LDNT1B_2Z_PSEUDO);
5393 else if (Subtarget->hasSVE2p1())
5394 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5395 AArch64::LDNT1B_2Z);
5399 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5400 VT == MVT::nxv8bf16) {
5401 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5402 SelectContiguousMultiVectorLoad(
Node, 2, 1,
5403 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5404 AArch64::LDNT1H_2Z_PSEUDO);
5405 else if (Subtarget->hasSVE2p1())
5406 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5407 AArch64::LDNT1H_2Z);
5411 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5412 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5413 SelectContiguousMultiVectorLoad(
Node, 2, 2,
5414 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5415 AArch64::LDNT1W_2Z_PSEUDO);
5416 else if (Subtarget->hasSVE2p1())
5417 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5418 AArch64::LDNT1W_2Z);
5422 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5423 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5424 SelectContiguousMultiVectorLoad(
Node, 2, 3,
5425 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5426 AArch64::LDNT1D_2Z_PSEUDO);
5427 else if (Subtarget->hasSVE2p1())
5428 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5429 AArch64::LDNT1D_2Z);
5436 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5437 if (VT == MVT::nxv16i8) {
5438 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5439 SelectContiguousMultiVectorLoad(
Node, 4, 0,
5440 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5441 AArch64::LDNT1B_4Z_PSEUDO);
5442 else if (Subtarget->hasSVE2p1())
5443 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5444 AArch64::LDNT1B_4Z);
5448 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5449 VT == MVT::nxv8bf16) {
5450 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5451 SelectContiguousMultiVectorLoad(
Node, 4, 1,
5452 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5453 AArch64::LDNT1H_4Z_PSEUDO);
5454 else if (Subtarget->hasSVE2p1())
5455 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5456 AArch64::LDNT1H_4Z);
5460 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5461 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5462 SelectContiguousMultiVectorLoad(
Node, 4, 2,
5463 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5464 AArch64::LDNT1W_4Z_PSEUDO);
5465 else if (Subtarget->hasSVE2p1())
5466 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5467 AArch64::LDNT1W_4Z);
5471 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5472 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5473 SelectContiguousMultiVectorLoad(
Node, 4, 3,
5474 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5475 AArch64::LDNT1D_4Z_PSEUDO);
5476 else if (Subtarget->hasSVE2p1())
5477 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5478 AArch64::LDNT1D_4Z);
5485 case Intrinsic::aarch64_sve_ld3_sret: {
5486 if (VT == MVT::nxv16i8) {
5487 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5490 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5491 VT == MVT::nxv8bf16) {
5492 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5495 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5496 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5499 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5500 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5506 case Intrinsic::aarch64_sve_ld4_sret: {
5507 if (VT == MVT::nxv16i8) {
5508 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5511 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5512 VT == MVT::nxv8bf16) {
5513 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5516 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5517 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5520 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5521 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5527 case Intrinsic::aarch64_sme_read_hor_vg2: {
5528 if (VT == MVT::nxv16i8) {
5529 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5530 AArch64::MOVA_2ZMXI_H_B);
5532 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5533 VT == MVT::nxv8bf16) {
5534 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5535 AArch64::MOVA_2ZMXI_H_H);
5537 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5538 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5539 AArch64::MOVA_2ZMXI_H_S);
5541 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5542 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5543 AArch64::MOVA_2ZMXI_H_D);
5548 case Intrinsic::aarch64_sme_read_ver_vg2: {
5549 if (VT == MVT::nxv16i8) {
5550 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5551 AArch64::MOVA_2ZMXI_V_B);
5553 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5554 VT == MVT::nxv8bf16) {
5555 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5556 AArch64::MOVA_2ZMXI_V_H);
5558 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5559 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5560 AArch64::MOVA_2ZMXI_V_S);
5562 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5563 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5564 AArch64::MOVA_2ZMXI_V_D);
5569 case Intrinsic::aarch64_sme_read_hor_vg4: {
5570 if (VT == MVT::nxv16i8) {
5571 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5572 AArch64::MOVA_4ZMXI_H_B);
5574 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5575 VT == MVT::nxv8bf16) {
5576 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5577 AArch64::MOVA_4ZMXI_H_H);
5579 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5580 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAS0,
5581 AArch64::MOVA_4ZMXI_H_S);
5583 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5584 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAD0,
5585 AArch64::MOVA_4ZMXI_H_D);
5590 case Intrinsic::aarch64_sme_read_ver_vg4: {
5591 if (VT == MVT::nxv16i8) {
5592 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5593 AArch64::MOVA_4ZMXI_V_B);
5595 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5596 VT == MVT::nxv8bf16) {
5597 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5598 AArch64::MOVA_4ZMXI_V_H);
5600 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5601 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAS0,
5602 AArch64::MOVA_4ZMXI_V_S);
5604 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5605 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAD0,
5606 AArch64::MOVA_4ZMXI_V_D);
5611 case Intrinsic::aarch64_sme_read_vg1x2: {
5612 SelectMultiVectorMove<7, 1>(
Node, 2, AArch64::ZA,
5613 AArch64::MOVA_VG2_2ZMXI);
5616 case Intrinsic::aarch64_sme_read_vg1x4: {
5617 SelectMultiVectorMove<7, 1>(
Node, 4, AArch64::ZA,
5618 AArch64::MOVA_VG4_4ZMXI);
5621 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5622 if (VT == MVT::nxv16i8) {
5623 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5625 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5626 VT == MVT::nxv8bf16) {
5627 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5629 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5630 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5632 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5633 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5638 case Intrinsic::aarch64_sme_readz_vert_x2: {
5639 if (VT == MVT::nxv16i8) {
5640 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5642 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5643 VT == MVT::nxv8bf16) {
5644 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5646 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5647 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5649 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5650 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5655 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5656 if (VT == MVT::nxv16i8) {
5657 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5659 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5660 VT == MVT::nxv8bf16) {
5661 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5663 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5664 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5666 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5667 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5672 case Intrinsic::aarch64_sme_readz_vert_x4: {
5673 if (VT == MVT::nxv16i8) {
5674 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5676 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5677 VT == MVT::nxv8bf16) {
5678 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5680 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5681 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5683 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5684 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5689 case Intrinsic::aarch64_sme_readz_x2: {
5690 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5694 case Intrinsic::aarch64_sme_readz_x4: {
5695 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5699 case Intrinsic::swift_async_context_addr: {
5702 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5704 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5705 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5706 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5710 CurDAG->RemoveDeadNode(
Node);
5712 auto &MF = CurDAG->getMachineFunction();
5713 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5717 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5718 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5719 Node->getValueType(0),
5720 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5721 AArch64::LUTI2_4ZTZI_S}))
5723 SelectMultiVectorLutiLane(
Node, 4,
Opc, 3);
5726 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5727 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5728 Node->getValueType(0),
5729 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5731 SelectMultiVectorLutiLane(
Node, 4,
Opc, 1);
5734 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5735 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5736 Node->getValueType(0),
5737 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5738 AArch64::LUTI2_2ZTZI_S}))
5740 SelectMultiVectorLutiLane(
Node, 2,
Opc, 7);
5743 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5744 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5745 Node->getValueType(0),
5746 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5747 AArch64::LUTI4_2ZTZI_S}))
5749 SelectMultiVectorLutiLane(
Node, 2,
Opc, 3);
5752 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5753 SelectMultiVectorLuti(
Node, 4, AArch64::LUTI4_4ZZT2Z);
5756 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5757 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5758 Node->getValueType(0),
5759 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5760 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5762 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5763 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5764 Node->getValueType(0),
5765 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5766 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5768 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5769 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5770 Node->getValueType(0),
5771 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5772 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5774 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5775 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5776 Node->getValueType(0),
5777 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5778 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5783 unsigned IntNo =
Node->getConstantOperandVal(0);
5787 case Intrinsic::aarch64_tagp:
5791 case Intrinsic::ptrauth_auth:
5792 SelectPtrauthAuth(
Node);
5795 case Intrinsic::ptrauth_resign:
5796 SelectPtrauthResign(
Node);
5799 case Intrinsic::aarch64_neon_tbl2:
5800 SelectTable(
Node, 2,
5801 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5804 case Intrinsic::aarch64_neon_tbl3:
5805 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5806 : AArch64::TBLv16i8Three,
5809 case Intrinsic::aarch64_neon_tbl4:
5810 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5811 : AArch64::TBLv16i8Four,
5814 case Intrinsic::aarch64_neon_tbx2:
5815 SelectTable(
Node, 2,
5816 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5819 case Intrinsic::aarch64_neon_tbx3:
5820 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5821 : AArch64::TBXv16i8Three,
5824 case Intrinsic::aarch64_neon_tbx4:
5825 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5826 : AArch64::TBXv16i8Four,
5829 case Intrinsic::aarch64_sve_srshl_single_x2:
5830 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5831 Node->getValueType(0),
5832 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5833 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5834 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5836 case Intrinsic::aarch64_sve_srshl_single_x4:
5837 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5838 Node->getValueType(0),
5839 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5840 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5841 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5843 case Intrinsic::aarch64_sve_urshl_single_x2:
5844 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5845 Node->getValueType(0),
5846 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5847 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5848 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5850 case Intrinsic::aarch64_sve_urshl_single_x4:
5851 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5852 Node->getValueType(0),
5853 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5854 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5855 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5857 case Intrinsic::aarch64_sve_srshl_x2:
5858 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5859 Node->getValueType(0),
5860 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5861 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5862 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5864 case Intrinsic::aarch64_sve_srshl_x4:
5865 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5866 Node->getValueType(0),
5867 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5868 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5869 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5871 case Intrinsic::aarch64_sve_urshl_x2:
5872 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5873 Node->getValueType(0),
5874 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5875 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5876 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5878 case Intrinsic::aarch64_sve_urshl_x4:
5879 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5880 Node->getValueType(0),
5881 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5882 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5883 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5885 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5886 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5887 Node->getValueType(0),
5888 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5889 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5890 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5892 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5893 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5894 Node->getValueType(0),
5895 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5896 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5897 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5899 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5900 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5901 Node->getValueType(0),
5902 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5903 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5904 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5906 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5907 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5908 Node->getValueType(0),
5909 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5910 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5911 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5913 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5914 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5915 Node->getValueType(0),
5916 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5917 AArch64::FSCALE_2ZZ_D}))
5918 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5920 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5921 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5922 Node->getValueType(0),
5923 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5924 AArch64::FSCALE_4ZZ_D}))
5925 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5927 case Intrinsic::aarch64_sme_fp8_scale_x2:
5928 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5929 Node->getValueType(0),
5930 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5931 AArch64::FSCALE_2Z2Z_D}))
5932 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5934 case Intrinsic::aarch64_sme_fp8_scale_x4:
5935 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5936 Node->getValueType(0),
5937 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5938 AArch64::FSCALE_4Z4Z_D}))
5939 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5941 case Intrinsic::aarch64_sve_whilege_x2:
5942 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5943 Node->getValueType(0),
5944 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5945 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5946 SelectWhilePair(
Node,
Op);
5948 case Intrinsic::aarch64_sve_whilegt_x2:
5949 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5950 Node->getValueType(0),
5951 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5952 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5953 SelectWhilePair(
Node,
Op);
5955 case Intrinsic::aarch64_sve_whilehi_x2:
5956 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5957 Node->getValueType(0),
5958 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5959 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5960 SelectWhilePair(
Node,
Op);
5962 case Intrinsic::aarch64_sve_whilehs_x2:
5963 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5964 Node->getValueType(0),
5965 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5966 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5967 SelectWhilePair(
Node,
Op);
5969 case Intrinsic::aarch64_sve_whilele_x2:
5970 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5971 Node->getValueType(0),
5972 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5973 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5974 SelectWhilePair(
Node,
Op);
5976 case Intrinsic::aarch64_sve_whilelo_x2:
5977 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5978 Node->getValueType(0),
5979 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5980 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5981 SelectWhilePair(
Node,
Op);
5983 case Intrinsic::aarch64_sve_whilels_x2:
5984 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5985 Node->getValueType(0),
5986 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5987 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5988 SelectWhilePair(
Node,
Op);
5990 case Intrinsic::aarch64_sve_whilelt_x2:
5991 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5992 Node->getValueType(0),
5993 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
5994 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
5995 SelectWhilePair(
Node,
Op);
5997 case Intrinsic::aarch64_sve_smax_single_x2:
5998 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5999 Node->getValueType(0),
6000 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6001 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6002 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6004 case Intrinsic::aarch64_sve_umax_single_x2:
6005 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6006 Node->getValueType(0),
6007 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6008 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6009 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6011 case Intrinsic::aarch64_sve_fmax_single_x2:
6012 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6013 Node->getValueType(0),
6014 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6015 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6016 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6018 case Intrinsic::aarch64_sve_smax_single_x4:
6019 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6020 Node->getValueType(0),
6021 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6022 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6023 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6025 case Intrinsic::aarch64_sve_umax_single_x4:
6026 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6027 Node->getValueType(0),
6028 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6029 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6030 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6032 case Intrinsic::aarch64_sve_fmax_single_x4:
6033 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6034 Node->getValueType(0),
6035 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6036 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6037 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6039 case Intrinsic::aarch64_sve_smin_single_x2:
6040 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6041 Node->getValueType(0),
6042 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6043 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6044 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6046 case Intrinsic::aarch64_sve_umin_single_x2:
6047 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6048 Node->getValueType(0),
6049 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6050 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6051 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6053 case Intrinsic::aarch64_sve_fmin_single_x2:
6054 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6055 Node->getValueType(0),
6056 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6057 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6058 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6060 case Intrinsic::aarch64_sve_smin_single_x4:
6061 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6062 Node->getValueType(0),
6063 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6064 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6065 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6067 case Intrinsic::aarch64_sve_umin_single_x4:
6068 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6069 Node->getValueType(0),
6070 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6071 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6072 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6074 case Intrinsic::aarch64_sve_fmin_single_x4:
6075 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6076 Node->getValueType(0),
6077 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6078 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6079 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6081 case Intrinsic::aarch64_sve_smax_x2:
6082 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6083 Node->getValueType(0),
6084 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6085 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6086 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6088 case Intrinsic::aarch64_sve_umax_x2:
6089 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6090 Node->getValueType(0),
6091 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6092 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6093 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6095 case Intrinsic::aarch64_sve_fmax_x2:
6096 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6097 Node->getValueType(0),
6098 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6099 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6100 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6102 case Intrinsic::aarch64_sve_smax_x4:
6103 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6104 Node->getValueType(0),
6105 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6106 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6107 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6109 case Intrinsic::aarch64_sve_umax_x4:
6110 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6111 Node->getValueType(0),
6112 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6113 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6114 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6116 case Intrinsic::aarch64_sve_fmax_x4:
6117 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6118 Node->getValueType(0),
6119 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6120 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6121 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6123 case Intrinsic::aarch64_sme_famax_x2:
6124 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6125 Node->getValueType(0),
6126 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6127 AArch64::FAMAX_2Z2Z_D}))
6128 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6130 case Intrinsic::aarch64_sme_famax_x4:
6131 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6132 Node->getValueType(0),
6133 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6134 AArch64::FAMAX_4Z4Z_D}))
6135 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6137 case Intrinsic::aarch64_sme_famin_x2:
6138 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6139 Node->getValueType(0),
6140 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6141 AArch64::FAMIN_2Z2Z_D}))
6142 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6144 case Intrinsic::aarch64_sme_famin_x4:
6145 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6146 Node->getValueType(0),
6147 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6148 AArch64::FAMIN_4Z4Z_D}))
6149 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6151 case Intrinsic::aarch64_sve_smin_x2:
6152 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6153 Node->getValueType(0),
6154 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6155 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6156 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6158 case Intrinsic::aarch64_sve_umin_x2:
6159 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6160 Node->getValueType(0),
6161 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6162 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6163 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6165 case Intrinsic::aarch64_sve_fmin_x2:
6166 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6167 Node->getValueType(0),
6168 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6169 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6170 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6172 case Intrinsic::aarch64_sve_smin_x4:
6173 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6174 Node->getValueType(0),
6175 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6176 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6177 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6179 case Intrinsic::aarch64_sve_umin_x4:
6180 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6181 Node->getValueType(0),
6182 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6183 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6184 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6186 case Intrinsic::aarch64_sve_fmin_x4:
6187 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6188 Node->getValueType(0),
6189 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6190 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6191 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6193 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6194 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6195 Node->getValueType(0),
6196 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6197 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6198 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6200 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6201 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6202 Node->getValueType(0),
6203 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6204 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6205 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6207 case Intrinsic::aarch64_sve_fminnm_single_x2:
6208 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6209 Node->getValueType(0),
6210 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6211 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6212 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6214 case Intrinsic::aarch64_sve_fminnm_single_x4:
6215 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6216 Node->getValueType(0),
6217 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6218 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6219 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6221 case Intrinsic::aarch64_sve_fmaxnm_x2:
6222 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6223 Node->getValueType(0),
6224 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6225 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6226 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6228 case Intrinsic::aarch64_sve_fmaxnm_x4:
6229 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6230 Node->getValueType(0),
6231 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6232 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6233 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6235 case Intrinsic::aarch64_sve_fminnm_x2:
6236 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6237 Node->getValueType(0),
6238 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6239 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6240 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6242 case Intrinsic::aarch64_sve_fminnm_x4:
6243 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6244 Node->getValueType(0),
6245 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6246 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6247 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6249 case Intrinsic::aarch64_sve_fcvtzs_x2:
6250 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6252 case Intrinsic::aarch64_sve_scvtf_x2:
6253 SelectCVTIntrinsic(
Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6255 case Intrinsic::aarch64_sve_fcvtzu_x2:
6256 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6258 case Intrinsic::aarch64_sve_ucvtf_x2:
6259 SelectCVTIntrinsic(
Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6261 case Intrinsic::aarch64_sve_fcvtzs_x4:
6262 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6264 case Intrinsic::aarch64_sve_scvtf_x4:
6265 SelectCVTIntrinsic(
Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6267 case Intrinsic::aarch64_sve_fcvtzu_x4:
6268 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6270 case Intrinsic::aarch64_sve_ucvtf_x4:
6271 SelectCVTIntrinsic(
Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6273 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6274 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6276 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6277 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6279 case Intrinsic::aarch64_sve_sclamp_single_x2:
6280 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6281 Node->getValueType(0),
6282 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6283 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6284 SelectClamp(
Node, 2,
Op);
6286 case Intrinsic::aarch64_sve_uclamp_single_x2:
6287 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6288 Node->getValueType(0),
6289 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6290 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6291 SelectClamp(
Node, 2,
Op);
6293 case Intrinsic::aarch64_sve_fclamp_single_x2:
6294 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6295 Node->getValueType(0),
6296 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6297 AArch64::FCLAMP_VG2_2Z2Z_D}))
6298 SelectClamp(
Node, 2,
Op);
6300 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6301 SelectClamp(
Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6303 case Intrinsic::aarch64_sve_sclamp_single_x4:
6304 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6305 Node->getValueType(0),
6306 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6307 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6308 SelectClamp(
Node, 4,
Op);
6310 case Intrinsic::aarch64_sve_uclamp_single_x4:
6311 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6312 Node->getValueType(0),
6313 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6314 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6315 SelectClamp(
Node, 4,
Op);
6317 case Intrinsic::aarch64_sve_fclamp_single_x4:
6318 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6319 Node->getValueType(0),
6320 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6321 AArch64::FCLAMP_VG4_4Z4Z_D}))
6322 SelectClamp(
Node, 4,
Op);
6324 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6325 SelectClamp(
Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6327 case Intrinsic::aarch64_sve_add_single_x2:
6328 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6329 Node->getValueType(0),
6330 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6331 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6332 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6334 case Intrinsic::aarch64_sve_add_single_x4:
6335 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6336 Node->getValueType(0),
6337 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6338 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6339 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6341 case Intrinsic::aarch64_sve_zip_x2:
6342 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6343 Node->getValueType(0),
6344 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6345 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6346 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6348 case Intrinsic::aarch64_sve_zipq_x2:
6349 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6350 AArch64::ZIP_VG2_2ZZZ_Q);
6352 case Intrinsic::aarch64_sve_zip_x4:
6353 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6354 Node->getValueType(0),
6355 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6356 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6357 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6359 case Intrinsic::aarch64_sve_zipq_x4:
6360 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6361 AArch64::ZIP_VG4_4Z4Z_Q);
6363 case Intrinsic::aarch64_sve_uzp_x2:
6364 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6365 Node->getValueType(0),
6366 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6367 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6368 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6370 case Intrinsic::aarch64_sve_uzpq_x2:
6371 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6372 AArch64::UZP_VG2_2ZZZ_Q);
6374 case Intrinsic::aarch64_sve_uzp_x4:
6375 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6376 Node->getValueType(0),
6377 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6378 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6379 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6381 case Intrinsic::aarch64_sve_uzpq_x4:
6382 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6383 AArch64::UZP_VG4_4Z4Z_Q);
6385 case Intrinsic::aarch64_sve_sel_x2:
6386 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6387 Node->getValueType(0),
6388 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6389 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6390 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op,
true);
6392 case Intrinsic::aarch64_sve_sel_x4:
6393 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6394 Node->getValueType(0),
6395 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6396 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6397 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op,
true);
6399 case Intrinsic::aarch64_sve_frinta_x2:
6400 SelectFrintFromVT(
Node, 2, AArch64::FRINTA_2Z2Z_S);
6402 case Intrinsic::aarch64_sve_frinta_x4:
6403 SelectFrintFromVT(
Node, 4, AArch64::FRINTA_4Z4Z_S);
6405 case Intrinsic::aarch64_sve_frintm_x2:
6406 SelectFrintFromVT(
Node, 2, AArch64::FRINTM_2Z2Z_S);
6408 case Intrinsic::aarch64_sve_frintm_x4:
6409 SelectFrintFromVT(
Node, 4, AArch64::FRINTM_4Z4Z_S);
6411 case Intrinsic::aarch64_sve_frintn_x2:
6412 SelectFrintFromVT(
Node, 2, AArch64::FRINTN_2Z2Z_S);
6414 case Intrinsic::aarch64_sve_frintn_x4:
6415 SelectFrintFromVT(
Node, 4, AArch64::FRINTN_4Z4Z_S);
6417 case Intrinsic::aarch64_sve_frintp_x2:
6418 SelectFrintFromVT(
Node, 2, AArch64::FRINTP_2Z2Z_S);
6420 case Intrinsic::aarch64_sve_frintp_x4:
6421 SelectFrintFromVT(
Node, 4, AArch64::FRINTP_4Z4Z_S);
6423 case Intrinsic::aarch64_sve_sunpk_x2:
6424 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6425 Node->getValueType(0),
6426 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6427 AArch64::SUNPK_VG2_2ZZ_D}))
6428 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6430 case Intrinsic::aarch64_sve_uunpk_x2:
6431 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6432 Node->getValueType(0),
6433 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6434 AArch64::UUNPK_VG2_2ZZ_D}))
6435 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6437 case Intrinsic::aarch64_sve_sunpk_x4:
6438 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6439 Node->getValueType(0),
6440 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6441 AArch64::SUNPK_VG4_4Z2Z_D}))
6442 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6444 case Intrinsic::aarch64_sve_uunpk_x4:
6445 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6446 Node->getValueType(0),
6447 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6448 AArch64::UUNPK_VG4_4Z2Z_D}))
6449 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6451 case Intrinsic::aarch64_sve_pext_x2: {
6452 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6453 Node->getValueType(0),
6454 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6455 AArch64::PEXT_2PCI_D}))
6456 SelectPExtPair(
Node,
Op);
6463 unsigned IntNo =
Node->getConstantOperandVal(1);
6464 if (
Node->getNumOperands() >= 3)
6465 VT =
Node->getOperand(2)->getValueType(0);
6469 case Intrinsic::aarch64_neon_st1x2: {
6470 if (VT == MVT::v8i8) {
6471 SelectStore(
Node, 2, AArch64::ST1Twov8b);
6473 }
else if (VT == MVT::v16i8) {
6474 SelectStore(
Node, 2, AArch64::ST1Twov16b);
6476 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6477 VT == MVT::v4bf16) {
6478 SelectStore(
Node, 2, AArch64::ST1Twov4h);
6480 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6481 VT == MVT::v8bf16) {
6482 SelectStore(
Node, 2, AArch64::ST1Twov8h);
6484 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6485 SelectStore(
Node, 2, AArch64::ST1Twov2s);
6487 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6488 SelectStore(
Node, 2, AArch64::ST1Twov4s);
6490 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6491 SelectStore(
Node, 2, AArch64::ST1Twov2d);
6493 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6494 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6499 case Intrinsic::aarch64_neon_st1x3: {
6500 if (VT == MVT::v8i8) {
6501 SelectStore(
Node, 3, AArch64::ST1Threev8b);
6503 }
else if (VT == MVT::v16i8) {
6504 SelectStore(
Node, 3, AArch64::ST1Threev16b);
6506 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6507 VT == MVT::v4bf16) {
6508 SelectStore(
Node, 3, AArch64::ST1Threev4h);
6510 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6511 VT == MVT::v8bf16) {
6512 SelectStore(
Node, 3, AArch64::ST1Threev8h);
6514 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6515 SelectStore(
Node, 3, AArch64::ST1Threev2s);
6517 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6518 SelectStore(
Node, 3, AArch64::ST1Threev4s);
6520 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6521 SelectStore(
Node, 3, AArch64::ST1Threev2d);
6523 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6524 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6529 case Intrinsic::aarch64_neon_st1x4: {
6530 if (VT == MVT::v8i8) {
6531 SelectStore(
Node, 4, AArch64::ST1Fourv8b);
6533 }
else if (VT == MVT::v16i8) {
6534 SelectStore(
Node, 4, AArch64::ST1Fourv16b);
6536 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6537 VT == MVT::v4bf16) {
6538 SelectStore(
Node, 4, AArch64::ST1Fourv4h);
6540 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6541 VT == MVT::v8bf16) {
6542 SelectStore(
Node, 4, AArch64::ST1Fourv8h);
6544 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6545 SelectStore(
Node, 4, AArch64::ST1Fourv2s);
6547 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6548 SelectStore(
Node, 4, AArch64::ST1Fourv4s);
6550 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6551 SelectStore(
Node, 4, AArch64::ST1Fourv2d);
6553 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6554 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6559 case Intrinsic::aarch64_neon_st2: {
6560 if (VT == MVT::v8i8) {
6561 SelectStore(
Node, 2, AArch64::ST2Twov8b);
6563 }
else if (VT == MVT::v16i8) {
6564 SelectStore(
Node, 2, AArch64::ST2Twov16b);
6566 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6567 VT == MVT::v4bf16) {
6568 SelectStore(
Node, 2, AArch64::ST2Twov4h);
6570 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6571 VT == MVT::v8bf16) {
6572 SelectStore(
Node, 2, AArch64::ST2Twov8h);
6574 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6575 SelectStore(
Node, 2, AArch64::ST2Twov2s);
6577 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6578 SelectStore(
Node, 2, AArch64::ST2Twov4s);
6580 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6581 SelectStore(
Node, 2, AArch64::ST2Twov2d);
6583 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6584 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6589 case Intrinsic::aarch64_neon_st3: {
6590 if (VT == MVT::v8i8) {
6591 SelectStore(
Node, 3, AArch64::ST3Threev8b);
6593 }
else if (VT == MVT::v16i8) {
6594 SelectStore(
Node, 3, AArch64::ST3Threev16b);
6596 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6597 VT == MVT::v4bf16) {
6598 SelectStore(
Node, 3, AArch64::ST3Threev4h);
6600 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6601 VT == MVT::v8bf16) {
6602 SelectStore(
Node, 3, AArch64::ST3Threev8h);
6604 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6605 SelectStore(
Node, 3, AArch64::ST3Threev2s);
6607 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6608 SelectStore(
Node, 3, AArch64::ST3Threev4s);
6610 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6611 SelectStore(
Node, 3, AArch64::ST3Threev2d);
6613 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6614 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6619 case Intrinsic::aarch64_neon_st4: {
6620 if (VT == MVT::v8i8) {
6621 SelectStore(
Node, 4, AArch64::ST4Fourv8b);
6623 }
else if (VT == MVT::v16i8) {
6624 SelectStore(
Node, 4, AArch64::ST4Fourv16b);
6626 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6627 VT == MVT::v4bf16) {
6628 SelectStore(
Node, 4, AArch64::ST4Fourv4h);
6630 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6631 VT == MVT::v8bf16) {
6632 SelectStore(
Node, 4, AArch64::ST4Fourv8h);
6634 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6635 SelectStore(
Node, 4, AArch64::ST4Fourv2s);
6637 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6638 SelectStore(
Node, 4, AArch64::ST4Fourv4s);
6640 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6641 SelectStore(
Node, 4, AArch64::ST4Fourv2d);
6643 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6644 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6649 case Intrinsic::aarch64_neon_st2lane: {
6650 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6651 SelectStoreLane(
Node, 2, AArch64::ST2i8);
6653 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6654 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6655 SelectStoreLane(
Node, 2, AArch64::ST2i16);
6657 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6659 SelectStoreLane(
Node, 2, AArch64::ST2i32);
6661 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6663 SelectStoreLane(
Node, 2, AArch64::ST2i64);
6668 case Intrinsic::aarch64_neon_st3lane: {
6669 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6670 SelectStoreLane(
Node, 3, AArch64::ST3i8);
6672 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6673 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6674 SelectStoreLane(
Node, 3, AArch64::ST3i16);
6676 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6678 SelectStoreLane(
Node, 3, AArch64::ST3i32);
6680 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6682 SelectStoreLane(
Node, 3, AArch64::ST3i64);
6687 case Intrinsic::aarch64_neon_st4lane: {
6688 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6689 SelectStoreLane(
Node, 4, AArch64::ST4i8);
6691 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6692 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6693 SelectStoreLane(
Node, 4, AArch64::ST4i16);
6695 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6697 SelectStoreLane(
Node, 4, AArch64::ST4i32);
6699 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6701 SelectStoreLane(
Node, 4, AArch64::ST4i64);
6706 case Intrinsic::aarch64_sve_st2q: {
6707 SelectPredicatedStore(
Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6710 case Intrinsic::aarch64_sve_st3q: {
6711 SelectPredicatedStore(
Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6714 case Intrinsic::aarch64_sve_st4q: {
6715 SelectPredicatedStore(
Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6718 case Intrinsic::aarch64_sve_st2: {
6719 if (VT == MVT::nxv16i8) {
6720 SelectPredicatedStore(
Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6722 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6723 VT == MVT::nxv8bf16) {
6724 SelectPredicatedStore(
Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6726 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6727 SelectPredicatedStore(
Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6729 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6730 SelectPredicatedStore(
Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6735 case Intrinsic::aarch64_sve_st3: {
6736 if (VT == MVT::nxv16i8) {
6737 SelectPredicatedStore(
Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6739 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6740 VT == MVT::nxv8bf16) {
6741 SelectPredicatedStore(
Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6743 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6744 SelectPredicatedStore(
Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6746 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6747 SelectPredicatedStore(
Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6752 case Intrinsic::aarch64_sve_st4: {
6753 if (VT == MVT::nxv16i8) {
6754 SelectPredicatedStore(
Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6756 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6757 VT == MVT::nxv8bf16) {
6758 SelectPredicatedStore(
Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6760 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6761 SelectPredicatedStore(
Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6763 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6764 SelectPredicatedStore(
Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6772 case AArch64ISD::LD2post: {
6773 if (VT == MVT::v8i8) {
6774 SelectPostLoad(
Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6776 }
else if (VT == MVT::v16i8) {
6777 SelectPostLoad(
Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6779 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6780 SelectPostLoad(
Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6782 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6783 SelectPostLoad(
Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6785 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6786 SelectPostLoad(
Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6788 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6789 SelectPostLoad(
Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6791 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6792 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6794 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6795 SelectPostLoad(
Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6800 case AArch64ISD::LD3post: {
6801 if (VT == MVT::v8i8) {
6802 SelectPostLoad(
Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6804 }
else if (VT == MVT::v16i8) {
6805 SelectPostLoad(
Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6807 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6808 SelectPostLoad(
Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6810 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6811 SelectPostLoad(
Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6813 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6814 SelectPostLoad(
Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6816 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6817 SelectPostLoad(
Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6819 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6820 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6822 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6823 SelectPostLoad(
Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6828 case AArch64ISD::LD4post: {
6829 if (VT == MVT::v8i8) {
6830 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6832 }
else if (VT == MVT::v16i8) {
6833 SelectPostLoad(
Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6835 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6836 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6838 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6839 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6841 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6842 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6844 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6845 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6847 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6848 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6850 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6851 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6856 case AArch64ISD::LD1x2post: {
6857 if (VT == MVT::v8i8) {
6858 SelectPostLoad(
Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6860 }
else if (VT == MVT::v16i8) {
6861 SelectPostLoad(
Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6863 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6864 SelectPostLoad(
Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6866 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6867 SelectPostLoad(
Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6869 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6870 SelectPostLoad(
Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6872 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6873 SelectPostLoad(
Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6875 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6876 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6878 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6879 SelectPostLoad(
Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6884 case AArch64ISD::LD1x3post: {
6885 if (VT == MVT::v8i8) {
6886 SelectPostLoad(
Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6888 }
else if (VT == MVT::v16i8) {
6889 SelectPostLoad(
Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6891 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6892 SelectPostLoad(
Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6894 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6895 SelectPostLoad(
Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6897 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6898 SelectPostLoad(
Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6900 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6901 SelectPostLoad(
Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6903 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6904 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6906 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6907 SelectPostLoad(
Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6912 case AArch64ISD::LD1x4post: {
6913 if (VT == MVT::v8i8) {
6914 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6916 }
else if (VT == MVT::v16i8) {
6917 SelectPostLoad(
Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6919 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6920 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6922 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6923 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6925 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6926 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6928 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6929 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6931 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6932 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6934 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6935 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6940 case AArch64ISD::LD1DUPpost: {
6941 if (VT == MVT::v8i8) {
6942 SelectPostLoad(
Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6944 }
else if (VT == MVT::v16i8) {
6945 SelectPostLoad(
Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6947 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6948 SelectPostLoad(
Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6950 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6951 SelectPostLoad(
Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6953 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6954 SelectPostLoad(
Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6956 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6957 SelectPostLoad(
Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6959 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6960 SelectPostLoad(
Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6962 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6963 SelectPostLoad(
Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6968 case AArch64ISD::LD2DUPpost: {
6969 if (VT == MVT::v8i8) {
6970 SelectPostLoad(
Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6972 }
else if (VT == MVT::v16i8) {
6973 SelectPostLoad(
Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6975 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6976 SelectPostLoad(
Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6978 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6979 SelectPostLoad(
Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6981 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6982 SelectPostLoad(
Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6984 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6985 SelectPostLoad(
Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6987 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6988 SelectPostLoad(
Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6990 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6991 SelectPostLoad(
Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
6996 case AArch64ISD::LD3DUPpost: {
6997 if (VT == MVT::v8i8) {
6998 SelectPostLoad(
Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7000 }
else if (VT == MVT::v16i8) {
7001 SelectPostLoad(
Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7003 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7004 SelectPostLoad(
Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7006 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7007 SelectPostLoad(
Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7009 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7010 SelectPostLoad(
Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7012 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7013 SelectPostLoad(
Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7015 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7016 SelectPostLoad(
Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7018 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7019 SelectPostLoad(
Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7024 case AArch64ISD::LD4DUPpost: {
7025 if (VT == MVT::v8i8) {
7026 SelectPostLoad(
Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7028 }
else if (VT == MVT::v16i8) {
7029 SelectPostLoad(
Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7031 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7032 SelectPostLoad(
Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7034 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7035 SelectPostLoad(
Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7037 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7038 SelectPostLoad(
Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7040 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7041 SelectPostLoad(
Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7043 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7044 SelectPostLoad(
Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7046 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7047 SelectPostLoad(
Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7052 case AArch64ISD::LD1LANEpost: {
7053 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7054 SelectPostLoadLane(
Node, 1, AArch64::LD1i8_POST);
7056 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7057 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7058 SelectPostLoadLane(
Node, 1, AArch64::LD1i16_POST);
7060 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7062 SelectPostLoadLane(
Node, 1, AArch64::LD1i32_POST);
7064 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7066 SelectPostLoadLane(
Node, 1, AArch64::LD1i64_POST);
7071 case AArch64ISD::LD2LANEpost: {
7072 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7073 SelectPostLoadLane(
Node, 2, AArch64::LD2i8_POST);
7075 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7076 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7077 SelectPostLoadLane(
Node, 2, AArch64::LD2i16_POST);
7079 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7081 SelectPostLoadLane(
Node, 2, AArch64::LD2i32_POST);
7083 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7085 SelectPostLoadLane(
Node, 2, AArch64::LD2i64_POST);
7090 case AArch64ISD::LD3LANEpost: {
7091 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7092 SelectPostLoadLane(
Node, 3, AArch64::LD3i8_POST);
7094 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7095 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7096 SelectPostLoadLane(
Node, 3, AArch64::LD3i16_POST);
7098 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7100 SelectPostLoadLane(
Node, 3, AArch64::LD3i32_POST);
7102 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7104 SelectPostLoadLane(
Node, 3, AArch64::LD3i64_POST);
7109 case AArch64ISD::LD4LANEpost: {
7110 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7111 SelectPostLoadLane(
Node, 4, AArch64::LD4i8_POST);
7113 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7114 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7115 SelectPostLoadLane(
Node, 4, AArch64::LD4i16_POST);
7117 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7119 SelectPostLoadLane(
Node, 4, AArch64::LD4i32_POST);
7121 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7123 SelectPostLoadLane(
Node, 4, AArch64::LD4i64_POST);
7128 case AArch64ISD::ST2post: {
7129 VT =
Node->getOperand(1).getValueType();
7130 if (VT == MVT::v8i8) {
7131 SelectPostStore(
Node, 2, AArch64::ST2Twov8b_POST);
7133 }
else if (VT == MVT::v16i8) {
7134 SelectPostStore(
Node, 2, AArch64::ST2Twov16b_POST);
7136 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7137 SelectPostStore(
Node, 2, AArch64::ST2Twov4h_POST);
7139 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7140 SelectPostStore(
Node, 2, AArch64::ST2Twov8h_POST);
7142 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7143 SelectPostStore(
Node, 2, AArch64::ST2Twov2s_POST);
7145 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7146 SelectPostStore(
Node, 2, AArch64::ST2Twov4s_POST);
7148 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7149 SelectPostStore(
Node, 2, AArch64::ST2Twov2d_POST);
7151 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7152 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7157 case AArch64ISD::ST3post: {
7158 VT =
Node->getOperand(1).getValueType();
7159 if (VT == MVT::v8i8) {
7160 SelectPostStore(
Node, 3, AArch64::ST3Threev8b_POST);
7162 }
else if (VT == MVT::v16i8) {
7163 SelectPostStore(
Node, 3, AArch64::ST3Threev16b_POST);
7165 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7166 SelectPostStore(
Node, 3, AArch64::ST3Threev4h_POST);
7168 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7169 SelectPostStore(
Node, 3, AArch64::ST3Threev8h_POST);
7171 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7172 SelectPostStore(
Node, 3, AArch64::ST3Threev2s_POST);
7174 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7175 SelectPostStore(
Node, 3, AArch64::ST3Threev4s_POST);
7177 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7178 SelectPostStore(
Node, 3, AArch64::ST3Threev2d_POST);
7180 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7181 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7186 case AArch64ISD::ST4post: {
7187 VT =
Node->getOperand(1).getValueType();
7188 if (VT == MVT::v8i8) {
7189 SelectPostStore(
Node, 4, AArch64::ST4Fourv8b_POST);
7191 }
else if (VT == MVT::v16i8) {
7192 SelectPostStore(
Node, 4, AArch64::ST4Fourv16b_POST);
7194 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7195 SelectPostStore(
Node, 4, AArch64::ST4Fourv4h_POST);
7197 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7198 SelectPostStore(
Node, 4, AArch64::ST4Fourv8h_POST);
7200 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7201 SelectPostStore(
Node, 4, AArch64::ST4Fourv2s_POST);
7203 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7204 SelectPostStore(
Node, 4, AArch64::ST4Fourv4s_POST);
7206 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7207 SelectPostStore(
Node, 4, AArch64::ST4Fourv2d_POST);
7209 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7210 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7215 case AArch64ISD::ST1x2post: {
7216 VT =
Node->getOperand(1).getValueType();
7217 if (VT == MVT::v8i8) {
7218 SelectPostStore(
Node, 2, AArch64::ST1Twov8b_POST);
7220 }
else if (VT == MVT::v16i8) {
7221 SelectPostStore(
Node, 2, AArch64::ST1Twov16b_POST);
7223 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7224 SelectPostStore(
Node, 2, AArch64::ST1Twov4h_POST);
7226 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7227 SelectPostStore(
Node, 2, AArch64::ST1Twov8h_POST);
7229 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7230 SelectPostStore(
Node, 2, AArch64::ST1Twov2s_POST);
7232 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7233 SelectPostStore(
Node, 2, AArch64::ST1Twov4s_POST);
7235 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7236 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7238 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7239 SelectPostStore(
Node, 2, AArch64::ST1Twov2d_POST);
7244 case AArch64ISD::ST1x3post: {
7245 VT =
Node->getOperand(1).getValueType();
7246 if (VT == MVT::v8i8) {
7247 SelectPostStore(
Node, 3, AArch64::ST1Threev8b_POST);
7249 }
else if (VT == MVT::v16i8) {
7250 SelectPostStore(
Node, 3, AArch64::ST1Threev16b_POST);
7252 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7253 SelectPostStore(
Node, 3, AArch64::ST1Threev4h_POST);
7255 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7256 SelectPostStore(
Node, 3, AArch64::ST1Threev8h_POST);
7258 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7259 SelectPostStore(
Node, 3, AArch64::ST1Threev2s_POST);
7261 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7262 SelectPostStore(
Node, 3, AArch64::ST1Threev4s_POST);
7264 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7265 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7267 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7268 SelectPostStore(
Node, 3, AArch64::ST1Threev2d_POST);
7273 case AArch64ISD::ST1x4post: {
7274 VT =
Node->getOperand(1).getValueType();
7275 if (VT == MVT::v8i8) {
7276 SelectPostStore(
Node, 4, AArch64::ST1Fourv8b_POST);
7278 }
else if (VT == MVT::v16i8) {
7279 SelectPostStore(
Node, 4, AArch64::ST1Fourv16b_POST);
7281 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7282 SelectPostStore(
Node, 4, AArch64::ST1Fourv4h_POST);
7284 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7285 SelectPostStore(
Node, 4, AArch64::ST1Fourv8h_POST);
7287 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7288 SelectPostStore(
Node, 4, AArch64::ST1Fourv2s_POST);
7290 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7291 SelectPostStore(
Node, 4, AArch64::ST1Fourv4s_POST);
7293 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7294 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7296 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7297 SelectPostStore(
Node, 4, AArch64::ST1Fourv2d_POST);
7302 case AArch64ISD::ST2LANEpost: {
7303 VT =
Node->getOperand(1).getValueType();
7304 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7305 SelectPostStoreLane(
Node, 2, AArch64::ST2i8_POST);
7307 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7308 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7309 SelectPostStoreLane(
Node, 2, AArch64::ST2i16_POST);
7311 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7313 SelectPostStoreLane(
Node, 2, AArch64::ST2i32_POST);
7315 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7317 SelectPostStoreLane(
Node, 2, AArch64::ST2i64_POST);
7322 case AArch64ISD::ST3LANEpost: {
7323 VT =
Node->getOperand(1).getValueType();
7324 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7325 SelectPostStoreLane(
Node, 3, AArch64::ST3i8_POST);
7327 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7328 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7329 SelectPostStoreLane(
Node, 3, AArch64::ST3i16_POST);
7331 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7333 SelectPostStoreLane(
Node, 3, AArch64::ST3i32_POST);
7335 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7337 SelectPostStoreLane(
Node, 3, AArch64::ST3i64_POST);
7342 case AArch64ISD::ST4LANEpost: {
7343 VT =
Node->getOperand(1).getValueType();
7344 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7345 SelectPostStoreLane(
Node, 4, AArch64::ST4i8_POST);
7347 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7348 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7349 SelectPostStoreLane(
Node, 4, AArch64::ST4i16_POST);
7351 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7353 SelectPostStoreLane(
Node, 4, AArch64::ST4i32_POST);
7355 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7357 SelectPostStoreLane(
Node, 4, AArch64::ST4i64_POST);
7372 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7384 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7388 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7389 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7403 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(Root))
7404 return MemIntr->getMemoryVT();
7406 if (isa<MemSDNode>(Root)) {
7407 EVT MemVT = cast<MemSDNode>(Root)->getMemoryVT();
7410 if (
auto *Load = dyn_cast<LoadSDNode>(Root))
7411 DataVT = Load->getValueType(0);
7412 else if (
auto *Load = dyn_cast<MaskedLoadSDNode>(Root))
7413 DataVT = Load->getValueType(0);
7414 else if (
auto *Store = dyn_cast<StoreSDNode>(Root))
7415 DataVT = Store->getValue().getValueType();
7416 else if (
auto *Store = dyn_cast<MaskedStoreSDNode>(Root))
7417 DataVT = Store->getValue().getValueType();
7424 const unsigned Opcode = Root->
getOpcode();
7428 case AArch64ISD::LD1_MERGE_ZERO:
7429 case AArch64ISD::LD1S_MERGE_ZERO:
7430 case AArch64ISD::LDNF1_MERGE_ZERO:
7431 case AArch64ISD::LDNF1S_MERGE_ZERO:
7432 return cast<VTSDNode>(Root->
getOperand(3))->getVT();
7433 case AArch64ISD::ST1_PRED:
7434 return cast<VTSDNode>(Root->
getOperand(4))->getVT();
7445 case Intrinsic::aarch64_sme_ldr:
7446 case Intrinsic::aarch64_sme_str:
7447 return MVT::nxv16i8;
7448 case Intrinsic::aarch64_sve_prf:
7453 case Intrinsic::aarch64_sve_ld2_sret:
7454 case Intrinsic::aarch64_sve_ld2q_sret:
7457 case Intrinsic::aarch64_sve_st2q:
7460 case Intrinsic::aarch64_sve_ld3_sret:
7461 case Intrinsic::aarch64_sve_ld3q_sret:
7464 case Intrinsic::aarch64_sve_st3q:
7467 case Intrinsic::aarch64_sve_ld4_sret:
7468 case Intrinsic::aarch64_sve_ld4q_sret:
7471 case Intrinsic::aarch64_sve_st4q:
7474 case Intrinsic::aarch64_sve_ld1udq:
7475 case Intrinsic::aarch64_sve_st1dq:
7476 return EVT(MVT::nxv1i64);
7477 case Intrinsic::aarch64_sve_ld1uwq:
7478 case Intrinsic::aarch64_sve_st1wq:
7479 return EVT(MVT::nxv1i32);
7486template <
int64_t Min,
int64_t Max>
7487bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(
SDNode *Root,
SDValue N,
7495 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
7500 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7514 int64_t MulImm = std::numeric_limits<int64_t>::max();
7516 MulImm = cast<ConstantSDNode>(VScale.
getOperand(0))->getSExtValue();
7517 }
else if (
auto C = dyn_cast<ConstantSDNode>(VScale)) {
7518 int64_t ByteOffset =
C->getSExtValue();
7519 const auto KnownVScale =
7522 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7525 MulImm = ByteOffset / KnownVScale;
7532 if ((MulImm % MemWidthBytes) != 0)
7535 int64_t
Offset = MulImm / MemWidthBytes;
7536 if (Offset < Min || Offset > Max)
7539 Base =
N.getOperand(0);
7541 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
7548 OffImm = CurDAG->getTargetConstant(
Offset,
SDLoc(
N), MVT::i64);
7554bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7572 if (
auto C = dyn_cast<ConstantSDNode>(RHS)) {
7573 int64_t ImmOff =
C->getSExtValue();
7574 unsigned Size = 1 << Scale;
7583 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7585 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
7595 if (
auto *
C = dyn_cast<ConstantSDNode>(ShiftRHS))
7596 if (
C->getZExtValue() == Scale) {
7605bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7612bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7613 EVT VT =
N.getValueType();
7617bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7621 if (
auto *
C = dyn_cast<ConstantSDNode>(CN)) {
7622 int64_t ImmOff =
C->getSExtValue();
7623 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7624 return CurDAG->getTargetConstant(ImmOff / Scale,
SDLoc(
N), MVT::i64);
7629 if (
SDValue C = MatchConstantOffset(
N)) {
7630 Base = CurDAG->getConstant(0,
SDLoc(
N), MVT::i32);
7636 if (CurDAG->isBaseWithConstantOffset(
N)) {
7637 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7638 Base =
N.getOperand(0);
7646 Offset = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7650bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(
SDNode *
P,
SDValue N,
7654 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
7670 uint64_t LowerBound = 0, UpperBound = 64;
7688 if (CN->getAPIntValue().uge(LowerBound) &&
7689 CN->getAPIntValue().ult(UpperBound)) {
7691 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static 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 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 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 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
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
DEMANGLE_DUMP_METHOD void dump() const
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool isLittleEndian() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
bool getExactInverse(APFloat *Inv) const
If this value is normal and has an exact, normal, multiplicative inverse, store it in inv and return ...
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) 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.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
An arbitrary precision integer that knows its signedness.
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
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
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 getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint8_t getStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
A description of a memory reference used in the backend.
An SDNode that represents everything that will be needed to construct a MachineInstr.
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 bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
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 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...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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 bool processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t &Encoding)
processLogicalImmediate - Determine if an immediate value can be encoded as the immediate operand of ...
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 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.
@ 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...
@ 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).
@ Undef
Value of the register doesn't matter.
Not(const Pred &P) -> Not< Pred >
Reg
All possible values of the reg field in the ModR/M byte.
DiagnosticInfoOptimizationBase::Argument NV
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.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
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...
CodeGenOptLevel
Code generation optimization level.
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
constexpr unsigned BitWidth
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
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
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.
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.
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
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.