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,
bool Negate>
251 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
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);
501 bool AllowSaturation,
SDValue &Imm);
509 bool SelectAllActivePredicate(
SDValue N);
521 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
525char AArch64DAGToDAGISelLegacy::ID = 0;
533 Imm =
C->getZExtValue();
550 return N->getOpcode() ==
Opc &&
561 return Imm == ImmExpected;
565bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
567 std::vector<SDValue> &OutOps) {
568 switch(ConstraintID) {
571 case InlineAsm::ConstraintCode::m:
572 case InlineAsm::ConstraintCode::o:
573 case InlineAsm::ConstraintCode::Q:
579 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
581 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
582 dl,
Op.getValueType(),
584 OutOps.push_back(NewOp);
600 if (!isa<ConstantSDNode>(
N.getNode()))
603 uint64_t Immed =
N.getNode()->getAsZExtVal();
606 if (Immed >> 12 == 0) {
608 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
616 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
617 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
630 if (!isa<ConstantSDNode>(
N.getNode()))
634 uint64_t Immed =
N.getNode()->getAsZExtVal();
642 if (
N.getValueType() == MVT::i32)
645 Immed = ~Immed + 1ULL;
646 if (Immed & 0xFFFFFFFFFF000000ULL)
649 Immed &= 0xFFFFFFULL;
650 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(
N), MVT::i32), Val,
657 switch (
N.getOpcode()) {
672 return isa<MemSDNode>(*
N) ||
N->getOpcode() == AArch64ISD::PREFETCH;
680 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
683 unsigned ShiftVal = CSD->getZExtValue();
701bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
704 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
709 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
731bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(
SDValue N,
SDValue &Reg,
733 EVT VT =
N.getValueType();
734 if (VT != MVT::i32 && VT != MVT::i64)
737 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
743 unsigned LHSOpcode =
LHS->getOpcode();
757 unsigned LowZBits, MaskLen;
761 unsigned BitWidth =
N.getValueSizeInBits();
768 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
771 NewShiftC = LowZBits - ShiftAmtC;
772 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
778 NewShiftC = LowZBits + ShiftAmtC;
791 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
793 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
797 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
799 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
800 NewShiftAmt, BitWidthMinus1),
803 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
815 SrcVT = cast<VTSDNode>(
N.getOperand(1))->getVT();
817 SrcVT =
N.getOperand(0).getValueType();
819 if (!IsLoadStore && SrcVT == MVT::i8)
821 else if (!IsLoadStore && SrcVT == MVT::i16)
823 else if (SrcVT == MVT::i32)
825 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
830 EVT SrcVT =
N.getOperand(0).getValueType();
831 if (!IsLoadStore && SrcVT == MVT::i8)
833 else if (!IsLoadStore && SrcVT == MVT::i16)
835 else if (SrcVT == MVT::i32)
837 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
865bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
868 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
873 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
874 V.getConstantOperandVal(1) <= 4 &&
887bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
889 if (SelectShiftedRegisterFromAnd(
N, Reg, Shift))
899 unsigned BitSize =
N.getValueSizeInBits();
900 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
903 Reg =
N.getOperand(0);
904 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(
N), MVT::i32);
905 return isWorthFoldingALU(
N,
true);
916 if (
N.getValueType() == MVT::i32)
924template<
signed Low,
signed High,
signed Scale>
926 if (!isa<ConstantSDNode>(
N))
929 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
930 if ((MulImm % std::abs(Scale)) == 0) {
931 int64_t RDVLImm = MulImm / Scale;
932 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
933 Imm = CurDAG->getSignedTargetConstant(RDVLImm,
SDLoc(
N), MVT::i32);
943bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
945 unsigned ShiftVal = 0;
960 Reg =
N.getOperand(0).getOperand(0);
966 Reg =
N.getOperand(0);
971 unsigned Opc =
N.getOpcode();
989 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
991 return isWorthFoldingALU(
N);
996bool AArch64DAGToDAGISel::SelectArithUXTXRegister(
SDValue N,
SDValue &Reg,
998 unsigned ShiftVal = 0;
1012 Reg =
N.getOperand(0);
1013 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
1015 return isWorthFoldingALU(
N);
1024 for (
auto *
User :
N->users()) {
1051bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1052 unsigned BW,
unsigned Size,
1059 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1061 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1067 if (CurDAG->isBaseWithConstantOffset(
N)) {
1068 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1070 int64_t RHSC =
RHS->getSExtValue();
1072 int64_t
Range = 0x1LL << (BW - 1);
1074 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1075 RHSC < (
Range << Scale)) {
1076 Base =
N.getOperand(0);
1078 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1081 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1090 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1091 Base =
N.getOperand(0);
1093 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1096 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1107 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1114bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1120 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1122 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1128 dyn_cast<GlobalAddressSDNode>(
N.getOperand(1).getNode());
1129 Base =
N.getOperand(0);
1130 OffImm =
N.getOperand(1);
1139 if (CurDAG->isBaseWithConstantOffset(
N)) {
1140 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1141 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1144 Base =
N.getOperand(0);
1146 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1149 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1157 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1165 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1174bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1177 if (!CurDAG->isBaseWithConstantOffset(
N))
1179 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1180 int64_t RHSC =
RHS->getSExtValue();
1181 if (RHSC >= -256 && RHSC < 256) {
1182 Base =
N.getOperand(0);
1184 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1186 Base = CurDAG->getTargetFrameIndex(
1189 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(
N), MVT::i64);
1199 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1206bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1226 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1232 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1235 return isWorthFoldingAddr(
N,
Size);
1238bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1250 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1263 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1266 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1267 SelectExtendedSHL(RHS,
Size,
true,
Offset, SignExtend)) {
1269 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1274 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1275 SelectExtendedSHL(LHS,
Size,
true,
Offset, SignExtend)) {
1277 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1282 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1286 if (IsExtendedRegisterWorthFolding &&
1293 if (isWorthFoldingAddr(LHS,
Size))
1298 if (IsExtendedRegisterWorthFolding &&
1305 if (isWorthFoldingAddr(RHS,
Size))
1317 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1320 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1322 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1323 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1327bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1357 if (isa<ConstantSDNode>(RHS)) {
1358 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1368 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
1371 N = CurDAG->getNode(
ISD::ADD,
DL, MVT::i64, LHS, MOVIV);
1375 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1378 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1379 SelectExtendedSHL(RHS,
Size,
false,
Offset, SignExtend)) {
1381 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1386 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1387 SelectExtendedSHL(LHS,
Size,
false,
Offset, SignExtend)) {
1389 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1396 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1397 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1403 static const unsigned RegClassIDs[] = {
1404 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1405 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1406 AArch64::dsub2, AArch64::dsub3};
1412 static const unsigned RegClassIDs[] = {
1413 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1414 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1415 AArch64::qsub2, AArch64::qsub3};
1421 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1422 AArch64::ZPR3RegClassID,
1423 AArch64::ZPR4RegClassID};
1424 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1425 AArch64::zsub2, AArch64::zsub3};
1435 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1436 AArch64::ZPR4Mul4RegClassID};
1437 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1438 AArch64::zsub2, AArch64::zsub3};
1443 const unsigned RegClassIDs[],
1444 const unsigned SubRegs[]) {
1447 if (Regs.
size() == 1)
1458 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1461 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1463 Ops.
push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1467 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped, Ops);
1471void AArch64DAGToDAGISel::SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1474 EVT VT =
N->getValueType(0);
1476 unsigned ExtOff = isExt;
1479 unsigned Vec0Off = ExtOff + 1;
1487 Ops.
push_back(
N->getOperand(NumVecs + ExtOff + 1));
1488 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT, Ops));
1491static std::tuple<SDValue, SDValue>
1511 auto *ConstDiscN = dyn_cast<ConstantSDNode>(ConstDisc);
1512 if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue()))
1517 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1519 return std::make_tuple(
1524void AArch64DAGToDAGISel::SelectPtrauthAuth(
SDNode *
N) {
1529 SDValue AUTDisc =
N->getOperand(3);
1531 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1532 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1534 SDValue AUTAddrDisc, AUTConstDisc;
1535 std::tie(AUTConstDisc, AUTAddrDisc) =
1538 if (!Subtarget->isX16X17Safer()) {
1539 SDValue Ops[] = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1542 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64, Ops);
1543 ReplaceNode(
N, AUT);
1545 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1546 AArch64::X16, Val,
SDValue());
1547 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1549 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64, Ops);
1550 ReplaceNode(
N, AUT);
1554void AArch64DAGToDAGISel::SelectPtrauthResign(
SDNode *
N) {
1559 SDValue AUTDisc =
N->getOperand(3);
1561 SDValue PACDisc =
N->getOperand(5);
1563 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1564 unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
1566 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1567 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1569 SDValue AUTAddrDisc, AUTConstDisc;
1570 std::tie(AUTConstDisc, AUTAddrDisc) =
1573 SDValue PACAddrDisc, PACConstDisc;
1574 std::tie(PACConstDisc, PACAddrDisc) =
1577 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1578 AArch64::X16, Val,
SDValue());
1580 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1581 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1583 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64, Ops);
1584 ReplaceNode(
N, AUTPAC);
1587bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
1589 if (
LD->isUnindexed())
1591 EVT VT =
LD->getMemoryVT();
1592 EVT DstVT =
N->getValueType(0);
1596 int OffsetVal = (int)
OffsetOp->getZExtValue();
1601 unsigned Opcode = 0;
1604 bool InsertTo64 =
false;
1606 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1607 else if (VT == MVT::i32) {
1609 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1611 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1613 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1619 }
else if (VT == MVT::i16) {
1621 if (DstVT == MVT::i64)
1622 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1624 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1626 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1627 InsertTo64 = DstVT == MVT::i64;
1632 }
else if (VT == MVT::i8) {
1634 if (DstVT == MVT::i64)
1635 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1637 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1639 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1640 InsertTo64 = DstVT == MVT::i64;
1645 }
else if (VT == MVT::f16) {
1646 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1647 }
else if (VT == MVT::bf16) {
1648 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1649 }
else if (VT == MVT::f32) {
1650 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1651 }
else if (VT == MVT::f64 ||
1653 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1655 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1657 if (IsPre || OffsetVal != 8)
1661 Opcode = AArch64::LD1Onev8b_POST;
1664 Opcode = AArch64::LD1Onev4h_POST;
1667 Opcode = AArch64::LD1Onev2s_POST;
1670 Opcode = AArch64::LD1Onev1d_POST;
1676 if (IsPre || OffsetVal != 16)
1680 Opcode = AArch64::LD1Onev16b_POST;
1683 Opcode = AArch64::LD1Onev8h_POST;
1686 Opcode = AArch64::LD1Onev4s_POST;
1689 Opcode = AArch64::LD1Onev2d_POST;
1701 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1702 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1704 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1709 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {
MemOp});
1714 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1716 SDValue(CurDAG->getMachineNode(
1717 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1718 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1723 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1726 CurDAG->RemoveDeadNode(
N);
1730void AArch64DAGToDAGISel::SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1731 unsigned SubRegIdx) {
1733 EVT VT =
N->getValueType(0);
1739 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1741 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
1743 for (
unsigned i = 0; i < NumVecs; ++i)
1745 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1751 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(
N)) {
1753 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
1756 CurDAG->RemoveDeadNode(
N);
1759void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
1760 unsigned Opc,
unsigned SubRegIdx) {
1762 EVT VT =
N->getValueType(0);
1769 const EVT ResTys[] = {MVT::i64,
1770 MVT::Untyped, MVT::Other};
1772 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
1780 ReplaceUses(
SDValue(
N, 0), SuperReg);
1782 for (
unsigned i = 0; i < NumVecs; ++i)
1784 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1788 CurDAG->RemoveDeadNode(
N);
1794std::tuple<unsigned, SDValue, SDValue>
1795AArch64DAGToDAGISel::findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
1801 SDValue NewOffset = OldOffset;
1803 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1804 N, OldBase, NewBase, NewOffset);
1808 const bool IsRegReg =
1809 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1812 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1825template <SelectTypeKind Kind>
1837 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1842 if (EltVT != MVT::i1)
1846 if (EltVT == MVT::bf16)
1848 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1878void AArch64DAGToDAGISel::SelectPExtPair(
SDNode *
N,
unsigned Opc) {
1881 if (
Imm->getZExtValue() > 1)
1885 EVT VT =
N->getValueType(0);
1886 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1887 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
1890 for (
unsigned I = 0;
I < 2; ++
I)
1891 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1892 AArch64::psub0 +
I,
DL, VT, SuperReg));
1894 CurDAG->RemoveDeadNode(
N);
1897void AArch64DAGToDAGISel::SelectWhilePair(
SDNode *
N,
unsigned Opc) {
1899 EVT VT =
N->getValueType(0);
1901 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1903 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
1906 for (
unsigned I = 0;
I < 2; ++
I)
1907 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1908 AArch64::psub0 +
I,
DL, VT, SuperReg));
1910 CurDAG->RemoveDeadNode(
N);
1913void AArch64DAGToDAGISel::SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
1915 EVT VT =
N->getValueType(0);
1917 SDValue Ops = createZTuple(Regs);
1921 for (
unsigned i = 0; i < NumVecs; ++i)
1922 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1923 AArch64::zsub0 + i,
DL, VT, SuperReg));
1925 CurDAG->RemoveDeadNode(
N);
1928void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
1931 EVT VT =
N->getValueType(0);
1933 Ops.push_back(
N->getOperand(0));
1936 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other}, Ops);
1939 for (
unsigned i = 0; i < NumVecs; ++i)
1940 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1941 AArch64::zsub0 + i,
DL, VT, SuperReg));
1944 unsigned ChainIdx = NumVecs;
1946 CurDAG->RemoveDeadNode(
N);
1949void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(
SDNode *
N,
1954 assert(Opcode != 0 &&
"Unexpected opcode");
1957 EVT VT =
N->getValueType(0);
1958 unsigned FirstVecIdx = HasPred ? 2 : 1;
1960 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1962 return createZMulTuple(Regs);
1965 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1969 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1971 Zm =
N->getOperand(NumVecs + FirstVecIdx);
1975 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1976 N->getOperand(1), Zdn, Zm);
1978 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
1980 for (
unsigned i = 0; i < NumVecs; ++i)
1981 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1982 AArch64::zsub0 + i,
DL, VT, SuperReg));
1984 CurDAG->RemoveDeadNode(
N);
1987void AArch64DAGToDAGISel::SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
1988 unsigned Scale,
unsigned Opc_ri,
1989 unsigned Opc_rr,
bool IsIntr) {
1990 assert(Scale < 5 &&
"Invalid scaling value.");
1992 EVT VT =
N->getValueType(0);
1999 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2000 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2002 SDValue Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
2006 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2010 for (
unsigned i = 0; i < NumVecs; ++i)
2011 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2012 AArch64::zsub0 + i,
DL, VT, SuperReg));
2015 unsigned ChainIdx = NumVecs;
2017 CurDAG->RemoveDeadNode(
N);
2020void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(
SDNode *
N,
2025 assert(Scale < 4 &&
"Invalid scaling value.");
2027 EVT VT =
N->getValueType(0);
2035 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2041 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2045 for (
unsigned i = 0; i < NumVecs; ++i)
2046 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2047 AArch64::zsub0 + i,
DL, VT, SuperReg));
2050 unsigned ChainIdx = NumVecs;
2052 CurDAG->RemoveDeadNode(
N);
2055void AArch64DAGToDAGISel::SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
2057 if (
N->getValueType(0) != MVT::nxv4f32)
2059 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2062void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(
SDNode *
Node,
2063 unsigned NumOutVecs,
2067 if (
Imm->getZExtValue() > MaxImm)
2071 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2076 EVT VT =
Node->getValueType(0);
2079 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2082 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2083 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2084 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2087 unsigned ChainIdx = NumOutVecs;
2089 CurDAG->RemoveDeadNode(
Node);
2092void AArch64DAGToDAGISel::SelectMultiVectorLuti(
SDNode *
Node,
2093 unsigned NumOutVecs,
2098 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2104 EVT VT =
Node->getValueType(0);
2107 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2110 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2111 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2112 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2115 unsigned ChainIdx = NumOutVecs;
2117 CurDAG->RemoveDeadNode(
Node);
2120void AArch64DAGToDAGISel::SelectClamp(
SDNode *
N,
unsigned NumVecs,
2123 EVT VT =
N->getValueType(0);
2126 SDValue Zd = createZMulTuple(Regs);
2127 SDValue Zn =
N->getOperand(1 + NumVecs);
2128 SDValue Zm =
N->getOperand(2 + NumVecs);
2134 for (
unsigned i = 0; i < NumVecs; ++i)
2135 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2136 AArch64::zsub0 + i,
DL, VT, SuperReg));
2138 CurDAG->RemoveDeadNode(
N);
2168template <
unsigned MaxIdx,
unsigned Scale>
2169void AArch64DAGToDAGISel::SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
2170 unsigned BaseReg,
unsigned Op) {
2171 unsigned TileNum = 0;
2172 if (BaseReg != AArch64::ZA)
2173 TileNum =
N->getConstantOperandVal(2);
2179 if (BaseReg == AArch64::ZA)
2180 SliceBase =
N->getOperand(2);
2182 SliceBase =
N->getOperand(3);
2184 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2190 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2192 EVT VT =
N->getValueType(0);
2193 for (
unsigned I = 0;
I < NumVecs; ++
I)
2195 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2198 unsigned ChainIdx = NumVecs;
2200 CurDAG->RemoveDeadNode(
N);
2203void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
2204 unsigned Op,
unsigned MaxIdx,
2205 unsigned Scale,
unsigned BaseReg) {
2209 SDValue SliceBase =
N->getOperand(2);
2210 if (BaseReg != AArch64::ZA)
2211 SliceBase =
N->getOperand(3);
2214 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2221 if (BaseReg != AArch64::ZA )
2226 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2228 EVT VT =
N->getValueType(0);
2229 for (
unsigned I = 0;
I < NumVecs; ++
I)
2231 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2235 unsigned ChainIdx = NumVecs;
2237 CurDAG->RemoveDeadNode(
N);
2240void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(
SDNode *
N,
2241 unsigned NumOutVecs,
2245 EVT VT =
N->getValueType(0);
2246 unsigned NumInVecs =
N->getNumOperands() - 1;
2250 assert((NumInVecs == 2 || NumInVecs == 4) &&
2251 "Don't know how to handle multi-register input!");
2256 for (
unsigned I = 0;
I < NumInVecs;
I++)
2260 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped, Ops);
2263 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2264 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2265 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2266 CurDAG->RemoveDeadNode(
N);
2269void AArch64DAGToDAGISel::SelectStore(
SDNode *
N,
unsigned NumVecs,
2272 EVT VT =
N->getOperand(2)->getValueType(0);
2279 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
N->getOperand(0)};
2280 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), Ops);
2284 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2289void AArch64DAGToDAGISel::SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
2290 unsigned Scale,
unsigned Opc_rr,
2296 SDValue RegSeq = createZTuple(Regs);
2302 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2303 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2305 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
2309 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), Ops);
2321 if (
auto FINode = dyn_cast<FrameIndexSDNode>(
N)) {
2322 int FI = FINode->getIndex();
2324 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2331void AArch64DAGToDAGISel::SelectPostStore(
SDNode *
N,
unsigned NumVecs,
2334 EVT VT =
N->getOperand(2)->getValueType(0);
2335 const EVT ResTys[] = {MVT::i64,
2344 N->getOperand(NumVecs + 1),
2345 N->getOperand(NumVecs + 2),
2347 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2387void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
2390 EVT VT =
N->getValueType(0);
2398 WidenVector(*CurDAG));
2402 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2404 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2406 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2407 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2408 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2412 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2413 AArch64::qsub2, AArch64::qsub3 };
2414 for (
unsigned i = 0; i < NumVecs; ++i) {
2415 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2422 CurDAG->RemoveDeadNode(
N);
2425void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
2428 EVT VT =
N->getValueType(0);
2436 WidenVector(*CurDAG));
2440 const EVT ResTys[] = {MVT::i64,
2443 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2446 CurDAG->getTargetConstant(LaneNo, dl,
2448 N->getOperand(NumVecs + 2),
2449 N->getOperand(NumVecs + 3),
2451 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2463 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2464 AArch64::qsub2, AArch64::qsub3 };
2465 for (
unsigned i = 0; i < NumVecs; ++i) {
2466 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2476 CurDAG->RemoveDeadNode(
N);
2479void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
2482 EVT VT =
N->getOperand(2)->getValueType(0);
2490 WidenVector(*CurDAG));
2494 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2496 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2497 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2498 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other, Ops);
2502 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2507void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
2510 EVT VT =
N->getOperand(2)->getValueType(0);
2518 WidenVector(*CurDAG));
2522 const EVT ResTys[] = {MVT::i64,
2525 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2527 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2528 N->getOperand(NumVecs + 2),
2529 N->getOperand(NumVecs + 3),
2531 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys, Ops);
2535 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2542 unsigned &LSB,
unsigned &MSB,
2543 unsigned NumberOfIgnoredLowBits,
2544 bool BiggerPattern) {
2546 "N must be a AND operation to call this function");
2548 EVT VT =
N->getValueType(0);
2553 assert((VT == MVT::i32 || VT == MVT::i64) &&
2554 "Type checking must have been done before calling this function");
2568 const SDNode *Op0 =
N->getOperand(0).getNode();
2572 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
2575 if (AndImm & (AndImm + 1))
2578 bool ClampMSB =
false;
2598 ClampMSB = (VT == MVT::i32);
2599 }
else if (BiggerPattern) {
2605 Opd0 =
N->getOperand(0);
2611 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2614 <<
": Found large shift immediate, this should not happen\n"));
2620 (VT == MVT::i32 ? llvm::countr_one<uint32_t>(AndImm)
2621 : llvm::countr_one<uint64_t>(AndImm)) -
2628 MSB = MSB > 31 ? 31 : MSB;
2630 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2635 SDValue &Opd0,
unsigned &Immr,
2639 EVT VT =
N->getValueType(0);
2641 assert((VT == MVT::i32 || VT == MVT::i64) &&
2642 "Type checking must have been done before calling this function");
2646 Op =
Op->getOperand(0);
2647 VT =
Op->getValueType(0);
2656 unsigned Width = cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2660 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2661 Opd0 =
Op.getOperand(0);
2663 Imms = ShiftImm + Width - 1;
2691 Opd0 =
N->getOperand(0).getOperand(0);
2701 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2708 unsigned &Immr,
unsigned &Imms,
2709 bool BiggerPattern) {
2711 "N must be a SHR/SRA operation to call this function");
2713 EVT VT =
N->getValueType(0);
2718 assert((VT == MVT::i32 || VT == MVT::i64) &&
2719 "Type checking must have been done before calling this function");
2729 Opd0 =
N->getOperand(0).getOperand(0);
2730 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2736 Opd0 =
N->getOperand(0).getOperand(0);
2739 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2740 }
else if (BiggerPattern) {
2744 Opd0 =
N->getOperand(0);
2753 <<
": Found large shift immediate, this should not happen\n"));
2762 "bad amount in shift node!");
2763 int immr = SrlImm - ShlImm;
2768 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2770 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2774bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *
N) {
2777 EVT VT =
N->getValueType(0);
2778 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2779 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2790 unsigned Immr = ShiftImm;
2792 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2793 CurDAG->getTargetConstant(Imms, dl, VT)};
2794 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT, Ops);
2799 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2800 unsigned NumberOfIgnoredLowBits = 0,
2801 bool BiggerPattern =
false) {
2802 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2805 switch (
N->getOpcode()) {
2807 if (!
N->isMachineOpcode())
2812 NumberOfIgnoredLowBits, BiggerPattern);
2821 unsigned NOpc =
N->getMachineOpcode();
2825 case AArch64::SBFMWri:
2826 case AArch64::UBFMWri:
2827 case AArch64::SBFMXri:
2828 case AArch64::UBFMXri:
2830 Opd0 =
N->getOperand(0);
2831 Immr =
N->getConstantOperandVal(1);
2832 Imms =
N->getConstantOperandVal(2);
2839bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *
N) {
2840 unsigned Opc, Immr, Imms;
2845 EVT VT =
N->getValueType(0);
2850 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2851 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2852 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2854 SDNode *
BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
2855 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2861 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2862 CurDAG->getTargetConstant(Imms, dl, VT)};
2863 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
2872 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2873 assert((VT == MVT::i32 || VT == MVT::i64) &&
2874 "i32 or i64 mask type expected!");
2878 APInt SignificantDstMask =
2882 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2883 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2906 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2916 APInt OpUsefulBits(UsefulBits);
2920 OpUsefulBits <<= MSB - Imm + 1;
2925 OpUsefulBits <<= Imm;
2927 OpUsefulBits <<= MSB + 1;
2930 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2936 UsefulBits &= OpUsefulBits;
2942 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2944 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2952 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2953 APInt Mask(UsefulBits);
2954 Mask.clearAllBits();
2962 Mask.lshrInPlace(ShiftAmt);
2968 Mask.lshrInPlace(ShiftAmt);
2980 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2982 cast<const ConstantSDNode>(
Op.getOperand(3).getNode())->getZExtValue();
2984 APInt OpUsefulBits(UsefulBits);
2998 OpUsefulBits <<= Width;
3001 if (
Op.getOperand(1) == Orig) {
3003 Mask = ResultUsefulBits & OpUsefulBits;
3007 if (
Op.getOperand(0) == Orig)
3009 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3015 OpUsefulBits <<= Width;
3017 OpUsefulBits <<= LSB;
3019 if (
Op.getOperand(1) == Orig) {
3021 Mask = ResultUsefulBits & OpUsefulBits;
3022 Mask.lshrInPlace(LSB);
3025 if (
Op.getOperand(0) == Orig)
3026 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3043 case AArch64::ANDSWri:
3044 case AArch64::ANDSXri:
3045 case AArch64::ANDWri:
3046 case AArch64::ANDXri:
3050 case AArch64::UBFMWri:
3051 case AArch64::UBFMXri:
3054 case AArch64::ORRWrs:
3055 case AArch64::ORRXrs:
3060 case AArch64::BFMWri:
3061 case AArch64::BFMXri:
3064 case AArch64::STRBBui:
3065 case AArch64::STURBBi:
3071 case AArch64::STRHHui:
3072 case AArch64::STURHHi:
3085 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3087 UsefulBits =
APInt(Bitwidth, 0);
3096 UsersUsefulBits |= UsefulBitsForUse;
3101 UsefulBits &= UsersUsefulBits;
3111 EVT VT =
Op.getValueType();
3114 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3117 if (ShlAmount > 0) {
3120 UBFMOpc, dl, VT,
Op,
3125 assert(ShlAmount < 0 &&
"expected right shift");
3126 int ShrAmount = -ShlAmount;
3152 bool BiggerPattern,
SDValue &Src,
3153 int &DstLSB,
int &Width) {
3154 EVT VT =
Op.getValueType();
3163 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3167 switch (
Op.getOpcode()) {
3172 NonZeroBits, Src, DstLSB, Width);
3175 NonZeroBits, Src, DstLSB, Width);
3188 EVT VT =
Op.getValueType();
3189 assert((VT == MVT::i32 || VT == MVT::i64) &&
3190 "Caller guarantees VT is one of i32 or i64");
3203 assert((~AndImm & NonZeroBits) == 0 &&
3204 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3233 if (!BiggerPattern && !AndOp0.
hasOneUse())
3252 <<
"Found large Width in bit-field-positioning -- this indicates no "
3253 "proper combining / constant folding was performed\n");
3262 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3277 "Op.getNode() should be a SHL node to call this function");
3279 "Op.getNode() should shift ShlImm to call this function");
3286 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3310 EVT VT =
Op.getValueType();
3311 assert((VT == MVT::i32 || VT == MVT::i64) &&
3312 "Caller guarantees that type is i32 or i64");
3319 if (!BiggerPattern && !
Op.hasOneUse())
3328 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3336 assert(VT == MVT::i32 || VT == MVT::i64);
3347 EVT VT =
N->getValueType(0);
3348 if (VT != MVT::i32 && VT != MVT::i64)
3366 if (!
And.hasOneUse() ||
3376 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3383 if ((OrImm & NotKnownZero) != 0) {
3395 unsigned ImmS = Width - 1;
3401 bool IsBFI = LSB != 0;
3406 unsigned OrChunks = 0, BFIChunks = 0;
3407 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3408 if (((OrImm >> Shift) & 0xFFFF) != 0)
3410 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3413 if (BFIChunks > OrChunks)
3419 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3427 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3436 if (!Dst.hasOneUse())
3439 EVT VT = Dst.getValueType();
3440 assert((VT == MVT::i32 || VT == MVT::i64) &&
3441 "Caller should guarantee that VT is one of i32 or i64");
3449 SDValue DstOp0 = Dst.getOperand(0);
3469 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3470 unsigned MaskWidth =
3473 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3479 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3480 ShiftedOperand =
SDValue(UBFMNode, 0);
3490 ShiftedOperand = Dst.getOperand(0);
3497 ShiftedOperand = Dst.getOperand(0);
3509 const bool BiggerPattern) {
3510 EVT VT =
N->getValueType(0);
3511 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3512 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3513 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3514 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3515 assert((VT == MVT::i32 || VT == MVT::i64) &&
3516 "Expect result type to be i32 or i64 since N is combinable to BFM");
3523 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3526 if (BiggerPattern) {
3540 SDValue Ops[] = {OrOpd0, ShiftedOperand,
3549 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3611 EVT VT =
N->getValueType(0);
3612 if (VT != MVT::i32 && VT != MVT::i64)
3620 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3621 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3641 for (
int I = 0;
I < 4; ++
I) {
3644 unsigned ImmR, ImmS;
3645 bool BiggerPattern =
I / 2;
3646 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3648 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3654 NumberOfIgnoredLowBits, BiggerPattern)) {
3657 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3658 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3663 Width = ImmS - ImmR + 1;
3674 Src, DstLSB, Width)) {
3682 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3692 APInt BitsToBeInserted =
3695 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3719 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3752 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3754 if (Src->hasOneUse() &&
3757 Src = Src->getOperand(0);
3767 unsigned ImmS = Width - 1;
3773 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3781bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *
N) {
3790 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3803bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *
N) {
3807 EVT VT =
N->getValueType(0);
3808 if (VT != MVT::i32 && VT != MVT::i64)
3814 Op0, DstLSB, Width))
3820 unsigned ImmS = Width - 1;
3823 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3824 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3825 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3826 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
3832bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
3833 EVT VT =
N->getValueType(0);
3836 switch (
N->getOpcode()) {
3838 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3841 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3844 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3847 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3855 if (VT == MVT::i32) {
3858 }
else if (VT == MVT::i64) {
3864 SDValue ShiftAmt =
N->getOperand(1);
3884 (Add0Imm %
Size == 0)) {
3890 if (SubVT == MVT::i32) {
3891 NegOpc = AArch64::SUBWrr;
3892 ZeroReg = AArch64::WZR;
3894 assert(SubVT == MVT::i64);
3895 NegOpc = AArch64::SUBXrr;
3896 ZeroReg = AArch64::XZR;
3899 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3901 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3902 NewShiftAmt =
SDValue(Neg, 0);
3910 if (SubVT == MVT::i32) {
3911 NotOpc = AArch64::ORNWrr;
3912 ZeroReg = AArch64::WZR;
3914 assert(SubVT == MVT::i64);
3915 NotOpc = AArch64::ORNXrr;
3916 ZeroReg = AArch64::XZR;
3919 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3921 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3922 NewShiftAmt =
SDValue(Not, 0);
3943 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3944 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3946 AArch64::SUBREG_TO_REG,
DL, VT,
3947 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3948 NewShiftAmt =
SDValue(Ext, 0);
3951 SDValue Ops[] = {
N->getOperand(0), NewShiftAmt};
3952 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
3959 bool isReciprocal) {
3962 FVal = CN->getValueAPF();
3963 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(
N)) {
3965 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
3966 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
3970 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
3971 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
3994 if (!IsExact || !IntVal.isPowerOf2())
3996 unsigned FBits = IntVal.logBase2();
4000 if (FBits == 0 || FBits > RegWidth)
return false;
4006bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4007 unsigned RegWidth) {
4012bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4014 unsigned RegWidth) {
4024 RegString.
split(Fields,
':');
4026 if (Fields.
size() == 1)
4030 &&
"Invalid number of fields in read register string");
4033 bool AllIntFields =
true;
4037 AllIntFields &= !
Field.getAsInteger(10, IntField);
4042 "Unexpected non-integer value in special register string.");
4047 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
4048 (Ops[3] << 3) | (Ops[4]);
4055bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *
N) {
4056 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4057 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4060 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4062 unsigned Opcode64Bit = AArch64::MRS;
4067 const auto *TheReg =
4068 AArch64SysReg::lookupSysRegByName(RegString->getString());
4069 if (TheReg && TheReg->Readable &&
4070 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4071 Imm = TheReg->Encoding;
4077 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4078 Opcode64Bit = AArch64::ADR;
4086 SDValue InChain =
N->getOperand(0);
4087 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4088 if (!ReadIs128Bit) {
4089 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4090 {SysRegImm, InChain});
4092 SDNode *MRRS = CurDAG->getMachineNode(
4094 {MVT::Untyped , MVT::Other },
4095 {SysRegImm, InChain});
4099 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4101 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4107 ReplaceUses(
SDValue(
N, 2), OutChain);
4116bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *
N) {
4117 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4118 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4121 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4123 if (!WriteIs128Bit) {
4129 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4131 assert(isa<ConstantSDNode>(
N->getOperand(2)) &&
4132 "Expected a constant integer expression.");
4133 unsigned Reg = PMapper->Encoding;
4134 uint64_t Immed =
N->getConstantOperandVal(2);
4135 CurDAG->SelectNodeTo(
4136 N, State, MVT::Other, CurDAG->getTargetConstant(Reg,
DL, MVT::i32),
4137 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4143 if (trySelectPState(
4144 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4145 AArch64::MSRpstateImm4))
4147 if (trySelectPState(
4148 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4149 AArch64::MSRpstateImm1))
4158 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4159 if (TheReg && TheReg->Writeable &&
4160 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4161 Imm = TheReg->Encoding;
4169 SDValue InChain =
N->getOperand(0);
4170 if (!WriteIs128Bit) {
4171 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4172 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4173 N->getOperand(2), InChain);
4177 SDNode *Pair = CurDAG->getMachineNode(
4178 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4179 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4182 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4184 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4186 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4187 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4195bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *
N) {
4197 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
4200 if (Subtarget->hasLSE())
return false;
4202 if (MemTy == MVT::i8)
4203 Opcode = AArch64::CMP_SWAP_8;
4204 else if (MemTy == MVT::i16)
4205 Opcode = AArch64::CMP_SWAP_16;
4206 else if (MemTy == MVT::i32)
4207 Opcode = AArch64::CMP_SWAP_32;
4208 else if (MemTy == MVT::i64)
4209 Opcode = AArch64::CMP_SWAP_64;
4213 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4214 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4216 SDNode *CmpSwap = CurDAG->getMachineNode(
4218 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
4221 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {
MemOp});
4225 CurDAG->RemoveDeadNode(
N);
4231 SDValue &Shift,
bool Negate) {
4232 if (!isa<ConstantSDNode>(
N))
4245 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4252 if ((Val & ~0xff) == 0) {
4253 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4258 if ((Val & ~0xff00) == 0) {
4259 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4271bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N,
MVT VT,
4274 if (!isa<ConstantSDNode>(
N))
4278 int64_t Val = cast<ConstantSDNode>(
N)
4295 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4296 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4303 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4304 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4308 if (Val <= 65280 && Val % 256 == 0) {
4309 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4310 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4323 if (!isa<ConstantSDNode>(
N))
4327 int64_t Val = cast<ConstantSDNode>(
N)
4335 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4336 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4342 if (Val >= -128 && Val <= 127) {
4343 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4344 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4348 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) {
4349 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4350 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF,
DL, MVT::i32);
4361bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4362 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4363 int64_t ImmVal = CNode->getSExtValue();
4365 if (ImmVal >= -128 && ImmVal < 128) {
4366 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4374 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4375 uint64_t ImmVal = CNode->getZExtValue();
4385 ImmVal &= 0xFFFFFFFF;
4394 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4403 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4404 uint64_t ImmVal = CNode->getZExtValue();
4414 ImmVal |= ImmVal << 8;
4415 ImmVal |= ImmVal << 16;
4416 ImmVal |= ImmVal << 32;
4420 ImmVal |= ImmVal << 16;
4421 ImmVal |= ImmVal << 32;
4424 ImmVal &= 0xFFFFFFFF;
4425 ImmVal |= ImmVal << 32;
4435 Imm = CurDAG->getTargetConstant(encoding,
DL, MVT::i64);
4450 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
4451 uint64_t ImmVal = CN->getZExtValue();
4458 if (ImmVal >
High) {
4459 if (!AllowSaturation)
4464 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4471bool AArch64DAGToDAGISel::trySelectStackSlotTagP(
SDNode *
N) {
4475 if (!(isa<FrameIndexSDNode>(
N->getOperand(1)))) {
4487 int FI = cast<FrameIndexSDNode>(
N->getOperand(1))->getIndex();
4488 SDValue FiOp = CurDAG->getTargetFrameIndex(
4490 int TagOffset =
N->getConstantOperandVal(3);
4492 SDNode *Out = CurDAG->getMachineNode(
4493 AArch64::TAGPstack,
DL, MVT::i64,
4494 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->getOperand(2),
4495 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4496 ReplaceNode(
N, Out);
4500void AArch64DAGToDAGISel::SelectTagP(
SDNode *
N) {
4501 assert(isa<ConstantSDNode>(
N->getOperand(3)) &&
4502 "llvm.aarch64.tagp third argument must be an immediate");
4503 if (trySelectStackSlotTagP(
N))
4510 int TagOffset =
N->getConstantOperandVal(3);
4511 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4512 {
N->getOperand(1),
N->getOperand(2)});
4513 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4514 {
SDValue(N1, 0),
N->getOperand(2)});
4515 SDNode *N3 = CurDAG->getMachineNode(
4516 AArch64::ADDG,
DL, MVT::i64,
4517 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4518 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4522bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(
SDNode *
N) {
4526 if (
N->getConstantOperandVal(2) != 0)
4528 if (!
N->getOperand(0).isUndef())
4532 EVT VT =
N->getValueType(0);
4533 EVT InVT =
N->getOperand(1).getValueType();
4544 "Expected to insert into a packed scalable vector!");
4547 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4548 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4549 N->getOperand(1), RC));
4553bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(
SDNode *
N) {
4557 if (
N->getConstantOperandVal(1) != 0)
4561 EVT VT =
N->getValueType(0);
4562 EVT InVT =
N->getOperand(0).getValueType();
4573 "Expected to extract from a packed scalable vector!");
4576 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4577 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4578 N->getOperand(0), RC));
4582bool AArch64DAGToDAGISel::trySelectXAR(
SDNode *
N) {
4588 EVT VT =
N->getValueType(0);
4601 (Subtarget->hasSVE2() ||
4602 (Subtarget->hasSME() && Subtarget->isStreaming()))) {
4603 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4606 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4611 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4612 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4619 bool IsXOROperand =
true;
4621 IsXOROperand =
false;
4627 APInt ShlAmt, ShrAmt;
4635 if (!IsXOROperand) {
4637 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4640 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4641 SDNode *SubRegToReg = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL,
4642 VT, Zero, MOVIV, ZSub);
4652 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4653 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4654 AArch64::XAR_ZZZI_D})) {
4655 CurDAG->SelectNodeTo(
N,
Opc, VT, Ops);
4680 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4690 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4698 bool IsXOROperand =
true;
4700 IsXOROperand =
false;
4703 R1 =
XOR.getOperand(0);
4704 R2 =
XOR.getOperand(1);
4714 if (ShAmt + HsAmt != VTSizeInBits)
4717 if (!IsXOROperand) {
4720 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4729 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4735 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4736 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4738 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4741 if (
R2.getValueType() == VT)
4742 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4750 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT, Undef,
4755 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4764 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4765 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4766 AArch64::XAR_ZZZI_D}))
4767 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT, Ops);
4769 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT, Ops);
4772 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4778 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4779 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4782 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4783 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4789 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4793 ReplaceNode(
N, XAR);
4797void AArch64DAGToDAGISel::Select(
SDNode *
Node) {
4799 if (
Node->isMachineOpcode()) {
4801 Node->setNodeId(-1);
4806 EVT VT =
Node->getValueType(0);
4808 switch (
Node->getOpcode()) {
4813 if (SelectCMP_SWAP(
Node))
4818 case AArch64ISD::MRRS:
4819 if (tryReadRegister(
Node))
4824 case AArch64ISD::MSRR:
4825 if (tryWriteRegister(
Node))
4832 if (tryIndexedLoad(
Node))
4841 if (tryBitfieldExtractOp(
Node))
4843 if (tryBitfieldInsertInZeroOp(
Node))
4848 if (tryShiftAmountMod(
Node))
4853 if (tryBitfieldExtractOpFromSExt(
Node))
4858 if (tryBitfieldInsertOp(
Node))
4860 if (trySelectXAR(
Node))
4865 if (trySelectCastScalableToFixedLengthVector(
Node))
4871 if (trySelectCastFixedLengthToScalableVector(
Node))
4880 if (ConstNode->
isZero()) {
4881 if (VT == MVT::i32) {
4883 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::WZR, MVT::i32);
4884 ReplaceNode(
Node,
New.getNode());
4886 }
else if (VT == MVT::i64) {
4888 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::XZR, MVT::i64);
4889 ReplaceNode(
Node,
New.getNode());
4898 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
4901 SDValue TFI = CurDAG->getTargetFrameIndex(
4904 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4905 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4906 CurDAG->SelectNodeTo(
Node, AArch64::ADDXri, MVT::i64, Ops);
4910 unsigned IntNo =
Node->getConstantOperandVal(1);
4914 case Intrinsic::aarch64_gcsss: {
4918 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4920 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4921 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4922 MVT::Other, Zero,
SDValue(SS1, 0));
4923 ReplaceNode(
Node, SS2);
4926 case Intrinsic::aarch64_ldaxp:
4927 case Intrinsic::aarch64_ldxp: {
4929 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4934 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4935 MVT::Other, MemAddr, Chain);
4939 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4940 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
4941 ReplaceNode(
Node, Ld);
4944 case Intrinsic::aarch64_stlxp:
4945 case Intrinsic::aarch64_stxp: {
4947 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4955 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4957 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other, Ops);
4960 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4961 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
4963 ReplaceNode(
Node, St);
4966 case Intrinsic::aarch64_neon_ld1x2:
4967 if (VT == MVT::v8i8) {
4968 SelectLoad(
Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4970 }
else if (VT == MVT::v16i8) {
4971 SelectLoad(
Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4973 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4974 SelectLoad(
Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4976 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4977 SelectLoad(
Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4979 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4980 SelectLoad(
Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4982 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4983 SelectLoad(
Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4985 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4986 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4988 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4989 SelectLoad(
Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4993 case Intrinsic::aarch64_neon_ld1x3:
4994 if (VT == MVT::v8i8) {
4995 SelectLoad(
Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
4997 }
else if (VT == MVT::v16i8) {
4998 SelectLoad(
Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5000 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5001 SelectLoad(
Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5003 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5004 SelectLoad(
Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5006 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5007 SelectLoad(
Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5009 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5010 SelectLoad(
Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5012 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5013 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5015 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5016 SelectLoad(
Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5020 case Intrinsic::aarch64_neon_ld1x4:
5021 if (VT == MVT::v8i8) {
5022 SelectLoad(
Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5024 }
else if (VT == MVT::v16i8) {
5025 SelectLoad(
Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5027 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5028 SelectLoad(
Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5030 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5031 SelectLoad(
Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5033 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5034 SelectLoad(
Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5036 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5037 SelectLoad(
Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5039 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5040 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5042 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5043 SelectLoad(
Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5047 case Intrinsic::aarch64_neon_ld2:
5048 if (VT == MVT::v8i8) {
5049 SelectLoad(
Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5051 }
else if (VT == MVT::v16i8) {
5052 SelectLoad(
Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5054 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5055 SelectLoad(
Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5057 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5058 SelectLoad(
Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5060 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5061 SelectLoad(
Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5063 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5064 SelectLoad(
Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5066 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5067 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5069 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5070 SelectLoad(
Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5074 case Intrinsic::aarch64_neon_ld3:
5075 if (VT == MVT::v8i8) {
5076 SelectLoad(
Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5078 }
else if (VT == MVT::v16i8) {
5079 SelectLoad(
Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5081 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5082 SelectLoad(
Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5084 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5085 SelectLoad(
Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5087 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5088 SelectLoad(
Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5090 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5091 SelectLoad(
Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5093 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5094 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5096 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5097 SelectLoad(
Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5101 case Intrinsic::aarch64_neon_ld4:
5102 if (VT == MVT::v8i8) {
5103 SelectLoad(
Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5105 }
else if (VT == MVT::v16i8) {
5106 SelectLoad(
Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5108 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5109 SelectLoad(
Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5111 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5112 SelectLoad(
Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5114 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5115 SelectLoad(
Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5117 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5118 SelectLoad(
Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5120 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5121 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5123 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5124 SelectLoad(
Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5128 case Intrinsic::aarch64_neon_ld2r:
5129 if (VT == MVT::v8i8) {
5130 SelectLoad(
Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5132 }
else if (VT == MVT::v16i8) {
5133 SelectLoad(
Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5135 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5136 SelectLoad(
Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5138 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5139 SelectLoad(
Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5141 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5142 SelectLoad(
Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5144 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5145 SelectLoad(
Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5147 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5148 SelectLoad(
Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5150 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5151 SelectLoad(
Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5155 case Intrinsic::aarch64_neon_ld3r:
5156 if (VT == MVT::v8i8) {
5157 SelectLoad(
Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5159 }
else if (VT == MVT::v16i8) {
5160 SelectLoad(
Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5162 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5163 SelectLoad(
Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5165 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5166 SelectLoad(
Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5168 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5169 SelectLoad(
Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5171 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5172 SelectLoad(
Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5174 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5175 SelectLoad(
Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5177 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5178 SelectLoad(
Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5182 case Intrinsic::aarch64_neon_ld4r:
5183 if (VT == MVT::v8i8) {
5184 SelectLoad(
Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5186 }
else if (VT == MVT::v16i8) {
5187 SelectLoad(
Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5189 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5190 SelectLoad(
Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5192 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5193 SelectLoad(
Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5195 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5196 SelectLoad(
Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5198 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5199 SelectLoad(
Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5201 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5202 SelectLoad(
Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5204 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5205 SelectLoad(
Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5209 case Intrinsic::aarch64_neon_ld2lane:
5210 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5211 SelectLoadLane(
Node, 2, AArch64::LD2i8);
5213 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5214 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5215 SelectLoadLane(
Node, 2, AArch64::LD2i16);
5217 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5219 SelectLoadLane(
Node, 2, AArch64::LD2i32);
5221 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5223 SelectLoadLane(
Node, 2, AArch64::LD2i64);
5227 case Intrinsic::aarch64_neon_ld3lane:
5228 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5229 SelectLoadLane(
Node, 3, AArch64::LD3i8);
5231 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5232 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5233 SelectLoadLane(
Node, 3, AArch64::LD3i16);
5235 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5237 SelectLoadLane(
Node, 3, AArch64::LD3i32);
5239 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5241 SelectLoadLane(
Node, 3, AArch64::LD3i64);
5245 case Intrinsic::aarch64_neon_ld4lane:
5246 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5247 SelectLoadLane(
Node, 4, AArch64::LD4i8);
5249 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5250 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5251 SelectLoadLane(
Node, 4, AArch64::LD4i16);
5253 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5255 SelectLoadLane(
Node, 4, AArch64::LD4i32);
5257 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5259 SelectLoadLane(
Node, 4, AArch64::LD4i64);
5263 case Intrinsic::aarch64_ld64b:
5264 SelectLoad(
Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5266 case Intrinsic::aarch64_sve_ld2q_sret: {
5267 SelectPredicatedLoad(
Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5270 case Intrinsic::aarch64_sve_ld3q_sret: {
5271 SelectPredicatedLoad(
Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5274 case Intrinsic::aarch64_sve_ld4q_sret: {
5275 SelectPredicatedLoad(
Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5278 case Intrinsic::aarch64_sve_ld2_sret: {
5279 if (VT == MVT::nxv16i8) {
5280 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5283 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5284 VT == MVT::nxv8bf16) {
5285 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5288 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5289 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5292 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5293 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5299 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5300 if (VT == MVT::nxv16i8) {
5301 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5302 SelectContiguousMultiVectorLoad(
5303 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5304 else if (Subtarget->hasSVE2p1())
5305 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LD1B_2Z_IMM,
5310 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5311 VT == MVT::nxv8bf16) {
5312 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5313 SelectContiguousMultiVectorLoad(
5314 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5315 else if (Subtarget->hasSVE2p1())
5316 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LD1H_2Z_IMM,
5321 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5322 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5323 SelectContiguousMultiVectorLoad(
5324 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5325 else if (Subtarget->hasSVE2p1())
5326 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LD1W_2Z_IMM,
5331 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5332 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5333 SelectContiguousMultiVectorLoad(
5334 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5335 else if (Subtarget->hasSVE2p1())
5336 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LD1D_2Z_IMM,
5344 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5345 if (VT == MVT::nxv16i8) {
5346 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5347 SelectContiguousMultiVectorLoad(
5348 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5349 else if (Subtarget->hasSVE2p1())
5350 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LD1B_4Z_IMM,
5355 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5356 VT == MVT::nxv8bf16) {
5357 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5358 SelectContiguousMultiVectorLoad(
5359 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5360 else if (Subtarget->hasSVE2p1())
5361 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LD1H_4Z_IMM,
5366 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5367 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5368 SelectContiguousMultiVectorLoad(
5369 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5370 else if (Subtarget->hasSVE2p1())
5371 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LD1W_4Z_IMM,
5376 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5377 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5378 SelectContiguousMultiVectorLoad(
5379 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5380 else if (Subtarget->hasSVE2p1())
5381 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LD1D_4Z_IMM,
5389 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5390 if (VT == MVT::nxv16i8) {
5391 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5392 SelectContiguousMultiVectorLoad(
Node, 2, 0,
5393 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5394 AArch64::LDNT1B_2Z_PSEUDO);
5395 else if (Subtarget->hasSVE2p1())
5396 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5397 AArch64::LDNT1B_2Z);
5401 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5402 VT == MVT::nxv8bf16) {
5403 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5404 SelectContiguousMultiVectorLoad(
Node, 2, 1,
5405 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5406 AArch64::LDNT1H_2Z_PSEUDO);
5407 else if (Subtarget->hasSVE2p1())
5408 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5409 AArch64::LDNT1H_2Z);
5413 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5414 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5415 SelectContiguousMultiVectorLoad(
Node, 2, 2,
5416 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5417 AArch64::LDNT1W_2Z_PSEUDO);
5418 else if (Subtarget->hasSVE2p1())
5419 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5420 AArch64::LDNT1W_2Z);
5424 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5425 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5426 SelectContiguousMultiVectorLoad(
Node, 2, 3,
5427 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5428 AArch64::LDNT1D_2Z_PSEUDO);
5429 else if (Subtarget->hasSVE2p1())
5430 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5431 AArch64::LDNT1D_2Z);
5438 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5439 if (VT == MVT::nxv16i8) {
5440 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5441 SelectContiguousMultiVectorLoad(
Node, 4, 0,
5442 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5443 AArch64::LDNT1B_4Z_PSEUDO);
5444 else if (Subtarget->hasSVE2p1())
5445 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5446 AArch64::LDNT1B_4Z);
5450 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5451 VT == MVT::nxv8bf16) {
5452 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5453 SelectContiguousMultiVectorLoad(
Node, 4, 1,
5454 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5455 AArch64::LDNT1H_4Z_PSEUDO);
5456 else if (Subtarget->hasSVE2p1())
5457 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5458 AArch64::LDNT1H_4Z);
5462 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5463 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5464 SelectContiguousMultiVectorLoad(
Node, 4, 2,
5465 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5466 AArch64::LDNT1W_4Z_PSEUDO);
5467 else if (Subtarget->hasSVE2p1())
5468 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5469 AArch64::LDNT1W_4Z);
5473 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5474 if (Subtarget->hasSME2() && Subtarget->isStreaming())
5475 SelectContiguousMultiVectorLoad(
Node, 4, 3,
5476 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5477 AArch64::LDNT1D_4Z_PSEUDO);
5478 else if (Subtarget->hasSVE2p1())
5479 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5480 AArch64::LDNT1D_4Z);
5487 case Intrinsic::aarch64_sve_ld3_sret: {
5488 if (VT == MVT::nxv16i8) {
5489 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5492 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5493 VT == MVT::nxv8bf16) {
5494 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5497 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5498 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5501 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5502 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5508 case Intrinsic::aarch64_sve_ld4_sret: {
5509 if (VT == MVT::nxv16i8) {
5510 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5513 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5514 VT == MVT::nxv8bf16) {
5515 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5518 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5519 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5522 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5523 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5529 case Intrinsic::aarch64_sme_read_hor_vg2: {
5530 if (VT == MVT::nxv16i8) {
5531 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5532 AArch64::MOVA_2ZMXI_H_B);
5534 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5535 VT == MVT::nxv8bf16) {
5536 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5537 AArch64::MOVA_2ZMXI_H_H);
5539 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5540 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5541 AArch64::MOVA_2ZMXI_H_S);
5543 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5544 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5545 AArch64::MOVA_2ZMXI_H_D);
5550 case Intrinsic::aarch64_sme_read_ver_vg2: {
5551 if (VT == MVT::nxv16i8) {
5552 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5553 AArch64::MOVA_2ZMXI_V_B);
5555 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5556 VT == MVT::nxv8bf16) {
5557 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5558 AArch64::MOVA_2ZMXI_V_H);
5560 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5561 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5562 AArch64::MOVA_2ZMXI_V_S);
5564 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5565 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5566 AArch64::MOVA_2ZMXI_V_D);
5571 case Intrinsic::aarch64_sme_read_hor_vg4: {
5572 if (VT == MVT::nxv16i8) {
5573 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5574 AArch64::MOVA_4ZMXI_H_B);
5576 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5577 VT == MVT::nxv8bf16) {
5578 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5579 AArch64::MOVA_4ZMXI_H_H);
5581 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5582 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAS0,
5583 AArch64::MOVA_4ZMXI_H_S);
5585 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5586 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAD0,
5587 AArch64::MOVA_4ZMXI_H_D);
5592 case Intrinsic::aarch64_sme_read_ver_vg4: {
5593 if (VT == MVT::nxv16i8) {
5594 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5595 AArch64::MOVA_4ZMXI_V_B);
5597 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5598 VT == MVT::nxv8bf16) {
5599 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5600 AArch64::MOVA_4ZMXI_V_H);
5602 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5603 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAS0,
5604 AArch64::MOVA_4ZMXI_V_S);
5606 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5607 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAD0,
5608 AArch64::MOVA_4ZMXI_V_D);
5613 case Intrinsic::aarch64_sme_read_vg1x2: {
5614 SelectMultiVectorMove<7, 1>(
Node, 2, AArch64::ZA,
5615 AArch64::MOVA_VG2_2ZMXI);
5618 case Intrinsic::aarch64_sme_read_vg1x4: {
5619 SelectMultiVectorMove<7, 1>(
Node, 4, AArch64::ZA,
5620 AArch64::MOVA_VG4_4ZMXI);
5623 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5624 if (VT == MVT::nxv16i8) {
5625 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5627 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5628 VT == MVT::nxv8bf16) {
5629 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5631 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5632 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5634 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5635 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5640 case Intrinsic::aarch64_sme_readz_vert_x2: {
5641 if (VT == MVT::nxv16i8) {
5642 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5644 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5645 VT == MVT::nxv8bf16) {
5646 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5648 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5649 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5651 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5652 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5657 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5658 if (VT == MVT::nxv16i8) {
5659 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5661 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5662 VT == MVT::nxv8bf16) {
5663 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5665 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5666 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5668 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5669 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5674 case Intrinsic::aarch64_sme_readz_vert_x4: {
5675 if (VT == MVT::nxv16i8) {
5676 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5678 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5679 VT == MVT::nxv8bf16) {
5680 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5682 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5683 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5685 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5686 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5691 case Intrinsic::aarch64_sme_readz_x2: {
5692 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5696 case Intrinsic::aarch64_sme_readz_x4: {
5697 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5701 case Intrinsic::swift_async_context_addr: {
5704 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5706 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5707 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5708 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5712 CurDAG->RemoveDeadNode(
Node);
5714 auto &MF = CurDAG->getMachineFunction();
5715 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5719 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5720 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5721 Node->getValueType(0),
5722 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5723 AArch64::LUTI2_4ZTZI_S}))
5725 SelectMultiVectorLutiLane(
Node, 4,
Opc, 3);
5728 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5729 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5730 Node->getValueType(0),
5731 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5733 SelectMultiVectorLutiLane(
Node, 4,
Opc, 1);
5736 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5737 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5738 Node->getValueType(0),
5739 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5740 AArch64::LUTI2_2ZTZI_S}))
5742 SelectMultiVectorLutiLane(
Node, 2,
Opc, 7);
5745 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5746 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5747 Node->getValueType(0),
5748 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5749 AArch64::LUTI4_2ZTZI_S}))
5751 SelectMultiVectorLutiLane(
Node, 2,
Opc, 3);
5754 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5755 SelectMultiVectorLuti(
Node, 4, AArch64::LUTI4_4ZZT2Z);
5758 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5759 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5760 Node->getValueType(0),
5761 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5762 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5764 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5765 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5766 Node->getValueType(0),
5767 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5768 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5770 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5771 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5772 Node->getValueType(0),
5773 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5774 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5776 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5777 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5778 Node->getValueType(0),
5779 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5780 SelectCVTIntrinsicFP8(
Node, 2,
Opc);
5785 unsigned IntNo =
Node->getConstantOperandVal(0);
5789 case Intrinsic::aarch64_tagp:
5793 case Intrinsic::ptrauth_auth:
5794 SelectPtrauthAuth(
Node);
5797 case Intrinsic::ptrauth_resign:
5798 SelectPtrauthResign(
Node);
5801 case Intrinsic::aarch64_neon_tbl2:
5802 SelectTable(
Node, 2,
5803 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5806 case Intrinsic::aarch64_neon_tbl3:
5807 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5808 : AArch64::TBLv16i8Three,
5811 case Intrinsic::aarch64_neon_tbl4:
5812 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5813 : AArch64::TBLv16i8Four,
5816 case Intrinsic::aarch64_neon_tbx2:
5817 SelectTable(
Node, 2,
5818 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5821 case Intrinsic::aarch64_neon_tbx3:
5822 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5823 : AArch64::TBXv16i8Three,
5826 case Intrinsic::aarch64_neon_tbx4:
5827 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5828 : AArch64::TBXv16i8Four,
5831 case Intrinsic::aarch64_sve_srshl_single_x2:
5832 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5833 Node->getValueType(0),
5834 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5835 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5836 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5838 case Intrinsic::aarch64_sve_srshl_single_x4:
5839 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5840 Node->getValueType(0),
5841 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5842 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5843 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5845 case Intrinsic::aarch64_sve_urshl_single_x2:
5846 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5847 Node->getValueType(0),
5848 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5849 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5850 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5852 case Intrinsic::aarch64_sve_urshl_single_x4:
5853 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5854 Node->getValueType(0),
5855 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5856 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5857 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5859 case Intrinsic::aarch64_sve_srshl_x2:
5860 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5861 Node->getValueType(0),
5862 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5863 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5864 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5866 case Intrinsic::aarch64_sve_srshl_x4:
5867 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5868 Node->getValueType(0),
5869 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5870 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5871 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5873 case Intrinsic::aarch64_sve_urshl_x2:
5874 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5875 Node->getValueType(0),
5876 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5877 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5878 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5880 case Intrinsic::aarch64_sve_urshl_x4:
5881 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5882 Node->getValueType(0),
5883 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5884 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5885 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5887 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5888 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5889 Node->getValueType(0),
5890 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5891 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5892 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5894 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5895 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5896 Node->getValueType(0),
5897 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5898 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5899 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5901 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5902 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5903 Node->getValueType(0),
5904 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5905 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5906 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5908 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5909 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5910 Node->getValueType(0),
5911 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5912 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5913 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5915 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5916 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5917 Node->getValueType(0),
5918 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5919 AArch64::FSCALE_2ZZ_D}))
5920 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5922 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5923 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5924 Node->getValueType(0),
5925 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5926 AArch64::FSCALE_4ZZ_D}))
5927 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5929 case Intrinsic::aarch64_sme_fp8_scale_x2:
5930 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5931 Node->getValueType(0),
5932 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5933 AArch64::FSCALE_2Z2Z_D}))
5934 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5936 case Intrinsic::aarch64_sme_fp8_scale_x4:
5937 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5938 Node->getValueType(0),
5939 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5940 AArch64::FSCALE_4Z4Z_D}))
5941 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5943 case Intrinsic::aarch64_sve_whilege_x2:
5944 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5945 Node->getValueType(0),
5946 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5947 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5948 SelectWhilePair(
Node,
Op);
5950 case Intrinsic::aarch64_sve_whilegt_x2:
5951 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5952 Node->getValueType(0),
5953 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5954 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5955 SelectWhilePair(
Node,
Op);
5957 case Intrinsic::aarch64_sve_whilehi_x2:
5958 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5959 Node->getValueType(0),
5960 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5961 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5962 SelectWhilePair(
Node,
Op);
5964 case Intrinsic::aarch64_sve_whilehs_x2:
5965 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5966 Node->getValueType(0),
5967 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5968 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5969 SelectWhilePair(
Node,
Op);
5971 case Intrinsic::aarch64_sve_whilele_x2:
5972 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5973 Node->getValueType(0),
5974 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5975 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5976 SelectWhilePair(
Node,
Op);
5978 case Intrinsic::aarch64_sve_whilelo_x2:
5979 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5980 Node->getValueType(0),
5981 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5982 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5983 SelectWhilePair(
Node,
Op);
5985 case Intrinsic::aarch64_sve_whilels_x2:
5986 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5987 Node->getValueType(0),
5988 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5989 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5990 SelectWhilePair(
Node,
Op);
5992 case Intrinsic::aarch64_sve_whilelt_x2:
5993 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5994 Node->getValueType(0),
5995 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
5996 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
5997 SelectWhilePair(
Node,
Op);
5999 case Intrinsic::aarch64_sve_smax_single_x2:
6000 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6001 Node->getValueType(0),
6002 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6003 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6004 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6006 case Intrinsic::aarch64_sve_umax_single_x2:
6007 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6008 Node->getValueType(0),
6009 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6010 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6011 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6013 case Intrinsic::aarch64_sve_fmax_single_x2:
6014 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6015 Node->getValueType(0),
6016 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6017 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6018 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6020 case Intrinsic::aarch64_sve_smax_single_x4:
6021 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6022 Node->getValueType(0),
6023 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6024 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6025 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6027 case Intrinsic::aarch64_sve_umax_single_x4:
6028 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6029 Node->getValueType(0),
6030 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6031 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6032 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6034 case Intrinsic::aarch64_sve_fmax_single_x4:
6035 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6036 Node->getValueType(0),
6037 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6038 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6039 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6041 case Intrinsic::aarch64_sve_smin_single_x2:
6042 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6043 Node->getValueType(0),
6044 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6045 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6046 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6048 case Intrinsic::aarch64_sve_umin_single_x2:
6049 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6050 Node->getValueType(0),
6051 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6052 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6053 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6055 case Intrinsic::aarch64_sve_fmin_single_x2:
6056 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6057 Node->getValueType(0),
6058 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6059 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6060 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6062 case Intrinsic::aarch64_sve_smin_single_x4:
6063 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6064 Node->getValueType(0),
6065 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6066 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6067 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6069 case Intrinsic::aarch64_sve_umin_single_x4:
6070 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6071 Node->getValueType(0),
6072 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6073 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6074 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6076 case Intrinsic::aarch64_sve_fmin_single_x4:
6077 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6078 Node->getValueType(0),
6079 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6080 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6081 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6083 case Intrinsic::aarch64_sve_smax_x2:
6084 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6085 Node->getValueType(0),
6086 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6087 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6088 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6090 case Intrinsic::aarch64_sve_umax_x2:
6091 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6092 Node->getValueType(0),
6093 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6094 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6095 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6097 case Intrinsic::aarch64_sve_fmax_x2:
6098 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6099 Node->getValueType(0),
6100 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6101 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6102 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6104 case Intrinsic::aarch64_sve_smax_x4:
6105 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6106 Node->getValueType(0),
6107 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6108 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6109 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6111 case Intrinsic::aarch64_sve_umax_x4:
6112 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6113 Node->getValueType(0),
6114 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6115 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6116 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6118 case Intrinsic::aarch64_sve_fmax_x4:
6119 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6120 Node->getValueType(0),
6121 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6122 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6123 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6125 case Intrinsic::aarch64_sme_famax_x2:
6126 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6127 Node->getValueType(0),
6128 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6129 AArch64::FAMAX_2Z2Z_D}))
6130 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6132 case Intrinsic::aarch64_sme_famax_x4:
6133 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6134 Node->getValueType(0),
6135 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6136 AArch64::FAMAX_4Z4Z_D}))
6137 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6139 case Intrinsic::aarch64_sme_famin_x2:
6140 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6141 Node->getValueType(0),
6142 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6143 AArch64::FAMIN_2Z2Z_D}))
6144 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6146 case Intrinsic::aarch64_sme_famin_x4:
6147 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6148 Node->getValueType(0),
6149 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6150 AArch64::FAMIN_4Z4Z_D}))
6151 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6153 case Intrinsic::aarch64_sve_smin_x2:
6154 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6155 Node->getValueType(0),
6156 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6157 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6158 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6160 case Intrinsic::aarch64_sve_umin_x2:
6161 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6162 Node->getValueType(0),
6163 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6164 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6165 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6167 case Intrinsic::aarch64_sve_fmin_x2:
6168 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6169 Node->getValueType(0),
6170 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6171 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6172 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6174 case Intrinsic::aarch64_sve_smin_x4:
6175 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6176 Node->getValueType(0),
6177 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6178 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6179 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6181 case Intrinsic::aarch64_sve_umin_x4:
6182 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6183 Node->getValueType(0),
6184 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6185 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6186 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6188 case Intrinsic::aarch64_sve_fmin_x4:
6189 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6190 Node->getValueType(0),
6191 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6192 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6193 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6195 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6196 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6197 Node->getValueType(0),
6198 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6199 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6200 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6202 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6203 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6204 Node->getValueType(0),
6205 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6206 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6207 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6209 case Intrinsic::aarch64_sve_fminnm_single_x2:
6210 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6211 Node->getValueType(0),
6212 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6213 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6214 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6216 case Intrinsic::aarch64_sve_fminnm_single_x4:
6217 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6218 Node->getValueType(0),
6219 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6220 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6221 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6223 case Intrinsic::aarch64_sve_fmaxnm_x2:
6224 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6225 Node->getValueType(0),
6226 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6227 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6228 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6230 case Intrinsic::aarch64_sve_fmaxnm_x4:
6231 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6232 Node->getValueType(0),
6233 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6234 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6235 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6237 case Intrinsic::aarch64_sve_fminnm_x2:
6238 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6239 Node->getValueType(0),
6240 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6241 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6242 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6244 case Intrinsic::aarch64_sve_fminnm_x4:
6245 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6246 Node->getValueType(0),
6247 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6248 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6249 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6251 case Intrinsic::aarch64_sve_fcvtzs_x2:
6252 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6254 case Intrinsic::aarch64_sve_scvtf_x2:
6255 SelectCVTIntrinsic(
Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6257 case Intrinsic::aarch64_sve_fcvtzu_x2:
6258 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6260 case Intrinsic::aarch64_sve_ucvtf_x2:
6261 SelectCVTIntrinsic(
Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6263 case Intrinsic::aarch64_sve_fcvtzs_x4:
6264 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6266 case Intrinsic::aarch64_sve_scvtf_x4:
6267 SelectCVTIntrinsic(
Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6269 case Intrinsic::aarch64_sve_fcvtzu_x4:
6270 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6272 case Intrinsic::aarch64_sve_ucvtf_x4:
6273 SelectCVTIntrinsic(
Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6275 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6276 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6278 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6279 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6281 case Intrinsic::aarch64_sve_sclamp_single_x2:
6282 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6283 Node->getValueType(0),
6284 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6285 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6286 SelectClamp(
Node, 2,
Op);
6288 case Intrinsic::aarch64_sve_uclamp_single_x2:
6289 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6290 Node->getValueType(0),
6291 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6292 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6293 SelectClamp(
Node, 2,
Op);
6295 case Intrinsic::aarch64_sve_fclamp_single_x2:
6296 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6297 Node->getValueType(0),
6298 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6299 AArch64::FCLAMP_VG2_2Z2Z_D}))
6300 SelectClamp(
Node, 2,
Op);
6302 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6303 SelectClamp(
Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6305 case Intrinsic::aarch64_sve_sclamp_single_x4:
6306 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6307 Node->getValueType(0),
6308 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6309 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6310 SelectClamp(
Node, 4,
Op);
6312 case Intrinsic::aarch64_sve_uclamp_single_x4:
6313 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6314 Node->getValueType(0),
6315 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6316 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6317 SelectClamp(
Node, 4,
Op);
6319 case Intrinsic::aarch64_sve_fclamp_single_x4:
6320 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6321 Node->getValueType(0),
6322 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6323 AArch64::FCLAMP_VG4_4Z4Z_D}))
6324 SelectClamp(
Node, 4,
Op);
6326 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6327 SelectClamp(
Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6329 case Intrinsic::aarch64_sve_add_single_x2:
6330 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6331 Node->getValueType(0),
6332 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6333 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6334 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6336 case Intrinsic::aarch64_sve_add_single_x4:
6337 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6338 Node->getValueType(0),
6339 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6340 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6341 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6343 case Intrinsic::aarch64_sve_zip_x2:
6344 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6345 Node->getValueType(0),
6346 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6347 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6348 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6350 case Intrinsic::aarch64_sve_zipq_x2:
6351 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6352 AArch64::ZIP_VG2_2ZZZ_Q);
6354 case Intrinsic::aarch64_sve_zip_x4:
6355 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6356 Node->getValueType(0),
6357 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6358 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6359 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6361 case Intrinsic::aarch64_sve_zipq_x4:
6362 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6363 AArch64::ZIP_VG4_4Z4Z_Q);
6365 case Intrinsic::aarch64_sve_uzp_x2:
6366 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6367 Node->getValueType(0),
6368 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6369 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6370 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6372 case Intrinsic::aarch64_sve_uzpq_x2:
6373 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6374 AArch64::UZP_VG2_2ZZZ_Q);
6376 case Intrinsic::aarch64_sve_uzp_x4:
6377 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6378 Node->getValueType(0),
6379 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6380 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6381 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6383 case Intrinsic::aarch64_sve_uzpq_x4:
6384 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6385 AArch64::UZP_VG4_4Z4Z_Q);
6387 case Intrinsic::aarch64_sve_sel_x2:
6388 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6389 Node->getValueType(0),
6390 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6391 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6392 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op,
true);
6394 case Intrinsic::aarch64_sve_sel_x4:
6395 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6396 Node->getValueType(0),
6397 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6398 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6399 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op,
true);
6401 case Intrinsic::aarch64_sve_frinta_x2:
6402 SelectFrintFromVT(
Node, 2, AArch64::FRINTA_2Z2Z_S);
6404 case Intrinsic::aarch64_sve_frinta_x4:
6405 SelectFrintFromVT(
Node, 4, AArch64::FRINTA_4Z4Z_S);
6407 case Intrinsic::aarch64_sve_frintm_x2:
6408 SelectFrintFromVT(
Node, 2, AArch64::FRINTM_2Z2Z_S);
6410 case Intrinsic::aarch64_sve_frintm_x4:
6411 SelectFrintFromVT(
Node, 4, AArch64::FRINTM_4Z4Z_S);
6413 case Intrinsic::aarch64_sve_frintn_x2:
6414 SelectFrintFromVT(
Node, 2, AArch64::FRINTN_2Z2Z_S);
6416 case Intrinsic::aarch64_sve_frintn_x4:
6417 SelectFrintFromVT(
Node, 4, AArch64::FRINTN_4Z4Z_S);
6419 case Intrinsic::aarch64_sve_frintp_x2:
6420 SelectFrintFromVT(
Node, 2, AArch64::FRINTP_2Z2Z_S);
6422 case Intrinsic::aarch64_sve_frintp_x4:
6423 SelectFrintFromVT(
Node, 4, AArch64::FRINTP_4Z4Z_S);
6425 case Intrinsic::aarch64_sve_sunpk_x2:
6426 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6427 Node->getValueType(0),
6428 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6429 AArch64::SUNPK_VG2_2ZZ_D}))
6430 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6432 case Intrinsic::aarch64_sve_uunpk_x2:
6433 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6434 Node->getValueType(0),
6435 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6436 AArch64::UUNPK_VG2_2ZZ_D}))
6437 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6439 case Intrinsic::aarch64_sve_sunpk_x4:
6440 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6441 Node->getValueType(0),
6442 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6443 AArch64::SUNPK_VG4_4Z2Z_D}))
6444 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6446 case Intrinsic::aarch64_sve_uunpk_x4:
6447 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6448 Node->getValueType(0),
6449 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6450 AArch64::UUNPK_VG4_4Z2Z_D}))
6451 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6453 case Intrinsic::aarch64_sve_pext_x2: {
6454 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6455 Node->getValueType(0),
6456 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6457 AArch64::PEXT_2PCI_D}))
6458 SelectPExtPair(
Node,
Op);
6465 unsigned IntNo =
Node->getConstantOperandVal(1);
6466 if (
Node->getNumOperands() >= 3)
6467 VT =
Node->getOperand(2)->getValueType(0);
6471 case Intrinsic::aarch64_neon_st1x2: {
6472 if (VT == MVT::v8i8) {
6473 SelectStore(
Node, 2, AArch64::ST1Twov8b);
6475 }
else if (VT == MVT::v16i8) {
6476 SelectStore(
Node, 2, AArch64::ST1Twov16b);
6478 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6479 VT == MVT::v4bf16) {
6480 SelectStore(
Node, 2, AArch64::ST1Twov4h);
6482 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6483 VT == MVT::v8bf16) {
6484 SelectStore(
Node, 2, AArch64::ST1Twov8h);
6486 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6487 SelectStore(
Node, 2, AArch64::ST1Twov2s);
6489 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6490 SelectStore(
Node, 2, AArch64::ST1Twov4s);
6492 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6493 SelectStore(
Node, 2, AArch64::ST1Twov2d);
6495 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6496 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6501 case Intrinsic::aarch64_neon_st1x3: {
6502 if (VT == MVT::v8i8) {
6503 SelectStore(
Node, 3, AArch64::ST1Threev8b);
6505 }
else if (VT == MVT::v16i8) {
6506 SelectStore(
Node, 3, AArch64::ST1Threev16b);
6508 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6509 VT == MVT::v4bf16) {
6510 SelectStore(
Node, 3, AArch64::ST1Threev4h);
6512 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6513 VT == MVT::v8bf16) {
6514 SelectStore(
Node, 3, AArch64::ST1Threev8h);
6516 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6517 SelectStore(
Node, 3, AArch64::ST1Threev2s);
6519 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6520 SelectStore(
Node, 3, AArch64::ST1Threev4s);
6522 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6523 SelectStore(
Node, 3, AArch64::ST1Threev2d);
6525 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6526 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6531 case Intrinsic::aarch64_neon_st1x4: {
6532 if (VT == MVT::v8i8) {
6533 SelectStore(
Node, 4, AArch64::ST1Fourv8b);
6535 }
else if (VT == MVT::v16i8) {
6536 SelectStore(
Node, 4, AArch64::ST1Fourv16b);
6538 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6539 VT == MVT::v4bf16) {
6540 SelectStore(
Node, 4, AArch64::ST1Fourv4h);
6542 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6543 VT == MVT::v8bf16) {
6544 SelectStore(
Node, 4, AArch64::ST1Fourv8h);
6546 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6547 SelectStore(
Node, 4, AArch64::ST1Fourv2s);
6549 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6550 SelectStore(
Node, 4, AArch64::ST1Fourv4s);
6552 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6553 SelectStore(
Node, 4, AArch64::ST1Fourv2d);
6555 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6556 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6561 case Intrinsic::aarch64_neon_st2: {
6562 if (VT == MVT::v8i8) {
6563 SelectStore(
Node, 2, AArch64::ST2Twov8b);
6565 }
else if (VT == MVT::v16i8) {
6566 SelectStore(
Node, 2, AArch64::ST2Twov16b);
6568 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6569 VT == MVT::v4bf16) {
6570 SelectStore(
Node, 2, AArch64::ST2Twov4h);
6572 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6573 VT == MVT::v8bf16) {
6574 SelectStore(
Node, 2, AArch64::ST2Twov8h);
6576 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6577 SelectStore(
Node, 2, AArch64::ST2Twov2s);
6579 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6580 SelectStore(
Node, 2, AArch64::ST2Twov4s);
6582 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6583 SelectStore(
Node, 2, AArch64::ST2Twov2d);
6585 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6586 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6591 case Intrinsic::aarch64_neon_st3: {
6592 if (VT == MVT::v8i8) {
6593 SelectStore(
Node, 3, AArch64::ST3Threev8b);
6595 }
else if (VT == MVT::v16i8) {
6596 SelectStore(
Node, 3, AArch64::ST3Threev16b);
6598 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6599 VT == MVT::v4bf16) {
6600 SelectStore(
Node, 3, AArch64::ST3Threev4h);
6602 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6603 VT == MVT::v8bf16) {
6604 SelectStore(
Node, 3, AArch64::ST3Threev8h);
6606 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6607 SelectStore(
Node, 3, AArch64::ST3Threev2s);
6609 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6610 SelectStore(
Node, 3, AArch64::ST3Threev4s);
6612 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6613 SelectStore(
Node, 3, AArch64::ST3Threev2d);
6615 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6616 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6621 case Intrinsic::aarch64_neon_st4: {
6622 if (VT == MVT::v8i8) {
6623 SelectStore(
Node, 4, AArch64::ST4Fourv8b);
6625 }
else if (VT == MVT::v16i8) {
6626 SelectStore(
Node, 4, AArch64::ST4Fourv16b);
6628 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6629 VT == MVT::v4bf16) {
6630 SelectStore(
Node, 4, AArch64::ST4Fourv4h);
6632 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6633 VT == MVT::v8bf16) {
6634 SelectStore(
Node, 4, AArch64::ST4Fourv8h);
6636 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6637 SelectStore(
Node, 4, AArch64::ST4Fourv2s);
6639 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6640 SelectStore(
Node, 4, AArch64::ST4Fourv4s);
6642 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6643 SelectStore(
Node, 4, AArch64::ST4Fourv2d);
6645 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6646 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6651 case Intrinsic::aarch64_neon_st2lane: {
6652 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6653 SelectStoreLane(
Node, 2, AArch64::ST2i8);
6655 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6656 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6657 SelectStoreLane(
Node, 2, AArch64::ST2i16);
6659 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6661 SelectStoreLane(
Node, 2, AArch64::ST2i32);
6663 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6665 SelectStoreLane(
Node, 2, AArch64::ST2i64);
6670 case Intrinsic::aarch64_neon_st3lane: {
6671 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6672 SelectStoreLane(
Node, 3, AArch64::ST3i8);
6674 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6675 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6676 SelectStoreLane(
Node, 3, AArch64::ST3i16);
6678 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6680 SelectStoreLane(
Node, 3, AArch64::ST3i32);
6682 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6684 SelectStoreLane(
Node, 3, AArch64::ST3i64);
6689 case Intrinsic::aarch64_neon_st4lane: {
6690 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6691 SelectStoreLane(
Node, 4, AArch64::ST4i8);
6693 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6694 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6695 SelectStoreLane(
Node, 4, AArch64::ST4i16);
6697 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6699 SelectStoreLane(
Node, 4, AArch64::ST4i32);
6701 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6703 SelectStoreLane(
Node, 4, AArch64::ST4i64);
6708 case Intrinsic::aarch64_sve_st2q: {
6709 SelectPredicatedStore(
Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6712 case Intrinsic::aarch64_sve_st3q: {
6713 SelectPredicatedStore(
Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6716 case Intrinsic::aarch64_sve_st4q: {
6717 SelectPredicatedStore(
Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6720 case Intrinsic::aarch64_sve_st2: {
6721 if (VT == MVT::nxv16i8) {
6722 SelectPredicatedStore(
Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6724 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6725 VT == MVT::nxv8bf16) {
6726 SelectPredicatedStore(
Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6728 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6729 SelectPredicatedStore(
Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6731 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6732 SelectPredicatedStore(
Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6737 case Intrinsic::aarch64_sve_st3: {
6738 if (VT == MVT::nxv16i8) {
6739 SelectPredicatedStore(
Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6741 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6742 VT == MVT::nxv8bf16) {
6743 SelectPredicatedStore(
Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6745 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6746 SelectPredicatedStore(
Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6748 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6749 SelectPredicatedStore(
Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6754 case Intrinsic::aarch64_sve_st4: {
6755 if (VT == MVT::nxv16i8) {
6756 SelectPredicatedStore(
Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6758 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6759 VT == MVT::nxv8bf16) {
6760 SelectPredicatedStore(
Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6762 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6763 SelectPredicatedStore(
Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6765 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6766 SelectPredicatedStore(
Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6774 case AArch64ISD::LD2post: {
6775 if (VT == MVT::v8i8) {
6776 SelectPostLoad(
Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6778 }
else if (VT == MVT::v16i8) {
6779 SelectPostLoad(
Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6781 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6782 SelectPostLoad(
Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6784 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6785 SelectPostLoad(
Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6787 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6788 SelectPostLoad(
Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6790 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6791 SelectPostLoad(
Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6793 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6794 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6796 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6797 SelectPostLoad(
Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6802 case AArch64ISD::LD3post: {
6803 if (VT == MVT::v8i8) {
6804 SelectPostLoad(
Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6806 }
else if (VT == MVT::v16i8) {
6807 SelectPostLoad(
Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6809 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6810 SelectPostLoad(
Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6812 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6813 SelectPostLoad(
Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6815 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6816 SelectPostLoad(
Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6818 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6819 SelectPostLoad(
Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6821 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6822 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6824 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6825 SelectPostLoad(
Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6830 case AArch64ISD::LD4post: {
6831 if (VT == MVT::v8i8) {
6832 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6834 }
else if (VT == MVT::v16i8) {
6835 SelectPostLoad(
Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6837 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6838 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6840 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6841 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6843 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6844 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6846 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6847 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6849 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6850 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6852 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6853 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6858 case AArch64ISD::LD1x2post: {
6859 if (VT == MVT::v8i8) {
6860 SelectPostLoad(
Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6862 }
else if (VT == MVT::v16i8) {
6863 SelectPostLoad(
Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6865 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6866 SelectPostLoad(
Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6868 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6869 SelectPostLoad(
Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6871 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6872 SelectPostLoad(
Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6874 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6875 SelectPostLoad(
Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6877 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6878 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6880 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6881 SelectPostLoad(
Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6886 case AArch64ISD::LD1x3post: {
6887 if (VT == MVT::v8i8) {
6888 SelectPostLoad(
Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6890 }
else if (VT == MVT::v16i8) {
6891 SelectPostLoad(
Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6893 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6894 SelectPostLoad(
Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6896 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6897 SelectPostLoad(
Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6899 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6900 SelectPostLoad(
Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6902 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6903 SelectPostLoad(
Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6905 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6906 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6908 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6909 SelectPostLoad(
Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6914 case AArch64ISD::LD1x4post: {
6915 if (VT == MVT::v8i8) {
6916 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6918 }
else if (VT == MVT::v16i8) {
6919 SelectPostLoad(
Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6921 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6922 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6924 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6925 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6927 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6928 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6930 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6931 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6933 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6934 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6936 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6937 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6942 case AArch64ISD::LD1DUPpost: {
6943 if (VT == MVT::v8i8) {
6944 SelectPostLoad(
Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6946 }
else if (VT == MVT::v16i8) {
6947 SelectPostLoad(
Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6949 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6950 SelectPostLoad(
Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6952 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6953 SelectPostLoad(
Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6955 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6956 SelectPostLoad(
Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6958 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6959 SelectPostLoad(
Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6961 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6962 SelectPostLoad(
Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6964 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6965 SelectPostLoad(
Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6970 case AArch64ISD::LD2DUPpost: {
6971 if (VT == MVT::v8i8) {
6972 SelectPostLoad(
Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6974 }
else if (VT == MVT::v16i8) {
6975 SelectPostLoad(
Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6977 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6978 SelectPostLoad(
Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6980 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6981 SelectPostLoad(
Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6983 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6984 SelectPostLoad(
Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6986 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6987 SelectPostLoad(
Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6989 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6990 SelectPostLoad(
Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6992 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6993 SelectPostLoad(
Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
6998 case AArch64ISD::LD3DUPpost: {
6999 if (VT == MVT::v8i8) {
7000 SelectPostLoad(
Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7002 }
else if (VT == MVT::v16i8) {
7003 SelectPostLoad(
Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7005 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7006 SelectPostLoad(
Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7008 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7009 SelectPostLoad(
Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7011 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7012 SelectPostLoad(
Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7014 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7015 SelectPostLoad(
Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7017 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7018 SelectPostLoad(
Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7020 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7021 SelectPostLoad(
Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7026 case AArch64ISD::LD4DUPpost: {
7027 if (VT == MVT::v8i8) {
7028 SelectPostLoad(
Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7030 }
else if (VT == MVT::v16i8) {
7031 SelectPostLoad(
Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7033 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7034 SelectPostLoad(
Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7036 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7037 SelectPostLoad(
Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7039 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7040 SelectPostLoad(
Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7042 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7043 SelectPostLoad(
Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7045 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7046 SelectPostLoad(
Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7048 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7049 SelectPostLoad(
Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7054 case AArch64ISD::LD1LANEpost: {
7055 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7056 SelectPostLoadLane(
Node, 1, AArch64::LD1i8_POST);
7058 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7059 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7060 SelectPostLoadLane(
Node, 1, AArch64::LD1i16_POST);
7062 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7064 SelectPostLoadLane(
Node, 1, AArch64::LD1i32_POST);
7066 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7068 SelectPostLoadLane(
Node, 1, AArch64::LD1i64_POST);
7073 case AArch64ISD::LD2LANEpost: {
7074 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7075 SelectPostLoadLane(
Node, 2, AArch64::LD2i8_POST);
7077 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7078 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7079 SelectPostLoadLane(
Node, 2, AArch64::LD2i16_POST);
7081 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7083 SelectPostLoadLane(
Node, 2, AArch64::LD2i32_POST);
7085 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7087 SelectPostLoadLane(
Node, 2, AArch64::LD2i64_POST);
7092 case AArch64ISD::LD3LANEpost: {
7093 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7094 SelectPostLoadLane(
Node, 3, AArch64::LD3i8_POST);
7096 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7097 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7098 SelectPostLoadLane(
Node, 3, AArch64::LD3i16_POST);
7100 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7102 SelectPostLoadLane(
Node, 3, AArch64::LD3i32_POST);
7104 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7106 SelectPostLoadLane(
Node, 3, AArch64::LD3i64_POST);
7111 case AArch64ISD::LD4LANEpost: {
7112 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7113 SelectPostLoadLane(
Node, 4, AArch64::LD4i8_POST);
7115 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7116 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7117 SelectPostLoadLane(
Node, 4, AArch64::LD4i16_POST);
7119 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7121 SelectPostLoadLane(
Node, 4, AArch64::LD4i32_POST);
7123 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7125 SelectPostLoadLane(
Node, 4, AArch64::LD4i64_POST);
7130 case AArch64ISD::ST2post: {
7131 VT =
Node->getOperand(1).getValueType();
7132 if (VT == MVT::v8i8) {
7133 SelectPostStore(
Node, 2, AArch64::ST2Twov8b_POST);
7135 }
else if (VT == MVT::v16i8) {
7136 SelectPostStore(
Node, 2, AArch64::ST2Twov16b_POST);
7138 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7139 SelectPostStore(
Node, 2, AArch64::ST2Twov4h_POST);
7141 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7142 SelectPostStore(
Node, 2, AArch64::ST2Twov8h_POST);
7144 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7145 SelectPostStore(
Node, 2, AArch64::ST2Twov2s_POST);
7147 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7148 SelectPostStore(
Node, 2, AArch64::ST2Twov4s_POST);
7150 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7151 SelectPostStore(
Node, 2, AArch64::ST2Twov2d_POST);
7153 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7154 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7159 case AArch64ISD::ST3post: {
7160 VT =
Node->getOperand(1).getValueType();
7161 if (VT == MVT::v8i8) {
7162 SelectPostStore(
Node, 3, AArch64::ST3Threev8b_POST);
7164 }
else if (VT == MVT::v16i8) {
7165 SelectPostStore(
Node, 3, AArch64::ST3Threev16b_POST);
7167 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7168 SelectPostStore(
Node, 3, AArch64::ST3Threev4h_POST);
7170 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7171 SelectPostStore(
Node, 3, AArch64::ST3Threev8h_POST);
7173 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7174 SelectPostStore(
Node, 3, AArch64::ST3Threev2s_POST);
7176 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7177 SelectPostStore(
Node, 3, AArch64::ST3Threev4s_POST);
7179 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7180 SelectPostStore(
Node, 3, AArch64::ST3Threev2d_POST);
7182 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7183 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7188 case AArch64ISD::ST4post: {
7189 VT =
Node->getOperand(1).getValueType();
7190 if (VT == MVT::v8i8) {
7191 SelectPostStore(
Node, 4, AArch64::ST4Fourv8b_POST);
7193 }
else if (VT == MVT::v16i8) {
7194 SelectPostStore(
Node, 4, AArch64::ST4Fourv16b_POST);
7196 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7197 SelectPostStore(
Node, 4, AArch64::ST4Fourv4h_POST);
7199 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7200 SelectPostStore(
Node, 4, AArch64::ST4Fourv8h_POST);
7202 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7203 SelectPostStore(
Node, 4, AArch64::ST4Fourv2s_POST);
7205 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7206 SelectPostStore(
Node, 4, AArch64::ST4Fourv4s_POST);
7208 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7209 SelectPostStore(
Node, 4, AArch64::ST4Fourv2d_POST);
7211 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7212 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7217 case AArch64ISD::ST1x2post: {
7218 VT =
Node->getOperand(1).getValueType();
7219 if (VT == MVT::v8i8) {
7220 SelectPostStore(
Node, 2, AArch64::ST1Twov8b_POST);
7222 }
else if (VT == MVT::v16i8) {
7223 SelectPostStore(
Node, 2, AArch64::ST1Twov16b_POST);
7225 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7226 SelectPostStore(
Node, 2, AArch64::ST1Twov4h_POST);
7228 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7229 SelectPostStore(
Node, 2, AArch64::ST1Twov8h_POST);
7231 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7232 SelectPostStore(
Node, 2, AArch64::ST1Twov2s_POST);
7234 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7235 SelectPostStore(
Node, 2, AArch64::ST1Twov4s_POST);
7237 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7238 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7240 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7241 SelectPostStore(
Node, 2, AArch64::ST1Twov2d_POST);
7246 case AArch64ISD::ST1x3post: {
7247 VT =
Node->getOperand(1).getValueType();
7248 if (VT == MVT::v8i8) {
7249 SelectPostStore(
Node, 3, AArch64::ST1Threev8b_POST);
7251 }
else if (VT == MVT::v16i8) {
7252 SelectPostStore(
Node, 3, AArch64::ST1Threev16b_POST);
7254 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7255 SelectPostStore(
Node, 3, AArch64::ST1Threev4h_POST);
7257 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7258 SelectPostStore(
Node, 3, AArch64::ST1Threev8h_POST);
7260 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7261 SelectPostStore(
Node, 3, AArch64::ST1Threev2s_POST);
7263 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7264 SelectPostStore(
Node, 3, AArch64::ST1Threev4s_POST);
7266 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7267 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7269 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7270 SelectPostStore(
Node, 3, AArch64::ST1Threev2d_POST);
7275 case AArch64ISD::ST1x4post: {
7276 VT =
Node->getOperand(1).getValueType();
7277 if (VT == MVT::v8i8) {
7278 SelectPostStore(
Node, 4, AArch64::ST1Fourv8b_POST);
7280 }
else if (VT == MVT::v16i8) {
7281 SelectPostStore(
Node, 4, AArch64::ST1Fourv16b_POST);
7283 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7284 SelectPostStore(
Node, 4, AArch64::ST1Fourv4h_POST);
7286 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7287 SelectPostStore(
Node, 4, AArch64::ST1Fourv8h_POST);
7289 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7290 SelectPostStore(
Node, 4, AArch64::ST1Fourv2s_POST);
7292 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7293 SelectPostStore(
Node, 4, AArch64::ST1Fourv4s_POST);
7295 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7296 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7298 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7299 SelectPostStore(
Node, 4, AArch64::ST1Fourv2d_POST);
7304 case AArch64ISD::ST2LANEpost: {
7305 VT =
Node->getOperand(1).getValueType();
7306 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7307 SelectPostStoreLane(
Node, 2, AArch64::ST2i8_POST);
7309 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7310 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7311 SelectPostStoreLane(
Node, 2, AArch64::ST2i16_POST);
7313 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7315 SelectPostStoreLane(
Node, 2, AArch64::ST2i32_POST);
7317 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7319 SelectPostStoreLane(
Node, 2, AArch64::ST2i64_POST);
7324 case AArch64ISD::ST3LANEpost: {
7325 VT =
Node->getOperand(1).getValueType();
7326 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7327 SelectPostStoreLane(
Node, 3, AArch64::ST3i8_POST);
7329 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7330 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7331 SelectPostStoreLane(
Node, 3, AArch64::ST3i16_POST);
7333 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7335 SelectPostStoreLane(
Node, 3, AArch64::ST3i32_POST);
7337 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7339 SelectPostStoreLane(
Node, 3, AArch64::ST3i64_POST);
7344 case AArch64ISD::ST4LANEpost: {
7345 VT =
Node->getOperand(1).getValueType();
7346 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7347 SelectPostStoreLane(
Node, 4, AArch64::ST4i8_POST);
7349 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7350 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7351 SelectPostStoreLane(
Node, 4, AArch64::ST4i16_POST);
7353 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7355 SelectPostStoreLane(
Node, 4, AArch64::ST4i32_POST);
7357 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7359 SelectPostStoreLane(
Node, 4, AArch64::ST4i64_POST);
7374 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7386 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7390 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7391 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7405 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(Root))
7406 return MemIntr->getMemoryVT();
7408 if (isa<MemSDNode>(Root)) {
7409 EVT MemVT = cast<MemSDNode>(Root)->getMemoryVT();
7412 if (
auto *Load = dyn_cast<LoadSDNode>(Root))
7413 DataVT = Load->getValueType(0);
7414 else if (
auto *Load = dyn_cast<MaskedLoadSDNode>(Root))
7415 DataVT = Load->getValueType(0);
7416 else if (
auto *Store = dyn_cast<StoreSDNode>(Root))
7417 DataVT = Store->getValue().getValueType();
7418 else if (
auto *Store = dyn_cast<MaskedStoreSDNode>(Root))
7419 DataVT = Store->getValue().getValueType();
7426 const unsigned Opcode = Root->
getOpcode();
7430 case AArch64ISD::LD1_MERGE_ZERO:
7431 case AArch64ISD::LD1S_MERGE_ZERO:
7432 case AArch64ISD::LDNF1_MERGE_ZERO:
7433 case AArch64ISD::LDNF1S_MERGE_ZERO:
7434 return cast<VTSDNode>(Root->
getOperand(3))->getVT();
7435 case AArch64ISD::ST1_PRED:
7436 return cast<VTSDNode>(Root->
getOperand(4))->getVT();
7447 case Intrinsic::aarch64_sme_ldr:
7448 case Intrinsic::aarch64_sme_str:
7449 return MVT::nxv16i8;
7450 case Intrinsic::aarch64_sve_prf:
7455 case Intrinsic::aarch64_sve_ld2_sret:
7456 case Intrinsic::aarch64_sve_ld2q_sret:
7459 case Intrinsic::aarch64_sve_st2q:
7462 case Intrinsic::aarch64_sve_ld3_sret:
7463 case Intrinsic::aarch64_sve_ld3q_sret:
7466 case Intrinsic::aarch64_sve_st3q:
7469 case Intrinsic::aarch64_sve_ld4_sret:
7470 case Intrinsic::aarch64_sve_ld4q_sret:
7473 case Intrinsic::aarch64_sve_st4q:
7476 case Intrinsic::aarch64_sve_ld1udq:
7477 case Intrinsic::aarch64_sve_st1dq:
7478 return EVT(MVT::nxv1i64);
7479 case Intrinsic::aarch64_sve_ld1uwq:
7480 case Intrinsic::aarch64_sve_st1wq:
7481 return EVT(MVT::nxv1i32);
7488template <
int64_t Min,
int64_t Max>
7489bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(
SDNode *Root,
SDValue N,
7497 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
7502 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7516 int64_t MulImm = std::numeric_limits<int64_t>::max();
7518 MulImm = cast<ConstantSDNode>(VScale.
getOperand(0))->getSExtValue();
7519 }
else if (
auto C = dyn_cast<ConstantSDNode>(VScale)) {
7520 int64_t ByteOffset =
C->getSExtValue();
7521 const auto KnownVScale =
7524 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7527 MulImm = ByteOffset / KnownVScale;
7534 if ((MulImm % MemWidthBytes) != 0)
7537 int64_t
Offset = MulImm / MemWidthBytes;
7538 if (Offset < Min || Offset > Max)
7541 Base =
N.getOperand(0);
7543 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
7550 OffImm = CurDAG->getTargetConstant(
Offset,
SDLoc(
N), MVT::i64);
7556bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7574 if (
auto C = dyn_cast<ConstantSDNode>(RHS)) {
7575 int64_t ImmOff =
C->getSExtValue();
7576 unsigned Size = 1 << Scale;
7585 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7587 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
7597 if (
auto *
C = dyn_cast<ConstantSDNode>(ShiftRHS))
7598 if (
C->getZExtValue() == Scale) {
7607bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7614bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7615 EVT VT =
N.getValueType();
7619bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7623 if (
auto *
C = dyn_cast<ConstantSDNode>(CN)) {
7624 int64_t ImmOff =
C->getSExtValue();
7625 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7626 return CurDAG->getTargetConstant(ImmOff / Scale,
SDLoc(
N), MVT::i64);
7631 if (
SDValue C = MatchConstantOffset(
N)) {
7632 Base = CurDAG->getConstant(0,
SDLoc(
N), MVT::i32);
7638 if (CurDAG->isBaseWithConstantOffset(
N)) {
7639 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7640 Base =
N.getOperand(0);
7648 Offset = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7652bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(
SDNode *
P,
SDValue N,
7656 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
7672 uint64_t LowerBound = 0, UpperBound = 64;
7690 if (CN->getAPIntValue().uge(LowerBound) &&
7691 CN->getAPIntValue().ult(UpperBound)) {
7693 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.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
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.