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);
186 EVT VT =
Op.getValueType();
187 unsigned ShtAmt =
N->getConstantOperandVal(1);
194 Op.getOperand(1).getConstantOperandVal(0)
195 <<
Op.getOperand(1).getConstantOperandVal(1));
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()) {
217 auto Opnd0 =
N->getOperand(0);
231 bool SelectAny(
SDValue) {
return true; }
234 switch(
N->getOpcode()) {
237 auto Opnd0 =
N->getOperand(0);
249 template<MVT::SimpleValueType VT>
251 return SelectSVEAddSubImm(
N, VT, Imm, Shift);
254 template <MVT::SimpleValueType VT,
bool Negate>
256 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
259 template <MVT::SimpleValueType VT>
261 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
264 template <MVT::SimpleValueType VT,
bool Invert = false>
266 return SelectSVELogicalImm(
N, VT, Imm, Invert);
269 template <MVT::SimpleValueType VT>
271 return SelectSVEArithImm(
N, VT, Imm);
274 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
276 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
283 EVT EltVT =
N->getValueType(0).getVectorElementType();
284 return SelectSVEShiftImm(
N->getOperand(0), 1,
290 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
292 if (!isa<ConstantSDNode>(
N))
295 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
297 MulImm = 1LL << MulImm;
299 if ((MulImm % std::abs(Scale)) != 0)
303 if ((MulImm >= Min) && (MulImm <= Max)) {
304 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
311 template <
signed Max,
signed Scale>
313 if (!isa<ConstantSDNode>(
N))
316 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
318 if (MulImm >= 0 && MulImm <= Max) {
320 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
327 template <
unsigned BaseReg,
unsigned Max>
329 if (
auto *CI = dyn_cast<ConstantSDNode>(
N)) {
335 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
358 const unsigned SubRegs[]);
360 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
362 bool tryIndexedLoad(
SDNode *
N);
364 void SelectPtrauthAuth(
SDNode *
N);
365 void SelectPtrauthResign(
SDNode *
N);
367 bool trySelectStackSlotTagP(
SDNode *
N);
370 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
372 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
374 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
375 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
376 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
377 unsigned Opc_rr,
unsigned Opc_ri,
378 bool IsIntr =
false);
379 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
380 unsigned Scale,
unsigned Opc_ri,
382 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
383 bool IsZmMulti,
unsigned Opcode,
384 bool HasPred =
false);
385 void SelectPExtPair(
SDNode *
N,
unsigned Opc);
386 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
387 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
388 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
389 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
390 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
391 bool IsTupleInput,
unsigned Opc);
392 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 template <
unsigned MaxIdx,
unsigned Scale>
395 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
397 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
398 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
399 unsigned BaseReg = 0);
402 template <
int64_t Min,
int64_t Max>
406 template <
unsigned Scale>
408 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
411 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
414 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
416 template <
unsigned MaxIdx,
unsigned Scale>
421 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
422 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
423 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
424 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
425 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
426 unsigned Opc_rr,
unsigned Opc_ri);
427 std::tuple<unsigned, SDValue, SDValue>
428 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
432 bool tryBitfieldExtractOp(
SDNode *
N);
433 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
434 bool tryBitfieldInsertOp(
SDNode *
N);
435 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
436 bool tryShiftAmountMod(
SDNode *
N);
438 bool tryReadRegister(
SDNode *
N);
439 bool tryWriteRegister(
SDNode *
N);
441 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
442 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
447#include "AArch64GenDAGISel.inc"
455 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
457 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
470 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
471 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
472 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
475 template<
unsigned RegW
idth>
477 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
480 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
482 template<
unsigned RegW
idth>
484 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
490 bool SelectCMP_SWAP(
SDNode *
N);
500 bool AllowSaturation,
SDValue &Imm);
508 bool SelectAllActivePredicate(
SDValue N);
518 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
522char AArch64DAGToDAGISelLegacy::ID = 0;
530 Imm =
C->getZExtValue();
547 return N->getOpcode() == Opc &&
558 return Imm == ImmExpected;
562bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
564 std::vector<SDValue> &OutOps) {
565 switch(ConstraintID) {
568 case InlineAsm::ConstraintCode::m:
569 case InlineAsm::ConstraintCode::o:
570 case InlineAsm::ConstraintCode::Q:
576 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
578 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
579 dl,
Op.getValueType(),
581 OutOps.push_back(NewOp);
597 if (!isa<ConstantSDNode>(
N.getNode()))
600 uint64_t Immed =
N.getNode()->getAsZExtVal();
603 if (Immed >> 12 == 0) {
605 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
613 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
614 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
627 if (!isa<ConstantSDNode>(
N.getNode()))
631 uint64_t Immed =
N.getNode()->getAsZExtVal();
639 if (
N.getValueType() == MVT::i32)
642 Immed = ~Immed + 1ULL;
643 if (Immed & 0xFFFFFFFFFF000000ULL)
646 Immed &= 0xFFFFFFULL;
647 return SelectArithImmed(CurDAG->getConstant(Immed,
SDLoc(
N), MVT::i32), Val,
654 switch (
N.getOpcode()) {
673 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1));
676 unsigned ShiftVal = CSD->getZExtValue();
685 if (!isa<MemSDNode>(*UI))
687 if (!isa<MemSDNode>(*UII))
694bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
697 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
702 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
724bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(
SDValue N,
SDValue &Reg,
726 EVT VT =
N.getValueType();
727 if (VT != MVT::i32 && VT != MVT::i64)
730 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
736 unsigned LHSOpcode =
LHS->getOpcode();
750 unsigned LowZBits, MaskLen;
754 unsigned BitWidth =
N.getValueSizeInBits();
761 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
764 NewShiftC = LowZBits - ShiftAmtC;
765 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
771 NewShiftC = LowZBits + ShiftAmtC;
784 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
786 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
790 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
792 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
793 NewShiftAmt, BitWidthMinus1),
796 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
808 SrcVT = cast<VTSDNode>(
N.getOperand(1))->getVT();
810 SrcVT =
N.getOperand(0).getValueType();
812 if (!IsLoadStore && SrcVT == MVT::i8)
814 else if (!IsLoadStore && SrcVT == MVT::i16)
816 else if (SrcVT == MVT::i32)
818 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
823 EVT SrcVT =
N.getOperand(0).getValueType();
824 if (!IsLoadStore && SrcVT == MVT::i8)
826 else if (!IsLoadStore && SrcVT == MVT::i16)
828 else if (SrcVT == MVT::i32)
830 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
858bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
861 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
866 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
867 V.getConstantOperandVal(1) <= 4 &&
880bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
882 if (SelectShiftedRegisterFromAnd(
N, Reg, Shift))
892 unsigned BitSize =
N.getValueSizeInBits();
893 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
896 Reg =
N.getOperand(0);
897 Shift = CurDAG->getTargetConstant(ShVal,
SDLoc(
N), MVT::i32);
898 return isWorthFoldingALU(
N,
true);
909 if (
N.getValueType() == MVT::i32)
917template<
signed Low,
signed High,
signed Scale>
919 if (!isa<ConstantSDNode>(
N))
922 int64_t MulImm = cast<ConstantSDNode>(
N)->getSExtValue();
923 if ((MulImm % std::abs(Scale)) == 0) {
924 int64_t RDVLImm = MulImm / Scale;
925 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
926 Imm = CurDAG->getSignedTargetConstant(RDVLImm,
SDLoc(
N), MVT::i32);
936bool AArch64DAGToDAGISel::SelectArithExtendedRegister(
SDValue N,
SDValue &Reg,
938 unsigned ShiftVal = 0;
953 Reg =
N.getOperand(0).getOperand(0);
959 Reg =
N.getOperand(0);
964 unsigned Opc =
N.getOpcode();
965 return Opc !=
ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG &&
982 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
984 return isWorthFoldingALU(
N);
989bool AArch64DAGToDAGISel::SelectArithUXTXRegister(
SDValue N,
SDValue &Reg,
991 unsigned ShiftVal = 0;
1005 Reg =
N.getOperand(0);
1006 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal),
SDLoc(
N),
1008 return isWorthFoldingALU(
N);
1017 for (
auto *
User :
N->users()) {
1044bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1045 unsigned BW,
unsigned Size,
1052 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1054 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1060 if (CurDAG->isBaseWithConstantOffset(
N)) {
1061 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1063 int64_t RHSC =
RHS->getSExtValue();
1065 int64_t
Range = 0x1LL << (BW - 1);
1067 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1068 RHSC < (
Range << Scale)) {
1069 Base =
N.getOperand(0);
1071 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1074 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1083 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1084 Base =
N.getOperand(0);
1086 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1089 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1100 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1107bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1113 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
1115 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1121 dyn_cast<GlobalAddressSDNode>(
N.getOperand(1).getNode());
1122 Base =
N.getOperand(0);
1123 OffImm =
N.getOperand(1);
1132 if (CurDAG->isBaseWithConstantOffset(
N)) {
1133 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1134 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1137 Base =
N.getOperand(0);
1139 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1142 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1150 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1158 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1167bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1170 if (!CurDAG->isBaseWithConstantOffset(
N))
1172 if (
ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
1173 int64_t RHSC =
RHS->getSExtValue();
1174 if (RHSC >= -256 && RHSC < 256) {
1175 Base =
N.getOperand(0);
1177 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
1179 Base = CurDAG->getTargetFrameIndex(
1182 OffImm = CurDAG->getTargetConstant(RHSC,
SDLoc(
N), MVT::i64);
1192 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1199bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1219 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1225 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1228 return isWorthFoldingAddr(
N,
Size);
1231bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1243 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
1251 if (!isa<MemSDNode>(*UI))
1256 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1259 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1260 SelectExtendedSHL(RHS,
Size,
true,
Offset, SignExtend)) {
1262 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1267 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1268 SelectExtendedSHL(LHS,
Size,
true,
Offset, SignExtend)) {
1270 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1275 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1279 if (IsExtendedRegisterWorthFolding &&
1286 if (isWorthFoldingAddr(LHS,
Size))
1291 if (IsExtendedRegisterWorthFolding &&
1298 if (isWorthFoldingAddr(RHS,
Size))
1310 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1313 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1315 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1316 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1320bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1335 if (!isa<MemSDNode>(*UI))
1350 if (isa<ConstantSDNode>(RHS)) {
1351 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1361 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
1364 N = CurDAG->getNode(
ISD::ADD,
DL, MVT::i64, LHS, MOVIV);
1368 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1371 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1372 SelectExtendedSHL(RHS,
Size,
false,
Offset, SignExtend)) {
1374 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1379 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1380 SelectExtendedSHL(LHS,
Size,
false,
Offset, SignExtend)) {
1382 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1389 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1390 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1396 static const unsigned RegClassIDs[] = {
1397 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1398 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1399 AArch64::dsub2, AArch64::dsub3};
1405 static const unsigned RegClassIDs[] = {
1406 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1407 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1408 AArch64::qsub2, AArch64::qsub3};
1414 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1415 AArch64::ZPR3RegClassID,
1416 AArch64::ZPR4RegClassID};
1417 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1418 AArch64::zsub2, AArch64::zsub3};
1428 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1429 AArch64::ZPR4Mul4RegClassID};
1430 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1431 AArch64::zsub2, AArch64::zsub3};
1436 const unsigned RegClassIDs[],
1437 const unsigned SubRegs[]) {
1440 if (Regs.
size() == 1)
1451 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1454 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1456 Ops.
push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1460 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped, Ops);
1464void AArch64DAGToDAGISel::SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1467 EVT VT =
N->getValueType(0);
1469 unsigned ExtOff = isExt;
1472 unsigned Vec0Off = ExtOff + 1;
1474 N->op_begin() + Vec0Off + NumVecs);
1481 Ops.
push_back(
N->getOperand(NumVecs + ExtOff + 1));
1482 ReplaceNode(
N, CurDAG->getMachineNode(Opc, dl, VT, Ops));
1485static std::tuple<SDValue, SDValue>
1505 auto *ConstDiscN = dyn_cast<ConstantSDNode>(ConstDisc);
1506 if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue()))
1511 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1513 return std::make_tuple(
1518void AArch64DAGToDAGISel::SelectPtrauthAuth(
SDNode *
N) {
1523 SDValue AUTDisc =
N->getOperand(3);
1525 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1526 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1528 SDValue AUTAddrDisc, AUTConstDisc;
1529 std::tie(AUTConstDisc, AUTAddrDisc) =
1532 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1533 AArch64::X16, Val,
SDValue());
1534 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1536 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUT,
DL, MVT::i64, Ops);
1537 ReplaceNode(
N, AUT);
1540void AArch64DAGToDAGISel::SelectPtrauthResign(
SDNode *
N) {
1545 SDValue AUTDisc =
N->getOperand(3);
1547 SDValue PACDisc =
N->getOperand(5);
1549 unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue();
1550 unsigned PACKeyC = cast<ConstantSDNode>(PACKey)->getZExtValue();
1552 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1553 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1555 SDValue AUTAddrDisc, AUTConstDisc;
1556 std::tie(AUTConstDisc, AUTAddrDisc) =
1559 SDValue PACAddrDisc, PACConstDisc;
1560 std::tie(PACConstDisc, PACAddrDisc) =
1563 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1564 AArch64::X16, Val,
SDValue());
1566 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1567 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1569 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64, Ops);
1570 ReplaceNode(
N, AUTPAC);
1573bool AArch64DAGToDAGISel::tryIndexedLoad(
SDNode *
N) {
1575 if (
LD->isUnindexed())
1577 EVT VT =
LD->getMemoryVT();
1578 EVT DstVT =
N->getValueType(0);
1585 unsigned Opcode = 0;
1588 bool InsertTo64 =
false;
1590 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1591 else if (VT == MVT::i32) {
1593 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1595 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1597 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1603 }
else if (VT == MVT::i16) {
1605 if (DstVT == MVT::i64)
1606 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1608 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1610 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1611 InsertTo64 = DstVT == MVT::i64;
1616 }
else if (VT == MVT::i8) {
1618 if (DstVT == MVT::i64)
1619 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1621 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1623 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1624 InsertTo64 = DstVT == MVT::i64;
1629 }
else if (VT == MVT::f16) {
1630 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1631 }
else if (VT == MVT::bf16) {
1632 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1633 }
else if (VT == MVT::f32) {
1634 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1636 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1638 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1646 SDValue Offset = CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1648 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1653 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {
MemOp});
1658 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1660 SDValue(CurDAG->getMachineNode(
1661 AArch64::SUBREG_TO_REG, dl, MVT::i64,
1662 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal,
1667 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1670 CurDAG->RemoveDeadNode(
N);
1674void AArch64DAGToDAGISel::SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1675 unsigned SubRegIdx) {
1677 EVT VT =
N->getValueType(0);
1683 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1685 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1687 for (
unsigned i = 0; i < NumVecs; ++i)
1689 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1695 if (
auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(
N)) {
1697 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
1700 CurDAG->RemoveDeadNode(
N);
1703void AArch64DAGToDAGISel::SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
1704 unsigned Opc,
unsigned SubRegIdx) {
1706 EVT VT =
N->getValueType(0);
1713 const EVT ResTys[] = {MVT::i64,
1714 MVT::Untyped, MVT::Other};
1716 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
1724 ReplaceUses(
SDValue(
N, 0), SuperReg);
1726 for (
unsigned i = 0; i < NumVecs; ++i)
1728 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1732 CurDAG->RemoveDeadNode(
N);
1738std::tuple<unsigned, SDValue, SDValue>
1739AArch64DAGToDAGISel::findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
1745 SDValue NewOffset = OldOffset;
1747 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1748 N, OldBase, NewBase, NewOffset);
1752 const bool IsRegReg =
1753 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1756 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1769template <SelectTypeKind Kind>
1781 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1786 if (EltVT != MVT::i1)
1790 if (EltVT == MVT::bf16)
1792 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1822void AArch64DAGToDAGISel::SelectPExtPair(
SDNode *
N,
unsigned Opc) {
1825 if (
Imm->getZExtValue() > 1)
1829 EVT VT =
N->getValueType(0);
1830 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1831 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1834 for (
unsigned I = 0;
I < 2; ++
I)
1835 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1836 AArch64::psub0 +
I,
DL, VT, SuperReg));
1838 CurDAG->RemoveDeadNode(
N);
1841void AArch64DAGToDAGISel::SelectWhilePair(
SDNode *
N,
unsigned Opc) {
1843 EVT VT =
N->getValueType(0);
1845 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2)};
1847 SDNode *WhilePair = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
1850 for (
unsigned I = 0;
I < 2; ++
I)
1851 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1852 AArch64::psub0 +
I,
DL, VT, SuperReg));
1854 CurDAG->RemoveDeadNode(
N);
1857void AArch64DAGToDAGISel::SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
1859 EVT VT =
N->getValueType(0);
1861 SDValue Ops = createZTuple(Regs);
1865 for (
unsigned i = 0; i < NumVecs; ++i)
1866 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1867 AArch64::zsub0 + i,
DL, VT, SuperReg));
1869 CurDAG->RemoveDeadNode(
N);
1872void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
1875 EVT VT =
N->getValueType(0);
1877 Ops.push_back(
N->getOperand(0));
1880 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other}, Ops);
1883 for (
unsigned i = 0; i < NumVecs; ++i)
1884 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1885 AArch64::zsub0 + i,
DL, VT, SuperReg));
1888 unsigned ChainIdx = NumVecs;
1890 CurDAG->RemoveDeadNode(
N);
1893void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(
SDNode *
N,
1898 assert(Opcode != 0 &&
"Unexpected opcode");
1901 EVT VT =
N->getValueType(0);
1902 unsigned FirstVecIdx = HasPred ? 2 : 1;
1904 auto GetMultiVecOperand = [=](
unsigned StartIdx) {
1906 return createZMulTuple(Regs);
1909 SDValue Zdn = GetMultiVecOperand(FirstVecIdx);
1913 Zm = GetMultiVecOperand(NumVecs + FirstVecIdx);
1915 Zm =
N->getOperand(NumVecs + FirstVecIdx);
1919 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
1920 N->getOperand(1), Zdn, Zm);
1922 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped, Zdn, Zm);
1924 for (
unsigned i = 0; i < NumVecs; ++i)
1925 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1926 AArch64::zsub0 + i,
DL, VT, SuperReg));
1928 CurDAG->RemoveDeadNode(
N);
1931void AArch64DAGToDAGISel::SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
1932 unsigned Scale,
unsigned Opc_ri,
1933 unsigned Opc_rr,
bool IsIntr) {
1934 assert(Scale < 5 &&
"Invalid scaling value.");
1936 EVT VT =
N->getValueType(0);
1942 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
1943 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
1944 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
1946 SDValue Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
1950 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1952 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1954 for (
unsigned i = 0; i < NumVecs; ++i)
1955 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1956 AArch64::zsub0 + i,
DL, VT, SuperReg));
1959 unsigned ChainIdx = NumVecs;
1961 CurDAG->RemoveDeadNode(
N);
1964void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(
SDNode *
N,
1969 assert(Scale < 4 &&
"Invalid scaling value.");
1971 EVT VT =
N->getValueType(0);
1979 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
1985 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1987 SDNode *
Load = CurDAG->getMachineNode(Opc,
DL, ResTys, Ops);
1989 for (
unsigned i = 0; i < NumVecs; ++i)
1990 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1991 AArch64::zsub0 + i,
DL, VT, SuperReg));
1994 unsigned ChainIdx = NumVecs;
1996 CurDAG->RemoveDeadNode(
N);
1999void AArch64DAGToDAGISel::SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
2001 if (
N->getValueType(0) != MVT::nxv4f32)
2003 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2006void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(
SDNode *
Node,
2007 unsigned NumOutVecs,
2011 if (
Imm->getZExtValue() > MaxImm)
2015 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2020 EVT VT =
Node->getValueType(0);
2023 CurDAG->getMachineNode(Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2026 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2027 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2028 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2031 unsigned ChainIdx = NumOutVecs;
2033 CurDAG->RemoveDeadNode(
Node);
2036void AArch64DAGToDAGISel::SelectMultiVectorLuti(
SDNode *
Node,
2037 unsigned NumOutVecs,
2042 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2048 EVT VT =
Node->getValueType(0);
2051 CurDAG->getMachineNode(Opc,
DL, {MVT::Untyped, MVT::Other}, Ops);
2054 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2055 ReplaceUses(
SDValue(
Node,
I), CurDAG->getTargetExtractSubreg(
2056 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2059 unsigned ChainIdx = NumOutVecs;
2061 CurDAG->RemoveDeadNode(
Node);
2064void AArch64DAGToDAGISel::SelectClamp(
SDNode *
N,
unsigned NumVecs,
2067 EVT VT =
N->getValueType(0);
2070 SDValue Zd = createZMulTuple(Regs);
2071 SDValue Zn =
N->getOperand(1 + NumVecs);
2072 SDValue Zm =
N->getOperand(2 + NumVecs);
2078 for (
unsigned i = 0; i < NumVecs; ++i)
2079 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2080 AArch64::zsub0 + i,
DL, VT, SuperReg));
2082 CurDAG->RemoveDeadNode(
N);
2112template <
unsigned MaxIdx,
unsigned Scale>
2113void AArch64DAGToDAGISel::SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
2114 unsigned BaseReg,
unsigned Op) {
2115 unsigned TileNum = 0;
2116 if (BaseReg != AArch64::ZA)
2117 TileNum =
N->getConstantOperandVal(2);
2123 if (BaseReg == AArch64::ZA)
2124 SliceBase =
N->getOperand(2);
2126 SliceBase =
N->getOperand(3);
2128 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2134 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2136 EVT VT =
N->getValueType(0);
2137 for (
unsigned I = 0;
I < NumVecs; ++
I)
2139 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2142 unsigned ChainIdx = NumVecs;
2144 CurDAG->RemoveDeadNode(
N);
2147void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
2148 unsigned Op,
unsigned MaxIdx,
2149 unsigned Scale,
unsigned BaseReg) {
2153 SDValue SliceBase =
N->getOperand(2);
2154 if (BaseReg != AArch64::ZA)
2155 SliceBase =
N->getOperand(3);
2158 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2165 if (BaseReg != AArch64::ZA )
2170 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other}, Ops);
2172 EVT VT =
N->getValueType(0);
2173 for (
unsigned I = 0;
I < NumVecs; ++
I)
2175 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2179 unsigned ChainIdx = NumVecs;
2181 CurDAG->RemoveDeadNode(
N);
2184void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(
SDNode *
N,
2185 unsigned NumOutVecs,
2189 EVT VT =
N->getValueType(0);
2190 unsigned NumInVecs =
N->getNumOperands() - 1;
2194 assert((NumInVecs == 2 || NumInVecs == 4) &&
2195 "Don't know how to handle multi-register input!");
2200 for (
unsigned I = 0;
I < NumInVecs;
I++)
2204 SDNode *Res = CurDAG->getMachineNode(Opc,
DL, MVT::Untyped, Ops);
2207 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2208 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2209 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2210 CurDAG->RemoveDeadNode(
N);
2213void AArch64DAGToDAGISel::SelectStore(
SDNode *
N,
unsigned NumVecs,
2216 EVT VT =
N->getOperand(2)->getValueType(0);
2223 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
N->getOperand(0)};
2224 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2228 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2233void AArch64DAGToDAGISel::SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
2234 unsigned Scale,
unsigned Opc_rr,
2240 SDValue RegSeq = createZTuple(Regs);
2245 std::tie(Opc,
Base,
Offset) = findAddrModeSVELoadStore(
2246 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2247 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2249 SDValue Ops[] = {RegSeq,
N->getOperand(NumVecs + 2),
2253 SDNode *St = CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), Ops);
2265 if (
auto FINode = dyn_cast<FrameIndexSDNode>(
N)) {
2266 int FI = FINode->getIndex();
2268 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2275void AArch64DAGToDAGISel::SelectPostStore(
SDNode *
N,
unsigned NumVecs,
2278 EVT VT =
N->getOperand(2)->getValueType(0);
2279 const EVT ResTys[] = {MVT::i64,
2288 N->getOperand(NumVecs + 1),
2289 N->getOperand(NumVecs + 2),
2291 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2331void AArch64DAGToDAGISel::SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
2334 EVT VT =
N->getValueType(0);
2342 WidenVector(*CurDAG));
2346 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2348 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2350 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2351 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2352 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2356 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2357 AArch64::qsub2, AArch64::qsub3 };
2358 for (
unsigned i = 0; i < NumVecs; ++i) {
2359 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2366 CurDAG->RemoveDeadNode(
N);
2369void AArch64DAGToDAGISel::SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
2372 EVT VT =
N->getValueType(0);
2380 WidenVector(*CurDAG));
2384 const EVT ResTys[] = {MVT::i64,
2387 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2390 CurDAG->getTargetConstant(LaneNo, dl,
2392 N->getOperand(NumVecs + 2),
2393 N->getOperand(NumVecs + 3),
2395 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2407 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2408 AArch64::qsub2, AArch64::qsub3 };
2409 for (
unsigned i = 0; i < NumVecs; ++i) {
2410 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2420 CurDAG->RemoveDeadNode(
N);
2423void AArch64DAGToDAGISel::SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
2426 EVT VT =
N->getOperand(2)->getValueType(0);
2434 WidenVector(*CurDAG));
2438 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2440 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2441 N->getOperand(NumVecs + 3),
N->getOperand(0)};
2442 SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
2446 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2451void AArch64DAGToDAGISel::SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
2454 EVT VT =
N->getOperand(2)->getValueType(0);
2462 WidenVector(*CurDAG));
2466 const EVT ResTys[] = {MVT::i64,
2469 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2471 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2472 N->getOperand(NumVecs + 2),
2473 N->getOperand(NumVecs + 3),
2475 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
2479 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
2486 unsigned &LSB,
unsigned &MSB,
2487 unsigned NumberOfIgnoredLowBits,
2488 bool BiggerPattern) {
2490 "N must be a AND operation to call this function");
2492 EVT VT =
N->getValueType(0);
2497 assert((VT == MVT::i32 || VT == MVT::i64) &&
2498 "Type checking must have been done before calling this function");
2512 const SDNode *Op0 =
N->getOperand(0).getNode();
2516 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits);
2519 if (AndImm & (AndImm + 1))
2522 bool ClampMSB =
false;
2542 ClampMSB = (VT == MVT::i32);
2543 }
else if (BiggerPattern) {
2549 Opd0 =
N->getOperand(0);
2555 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2558 <<
": Found large shift immediate, this should not happen\n"));
2564 (VT == MVT::i32 ? llvm::countr_one<uint32_t>(AndImm)
2565 : llvm::countr_one<uint64_t>(AndImm)) -
2572 MSB = MSB > 31 ? 31 : MSB;
2574 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2579 SDValue &Opd0,
unsigned &Immr,
2583 EVT VT =
N->getValueType(0);
2585 assert((VT == MVT::i32 || VT == MVT::i64) &&
2586 "Type checking must have been done before calling this function");
2590 Op =
Op->getOperand(0);
2591 VT =
Op->getValueType(0);
2600 unsigned Width = cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2604 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2605 Opd0 =
Op.getOperand(0);
2607 Imms = ShiftImm + Width - 1;
2635 Opd0 =
N->getOperand(0).getOperand(0);
2645 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2652 unsigned &Immr,
unsigned &Imms,
2653 bool BiggerPattern) {
2655 "N must be a SHR/SRA operation to call this function");
2657 EVT VT =
N->getValueType(0);
2662 assert((VT == MVT::i32 || VT == MVT::i64) &&
2663 "Type checking must have been done before calling this function");
2673 Opd0 =
N->getOperand(0).getOperand(0);
2674 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2680 Opd0 =
N->getOperand(0).getOperand(0);
2683 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2684 }
else if (BiggerPattern) {
2688 Opd0 =
N->getOperand(0);
2697 <<
": Found large shift immediate, this should not happen\n"));
2706 "bad amount in shift node!");
2707 int immr = SrlImm - ShlImm;
2712 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2714 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2718bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(
SDNode *
N) {
2721 EVT VT =
N->getValueType(0);
2722 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2723 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2734 unsigned Immr = ShiftImm;
2736 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2737 CurDAG->getTargetConstant(Imms, dl, VT)};
2738 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT, Ops);
2743 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2744 unsigned NumberOfIgnoredLowBits = 0,
2745 bool BiggerPattern =
false) {
2746 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2749 switch (
N->getOpcode()) {
2751 if (!
N->isMachineOpcode())
2756 NumberOfIgnoredLowBits, BiggerPattern);
2765 unsigned NOpc =
N->getMachineOpcode();
2769 case AArch64::SBFMWri:
2770 case AArch64::UBFMWri:
2771 case AArch64::SBFMXri:
2772 case AArch64::UBFMXri:
2774 Opd0 =
N->getOperand(0);
2775 Immr =
N->getConstantOperandVal(1);
2776 Imms =
N->getConstantOperandVal(2);
2783bool AArch64DAGToDAGISel::tryBitfieldExtractOp(
SDNode *
N) {
2784 unsigned Opc, Immr, Imms;
2789 EVT VT =
N->getValueType(0);
2794 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2795 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2796 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2798 SDNode *
BFM = CurDAG->getMachineNode(Opc, dl, MVT::i64, Ops64);
2799 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2805 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2806 CurDAG->getTargetConstant(Imms, dl, VT)};
2807 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
2816 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2817 assert((VT == MVT::i32 || VT == MVT::i64) &&
2818 "i32 or i64 mask type expected!");
2822 APInt SignificantDstMask =
2826 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2827 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2850 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2860 APInt OpUsefulBits(UsefulBits);
2864 OpUsefulBits <<= MSB - Imm + 1;
2869 OpUsefulBits <<= Imm;
2871 OpUsefulBits <<= MSB + 1;
2874 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2880 UsefulBits &= OpUsefulBits;
2886 cast<const ConstantSDNode>(
Op.getOperand(1).getNode())->getZExtValue();
2888 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2896 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2897 APInt Mask(UsefulBits);
2898 Mask.clearAllBits();
2906 Mask.lshrInPlace(ShiftAmt);
2912 Mask.lshrInPlace(ShiftAmt);
2924 cast<const ConstantSDNode>(
Op.getOperand(2).getNode())->getZExtValue();
2926 cast<const ConstantSDNode>(
Op.getOperand(3).getNode())->getZExtValue();
2928 APInt OpUsefulBits(UsefulBits);
2942 OpUsefulBits <<= Width;
2945 if (
Op.getOperand(1) == Orig) {
2947 Mask = ResultUsefulBits & OpUsefulBits;
2951 if (
Op.getOperand(0) == Orig)
2953 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2959 OpUsefulBits <<= Width;
2961 OpUsefulBits <<= LSB;
2963 if (
Op.getOperand(1) == Orig) {
2965 Mask = ResultUsefulBits & OpUsefulBits;
2966 Mask.lshrInPlace(LSB);
2969 if (
Op.getOperand(0) == Orig)
2970 Mask |= (ResultUsefulBits & ~OpUsefulBits);
2987 case AArch64::ANDSWri:
2988 case AArch64::ANDSXri:
2989 case AArch64::ANDWri:
2990 case AArch64::ANDXri:
2994 case AArch64::UBFMWri:
2995 case AArch64::UBFMXri:
2998 case AArch64::ORRWrs:
2999 case AArch64::ORRXrs:
3004 case AArch64::BFMWri:
3005 case AArch64::BFMXri:
3008 case AArch64::STRBBui:
3009 case AArch64::STURBBi:
3015 case AArch64::STRHHui:
3016 case AArch64::STURHHi:
3029 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3031 UsefulBits =
APInt(Bitwidth, 0);
3040 UsersUsefulBits |= UsefulBitsForUse;
3045 UsefulBits &= UsersUsefulBits;
3055 EVT VT =
Op.getValueType();
3058 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3061 if (ShlAmount > 0) {
3064 UBFMOpc, dl, VT,
Op,
3069 assert(ShlAmount < 0 &&
"expected right shift");
3070 int ShrAmount = -ShlAmount;
3096 bool BiggerPattern,
SDValue &Src,
3097 int &DstLSB,
int &Width) {
3098 EVT VT =
Op.getValueType();
3107 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3111 switch (
Op.getOpcode()) {
3116 NonZeroBits, Src, DstLSB, Width);
3119 NonZeroBits, Src, DstLSB, Width);
3132 EVT VT =
Op.getValueType();
3133 assert((VT == MVT::i32 || VT == MVT::i64) &&
3134 "Caller guarantees VT is one of i32 or i64");
3147 assert((~AndImm & NonZeroBits) == 0 &&
3148 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3177 if (!BiggerPattern && !AndOp0.
hasOneUse())
3196 <<
"Found large Width in bit-field-positioning -- this indicates no "
3197 "proper combining / constant folding was performed\n");
3206 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3221 "Op.getNode() should be a SHL node to call this function");
3223 "Op.getNode() should shift ShlImm to call this function");
3230 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3254 EVT VT =
Op.getValueType();
3255 assert((VT == MVT::i32 || VT == MVT::i64) &&
3256 "Caller guarantees that type is i32 or i64");
3263 if (!BiggerPattern && !
Op.hasOneUse())
3272 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3280 assert(VT == MVT::i32 || VT == MVT::i64);
3291 EVT VT =
N->getValueType(0);
3292 if (VT != MVT::i32 && VT != MVT::i64)
3310 if (!
And.hasOneUse() ||
3320 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3327 if ((OrImm & NotKnownZero) != 0) {
3339 unsigned ImmS = Width - 1;
3345 bool IsBFI = LSB != 0;
3350 unsigned OrChunks = 0, BFIChunks = 0;
3351 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3352 if (((OrImm >> Shift) & 0xFFFF) != 0)
3354 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3357 if (BFIChunks > OrChunks)
3363 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3371 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3380 if (!Dst.hasOneUse())
3383 EVT VT = Dst.getValueType();
3384 assert((VT == MVT::i32 || VT == MVT::i64) &&
3385 "Caller should guarantee that VT is one of i32 or i64");
3393 SDValue DstOp0 = Dst.getOperand(0);
3413 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3414 unsigned MaskWidth =
3417 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3423 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3424 ShiftedOperand =
SDValue(UBFMNode, 0);
3434 ShiftedOperand = Dst.getOperand(0);
3441 ShiftedOperand = Dst.getOperand(0);
3453 const bool BiggerPattern) {
3454 EVT VT =
N->getValueType(0);
3455 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3456 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3457 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3458 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3459 assert((VT == MVT::i32 || VT == MVT::i64) &&
3460 "Expect result type to be i32 or i64 since N is combinable to BFM");
3467 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3470 if (BiggerPattern) {
3484 SDValue Ops[] = {OrOpd0, ShiftedOperand,
3493 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3555 EVT VT =
N->getValueType(0);
3556 if (VT != MVT::i32 && VT != MVT::i64)
3564 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3565 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3585 for (
int I = 0;
I < 4; ++
I) {
3588 unsigned ImmR, ImmS;
3589 bool BiggerPattern =
I / 2;
3590 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3592 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3598 NumberOfIgnoredLowBits, BiggerPattern)) {
3601 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3602 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3607 Width = ImmS - ImmR + 1;
3618 Src, DstLSB, Width)) {
3626 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3636 APInt BitsToBeInserted =
3639 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3663 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3696 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3698 if (Src->hasOneUse() &&
3701 Src = Src->getOperand(0);
3711 unsigned ImmS = Width - 1;
3717 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3725bool AArch64DAGToDAGISel::tryBitfieldInsertOp(
SDNode *
N) {
3734 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3747bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(
SDNode *
N) {
3751 EVT VT =
N->getValueType(0);
3752 if (VT != MVT::i32 && VT != MVT::i64)
3758 Op0, DstLSB, Width))
3764 unsigned ImmS = Width - 1;
3767 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3768 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3769 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3770 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3776bool AArch64DAGToDAGISel::tryShiftAmountMod(
SDNode *
N) {
3777 EVT VT =
N->getValueType(0);
3780 switch (
N->getOpcode()) {
3782 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3785 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3788 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3791 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3799 if (VT == MVT::i32) {
3802 }
else if (VT == MVT::i64) {
3808 SDValue ShiftAmt =
N->getOperand(1);
3828 (Add0Imm %
Size == 0)) {
3834 if (SubVT == MVT::i32) {
3835 NegOpc = AArch64::SUBWrr;
3836 ZeroReg = AArch64::WZR;
3838 assert(SubVT == MVT::i64);
3839 NegOpc = AArch64::SUBXrr;
3840 ZeroReg = AArch64::XZR;
3843 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3845 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3846 NewShiftAmt =
SDValue(Neg, 0);
3854 if (SubVT == MVT::i32) {
3855 NotOpc = AArch64::ORNWrr;
3856 ZeroReg = AArch64::WZR;
3858 assert(SubVT == MVT::i64);
3859 NotOpc = AArch64::ORNXrr;
3860 ZeroReg = AArch64::XZR;
3863 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3865 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3866 NewShiftAmt =
SDValue(Not, 0);
3887 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3888 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3890 AArch64::SUBREG_TO_REG,
DL, VT,
3891 CurDAG->getTargetConstant(0,
DL, MVT::i64), NewShiftAmt,
SubReg);
3892 NewShiftAmt =
SDValue(Ext, 0);
3895 SDValue Ops[] = {
N->getOperand(0), NewShiftAmt};
3896 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
3903 bool isReciprocal) {
3906 FVal = CN->getValueAPF();
3907 else if (
LoadSDNode *LN = dyn_cast<LoadSDNode>(
N)) {
3910 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
3914 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
3915 FVal = cast<ConstantFP>(CN->
getConstVal())->getValueAPF();
3938 if (!IsExact || !IntVal.isPowerOf2())
3940 unsigned FBits = IntVal.logBase2();
3944 if (FBits == 0 || FBits > RegWidth)
return false;
3950bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
3951 unsigned RegWidth) {
3956bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
3958 unsigned RegWidth) {
3968 RegString.
split(Fields,
':');
3970 if (Fields.
size() == 1)
3974 &&
"Invalid number of fields in read register string");
3977 bool AllIntFields =
true;
3981 AllIntFields &= !
Field.getAsInteger(10, IntField);
3986 "Unexpected non-integer value in special register string.");
3991 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
3992 (Ops[3] << 3) | (Ops[4]);
3999bool AArch64DAGToDAGISel::tryReadRegister(
SDNode *
N) {
4000 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4001 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4006 unsigned Opcode64Bit = AArch64::MRS;
4011 const auto *TheReg =
4013 if (TheReg && TheReg->Readable &&
4014 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4015 Imm = TheReg->Encoding;
4021 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4022 Opcode64Bit = AArch64::ADR;
4030 SDValue InChain =
N->getOperand(0);
4031 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4032 if (!ReadIs128Bit) {
4033 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4034 {SysRegImm, InChain});
4038 {MVT::Untyped , MVT::Other },
4039 {SysRegImm, InChain});
4043 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4045 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4051 ReplaceUses(
SDValue(
N, 2), OutChain);
4060bool AArch64DAGToDAGISel::tryWriteRegister(
SDNode *
N) {
4061 const auto *MD = cast<MDNodeSDNode>(
N->getOperand(1));
4062 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0));
4067 if (!WriteIs128Bit) {
4073 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4075 assert(isa<ConstantSDNode>(
N->getOperand(2)) &&
4076 "Expected a constant integer expression.");
4077 unsigned Reg = PMapper->Encoding;
4078 uint64_t Immed =
N->getConstantOperandVal(2);
4079 CurDAG->SelectNodeTo(
4080 N, State, MVT::Other, CurDAG->getTargetConstant(Reg,
DL, MVT::i32),
4081 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4087 if (trySelectPState(
4088 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4089 AArch64::MSRpstateImm4))
4091 if (trySelectPState(
4092 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4093 AArch64::MSRpstateImm1))
4103 if (TheReg && TheReg->Writeable &&
4104 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4105 Imm = TheReg->Encoding;
4113 SDValue InChain =
N->getOperand(0);
4114 if (!WriteIs128Bit) {
4115 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4116 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4117 N->getOperand(2), InChain);
4121 SDNode *Pair = CurDAG->getMachineNode(
4122 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4123 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4126 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4128 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4130 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4131 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4139bool AArch64DAGToDAGISel::SelectCMP_SWAP(
SDNode *
N) {
4141 EVT MemTy = cast<MemSDNode>(
N)->getMemoryVT();
4144 if (Subtarget->hasLSE())
return false;
4146 if (MemTy == MVT::i8)
4147 Opcode = AArch64::CMP_SWAP_8;
4148 else if (MemTy == MVT::i16)
4149 Opcode = AArch64::CMP_SWAP_16;
4150 else if (MemTy == MVT::i32)
4151 Opcode = AArch64::CMP_SWAP_32;
4152 else if (MemTy == MVT::i64)
4153 Opcode = AArch64::CMP_SWAP_64;
4157 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4158 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4160 SDNode *CmpSwap = CurDAG->getMachineNode(
4162 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops);
4165 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {
MemOp});
4169 CurDAG->RemoveDeadNode(
N);
4176 if (!isa<ConstantSDNode>(
N))
4188 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4189 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4196 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4197 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4201 if (Val <= 65280 && Val % 256 == 0) {
4202 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4203 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4214bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N,
MVT VT,
4217 if (!isa<ConstantSDNode>(
N))
4221 int64_t Val = cast<ConstantSDNode>(
N)
4238 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4239 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4246 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4247 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4251 if (Val <= 65280 && Val % 256 == 0) {
4252 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4253 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4266 if (!isa<ConstantSDNode>(
N))
4270 int64_t Val = cast<ConstantSDNode>(
N)
4278 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4279 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4285 if (Val >= -128 && Val <= 127) {
4286 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4287 Imm = CurDAG->getTargetConstant(Val & 0xFF,
DL, MVT::i32);
4291 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) {
4292 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4293 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF,
DL, MVT::i32);
4304bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4305 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4306 int64_t ImmVal = CNode->getSExtValue();
4308 if (ImmVal >= -128 && ImmVal < 128) {
4309 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4317 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4318 uint64_t ImmVal = CNode->getZExtValue();
4328 ImmVal &= 0xFFFFFFFF;
4337 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4346 if (
auto CNode = dyn_cast<ConstantSDNode>(
N)) {
4347 uint64_t ImmVal = CNode->getZExtValue();
4357 ImmVal |= ImmVal << 8;
4358 ImmVal |= ImmVal << 16;
4359 ImmVal |= ImmVal << 32;
4363 ImmVal |= ImmVal << 16;
4364 ImmVal |= ImmVal << 32;
4367 ImmVal &= 0xFFFFFFFF;
4368 ImmVal |= ImmVal << 32;
4378 Imm = CurDAG->getTargetConstant(encoding,
DL, MVT::i64);
4393 if (
auto *CN = dyn_cast<ConstantSDNode>(
N)) {
4394 uint64_t ImmVal = CN->getZExtValue();
4401 if (ImmVal >
High) {
4402 if (!AllowSaturation)
4407 Imm = CurDAG->getTargetConstant(ImmVal,
SDLoc(
N), MVT::i32);
4414bool AArch64DAGToDAGISel::trySelectStackSlotTagP(
SDNode *
N) {
4418 if (!(isa<FrameIndexSDNode>(
N->getOperand(1)))) {
4430 int FI = cast<FrameIndexSDNode>(
N->getOperand(1))->getIndex();
4431 SDValue FiOp = CurDAG->getTargetFrameIndex(
4433 int TagOffset =
N->getConstantOperandVal(3);
4435 SDNode *Out = CurDAG->getMachineNode(
4436 AArch64::TAGPstack,
DL, MVT::i64,
4437 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->getOperand(2),
4438 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4439 ReplaceNode(
N, Out);
4443void AArch64DAGToDAGISel::SelectTagP(
SDNode *
N) {
4444 assert(isa<ConstantSDNode>(
N->getOperand(3)) &&
4445 "llvm.aarch64.tagp third argument must be an immediate");
4446 if (trySelectStackSlotTagP(
N))
4453 int TagOffset =
N->getConstantOperandVal(3);
4454 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4455 {
N->getOperand(1),
N->getOperand(2)});
4456 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4457 {
SDValue(N1, 0),
N->getOperand(2)});
4458 SDNode *N3 = CurDAG->getMachineNode(
4459 AArch64::ADDG,
DL, MVT::i64,
4460 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4461 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4465bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(
SDNode *
N) {
4469 if (
N->getConstantOperandVal(2) != 0)
4471 if (!
N->getOperand(0).isUndef())
4475 EVT VT =
N->getValueType(0);
4476 EVT InVT =
N->getOperand(1).getValueType();
4487 "Expected to insert into a packed scalable vector!");
4490 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4491 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4492 N->getOperand(1), RC));
4496bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(
SDNode *
N) {
4500 if (
N->getConstantOperandVal(1) != 0)
4504 EVT VT =
N->getValueType(0);
4505 EVT InVT =
N->getOperand(0).getValueType();
4516 "Expected to extract from a packed scalable vector!");
4519 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4520 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4521 N->getOperand(0), RC));
4525bool AArch64DAGToDAGISel::trySelectXAR(
SDNode *
N) {
4530 EVT VT =
N->getValueType(0);
4542 (Subtarget->hasSVE2() ||
4543 (Subtarget->hasSME() && Subtarget->isStreaming()))) {
4552 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4553 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4560 APInt ShlAmt, ShrAmt;
4573 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::Int>(
4574 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4575 AArch64::XAR_ZZZI_D})) {
4576 CurDAG->SelectNodeTo(
N, Opc, VT, Ops);
4582 if (!Subtarget->hasSHA3())
4604 if (ShAmt + HsAmt != 64)
4608 CurDAG->SelectNodeTo(
N, AArch64::XAR, N0.
getValueType(), Ops);
4613void AArch64DAGToDAGISel::Select(
SDNode *
Node) {
4615 if (
Node->isMachineOpcode()) {
4617 Node->setNodeId(-1);
4622 EVT VT =
Node->getValueType(0);
4624 switch (
Node->getOpcode()) {
4629 if (SelectCMP_SWAP(
Node))
4635 if (tryReadRegister(
Node))
4641 if (tryWriteRegister(
Node))
4648 if (tryIndexedLoad(
Node))
4657 if (tryBitfieldExtractOp(
Node))
4659 if (tryBitfieldInsertInZeroOp(
Node))
4664 if (tryShiftAmountMod(
Node))
4669 if (tryBitfieldExtractOpFromSExt(
Node))
4674 if (tryBitfieldInsertOp(
Node))
4676 if (trySelectXAR(
Node))
4681 if (trySelectCastScalableToFixedLengthVector(
Node))
4687 if (trySelectCastFixedLengthToScalableVector(
Node))
4696 if (ConstNode->
isZero()) {
4697 if (VT == MVT::i32) {
4699 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::WZR, MVT::i32);
4700 ReplaceNode(
Node,
New.getNode());
4702 }
else if (VT == MVT::i64) {
4704 CurDAG->getEntryNode(),
SDLoc(
Node), AArch64::XZR, MVT::i64);
4705 ReplaceNode(
Node,
New.getNode());
4714 int FI = cast<FrameIndexSDNode>(
Node)->getIndex();
4717 SDValue TFI = CurDAG->getTargetFrameIndex(
4720 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4721 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4722 CurDAG->SelectNodeTo(
Node, AArch64::ADDXri, MVT::i64, Ops);
4726 unsigned IntNo =
Node->getConstantOperandVal(1);
4730 case Intrinsic::aarch64_gcsss: {
4734 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4736 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4737 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4738 MVT::Other, Zero,
SDValue(SS1, 0));
4739 ReplaceNode(
Node, SS2);
4742 case Intrinsic::aarch64_ldaxp:
4743 case Intrinsic::aarch64_ldxp: {
4745 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4750 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4751 MVT::Other, MemAddr, Chain);
4755 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4756 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {
MemOp});
4757 ReplaceNode(
Node, Ld);
4760 case Intrinsic::aarch64_stlxp:
4761 case Intrinsic::aarch64_stxp: {
4763 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4771 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4773 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other, Ops);
4776 cast<MemIntrinsicSDNode>(
Node)->getMemOperand();
4777 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {
MemOp});
4779 ReplaceNode(
Node, St);
4782 case Intrinsic::aarch64_neon_ld1x2:
4783 if (VT == MVT::v8i8) {
4784 SelectLoad(
Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
4786 }
else if (VT == MVT::v16i8) {
4787 SelectLoad(
Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
4789 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4790 SelectLoad(
Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
4792 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4793 SelectLoad(
Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
4795 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4796 SelectLoad(
Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
4798 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4799 SelectLoad(
Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
4801 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4802 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4804 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4805 SelectLoad(
Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
4809 case Intrinsic::aarch64_neon_ld1x3:
4810 if (VT == MVT::v8i8) {
4811 SelectLoad(
Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
4813 }
else if (VT == MVT::v16i8) {
4814 SelectLoad(
Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
4816 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4817 SelectLoad(
Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
4819 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4820 SelectLoad(
Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
4822 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4823 SelectLoad(
Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
4825 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4826 SelectLoad(
Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
4828 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4829 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4831 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4832 SelectLoad(
Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
4836 case Intrinsic::aarch64_neon_ld1x4:
4837 if (VT == MVT::v8i8) {
4838 SelectLoad(
Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
4840 }
else if (VT == MVT::v16i8) {
4841 SelectLoad(
Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
4843 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4844 SelectLoad(
Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
4846 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4847 SelectLoad(
Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
4849 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4850 SelectLoad(
Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
4852 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4853 SelectLoad(
Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
4855 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4856 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4858 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4859 SelectLoad(
Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
4863 case Intrinsic::aarch64_neon_ld2:
4864 if (VT == MVT::v8i8) {
4865 SelectLoad(
Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
4867 }
else if (VT == MVT::v16i8) {
4868 SelectLoad(
Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
4870 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4871 SelectLoad(
Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
4873 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4874 SelectLoad(
Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
4876 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4877 SelectLoad(
Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
4879 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4880 SelectLoad(
Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
4882 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4883 SelectLoad(
Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
4885 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4886 SelectLoad(
Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
4890 case Intrinsic::aarch64_neon_ld3:
4891 if (VT == MVT::v8i8) {
4892 SelectLoad(
Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
4894 }
else if (VT == MVT::v16i8) {
4895 SelectLoad(
Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
4897 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4898 SelectLoad(
Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
4900 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4901 SelectLoad(
Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
4903 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4904 SelectLoad(
Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
4906 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4907 SelectLoad(
Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
4909 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4910 SelectLoad(
Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
4912 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4913 SelectLoad(
Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
4917 case Intrinsic::aarch64_neon_ld4:
4918 if (VT == MVT::v8i8) {
4919 SelectLoad(
Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
4921 }
else if (VT == MVT::v16i8) {
4922 SelectLoad(
Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
4924 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4925 SelectLoad(
Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
4927 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4928 SelectLoad(
Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
4930 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4931 SelectLoad(
Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
4933 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4934 SelectLoad(
Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
4936 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4937 SelectLoad(
Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
4939 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4940 SelectLoad(
Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
4944 case Intrinsic::aarch64_neon_ld2r:
4945 if (VT == MVT::v8i8) {
4946 SelectLoad(
Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
4948 }
else if (VT == MVT::v16i8) {
4949 SelectLoad(
Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
4951 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4952 SelectLoad(
Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
4954 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4955 SelectLoad(
Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
4957 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4958 SelectLoad(
Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
4960 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4961 SelectLoad(
Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
4963 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4964 SelectLoad(
Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
4966 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4967 SelectLoad(
Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
4971 case Intrinsic::aarch64_neon_ld3r:
4972 if (VT == MVT::v8i8) {
4973 SelectLoad(
Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
4975 }
else if (VT == MVT::v16i8) {
4976 SelectLoad(
Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
4978 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
4979 SelectLoad(
Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
4981 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
4982 SelectLoad(
Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
4984 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
4985 SelectLoad(
Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
4987 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
4988 SelectLoad(
Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
4990 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
4991 SelectLoad(
Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
4993 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
4994 SelectLoad(
Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
4998 case Intrinsic::aarch64_neon_ld4r:
4999 if (VT == MVT::v8i8) {
5000 SelectLoad(
Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5002 }
else if (VT == MVT::v16i8) {
5003 SelectLoad(
Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5005 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5006 SelectLoad(
Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5008 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5009 SelectLoad(
Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5011 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5012 SelectLoad(
Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5014 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5015 SelectLoad(
Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5017 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5018 SelectLoad(
Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5020 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5021 SelectLoad(
Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5025 case Intrinsic::aarch64_neon_ld2lane:
5026 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5027 SelectLoadLane(
Node, 2, AArch64::LD2i8);
5029 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5030 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5031 SelectLoadLane(
Node, 2, AArch64::LD2i16);
5033 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5035 SelectLoadLane(
Node, 2, AArch64::LD2i32);
5037 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5039 SelectLoadLane(
Node, 2, AArch64::LD2i64);
5043 case Intrinsic::aarch64_neon_ld3lane:
5044 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5045 SelectLoadLane(
Node, 3, AArch64::LD3i8);
5047 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5048 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5049 SelectLoadLane(
Node, 3, AArch64::LD3i16);
5051 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5053 SelectLoadLane(
Node, 3, AArch64::LD3i32);
5055 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5057 SelectLoadLane(
Node, 3, AArch64::LD3i64);
5061 case Intrinsic::aarch64_neon_ld4lane:
5062 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5063 SelectLoadLane(
Node, 4, AArch64::LD4i8);
5065 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5066 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5067 SelectLoadLane(
Node, 4, AArch64::LD4i16);
5069 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5071 SelectLoadLane(
Node, 4, AArch64::LD4i32);
5073 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5075 SelectLoadLane(
Node, 4, AArch64::LD4i64);
5079 case Intrinsic::aarch64_ld64b:
5080 SelectLoad(
Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5082 case Intrinsic::aarch64_sve_ld2q_sret: {
5083 SelectPredicatedLoad(
Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5086 case Intrinsic::aarch64_sve_ld3q_sret: {
5087 SelectPredicatedLoad(
Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5090 case Intrinsic::aarch64_sve_ld4q_sret: {
5091 SelectPredicatedLoad(
Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5094 case Intrinsic::aarch64_sve_ld2_sret: {
5095 if (VT == MVT::nxv16i8) {
5096 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5099 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5100 VT == MVT::nxv8bf16) {
5101 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5104 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5105 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5108 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5109 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5115 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5116 if (VT == MVT::nxv16i8) {
5117 if (Subtarget->hasSME2())
5118 SelectContiguousMultiVectorLoad(
5119 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5120 else if (Subtarget->hasSVE2p1())
5121 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LD1B_2Z_IMM,
5126 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5127 VT == MVT::nxv8bf16) {
5128 if (Subtarget->hasSME2())
5129 SelectContiguousMultiVectorLoad(
5130 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5131 else if (Subtarget->hasSVE2p1())
5132 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LD1H_2Z_IMM,
5137 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5138 if (Subtarget->hasSME2())
5139 SelectContiguousMultiVectorLoad(
5140 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5141 else if (Subtarget->hasSVE2p1())
5142 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LD1W_2Z_IMM,
5147 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5148 if (Subtarget->hasSME2())
5149 SelectContiguousMultiVectorLoad(
5150 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5151 else if (Subtarget->hasSVE2p1())
5152 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LD1D_2Z_IMM,
5160 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5161 if (VT == MVT::nxv16i8) {
5162 if (Subtarget->hasSME2())
5163 SelectContiguousMultiVectorLoad(
5164 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5165 else if (Subtarget->hasSVE2p1())
5166 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LD1B_4Z_IMM,
5171 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5172 VT == MVT::nxv8bf16) {
5173 if (Subtarget->hasSME2())
5174 SelectContiguousMultiVectorLoad(
5175 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5176 else if (Subtarget->hasSVE2p1())
5177 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LD1H_4Z_IMM,
5182 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5183 if (Subtarget->hasSME2())
5184 SelectContiguousMultiVectorLoad(
5185 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5186 else if (Subtarget->hasSVE2p1())
5187 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LD1W_4Z_IMM,
5192 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5193 if (Subtarget->hasSME2())
5194 SelectContiguousMultiVectorLoad(
5195 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5196 else if (Subtarget->hasSVE2p1())
5197 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LD1D_4Z_IMM,
5205 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5206 if (VT == MVT::nxv16i8) {
5207 if (Subtarget->hasSME2())
5208 SelectContiguousMultiVectorLoad(
Node, 2, 0,
5209 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5210 AArch64::LDNT1B_2Z_PSEUDO);
5211 else if (Subtarget->hasSVE2p1())
5212 SelectContiguousMultiVectorLoad(
Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5213 AArch64::LDNT1B_2Z);
5217 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5218 VT == MVT::nxv8bf16) {
5219 if (Subtarget->hasSME2())
5220 SelectContiguousMultiVectorLoad(
Node, 2, 1,
5221 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5222 AArch64::LDNT1H_2Z_PSEUDO);
5223 else if (Subtarget->hasSVE2p1())
5224 SelectContiguousMultiVectorLoad(
Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5225 AArch64::LDNT1H_2Z);
5229 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5230 if (Subtarget->hasSME2())
5231 SelectContiguousMultiVectorLoad(
Node, 2, 2,
5232 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5233 AArch64::LDNT1W_2Z_PSEUDO);
5234 else if (Subtarget->hasSVE2p1())
5235 SelectContiguousMultiVectorLoad(
Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5236 AArch64::LDNT1W_2Z);
5240 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5241 if (Subtarget->hasSME2())
5242 SelectContiguousMultiVectorLoad(
Node, 2, 3,
5243 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5244 AArch64::LDNT1D_2Z_PSEUDO);
5245 else if (Subtarget->hasSVE2p1())
5246 SelectContiguousMultiVectorLoad(
Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5247 AArch64::LDNT1D_2Z);
5254 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5255 if (VT == MVT::nxv16i8) {
5256 if (Subtarget->hasSME2())
5257 SelectContiguousMultiVectorLoad(
Node, 4, 0,
5258 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5259 AArch64::LDNT1B_4Z_PSEUDO);
5260 else if (Subtarget->hasSVE2p1())
5261 SelectContiguousMultiVectorLoad(
Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5262 AArch64::LDNT1B_4Z);
5266 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5267 VT == MVT::nxv8bf16) {
5268 if (Subtarget->hasSME2())
5269 SelectContiguousMultiVectorLoad(
Node, 4, 1,
5270 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5271 AArch64::LDNT1H_4Z_PSEUDO);
5272 else if (Subtarget->hasSVE2p1())
5273 SelectContiguousMultiVectorLoad(
Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5274 AArch64::LDNT1H_4Z);
5278 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5279 if (Subtarget->hasSME2())
5280 SelectContiguousMultiVectorLoad(
Node, 4, 2,
5281 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5282 AArch64::LDNT1W_4Z_PSEUDO);
5283 else if (Subtarget->hasSVE2p1())
5284 SelectContiguousMultiVectorLoad(
Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5285 AArch64::LDNT1W_4Z);
5289 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5290 if (Subtarget->hasSME2())
5291 SelectContiguousMultiVectorLoad(
Node, 4, 3,
5292 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5293 AArch64::LDNT1D_4Z_PSEUDO);
5294 else if (Subtarget->hasSVE2p1())
5295 SelectContiguousMultiVectorLoad(
Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5296 AArch64::LDNT1D_4Z);
5303 case Intrinsic::aarch64_sve_ld3_sret: {
5304 if (VT == MVT::nxv16i8) {
5305 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5308 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5309 VT == MVT::nxv8bf16) {
5310 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5313 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5314 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5317 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5318 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5324 case Intrinsic::aarch64_sve_ld4_sret: {
5325 if (VT == MVT::nxv16i8) {
5326 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5329 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5330 VT == MVT::nxv8bf16) {
5331 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5334 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5335 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5338 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5339 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5345 case Intrinsic::aarch64_sme_read_hor_vg2: {
5346 if (VT == MVT::nxv16i8) {
5347 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5348 AArch64::MOVA_2ZMXI_H_B);
5350 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5351 VT == MVT::nxv8bf16) {
5352 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5353 AArch64::MOVA_2ZMXI_H_H);
5355 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5356 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5357 AArch64::MOVA_2ZMXI_H_S);
5359 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5360 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5361 AArch64::MOVA_2ZMXI_H_D);
5366 case Intrinsic::aarch64_sme_read_ver_vg2: {
5367 if (VT == MVT::nxv16i8) {
5368 SelectMultiVectorMove<14, 2>(
Node, 2, AArch64::ZAB0,
5369 AArch64::MOVA_2ZMXI_V_B);
5371 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5372 VT == MVT::nxv8bf16) {
5373 SelectMultiVectorMove<6, 2>(
Node, 2, AArch64::ZAH0,
5374 AArch64::MOVA_2ZMXI_V_H);
5376 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5377 SelectMultiVectorMove<2, 2>(
Node, 2, AArch64::ZAS0,
5378 AArch64::MOVA_2ZMXI_V_S);
5380 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5381 SelectMultiVectorMove<0, 2>(
Node, 2, AArch64::ZAD0,
5382 AArch64::MOVA_2ZMXI_V_D);
5387 case Intrinsic::aarch64_sme_read_hor_vg4: {
5388 if (VT == MVT::nxv16i8) {
5389 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5390 AArch64::MOVA_4ZMXI_H_B);
5392 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5393 VT == MVT::nxv8bf16) {
5394 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5395 AArch64::MOVA_4ZMXI_H_H);
5397 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5398 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAS0,
5399 AArch64::MOVA_4ZMXI_H_S);
5401 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5402 SelectMultiVectorMove<0, 2>(
Node, 4, AArch64::ZAD0,
5403 AArch64::MOVA_4ZMXI_H_D);
5408 case Intrinsic::aarch64_sme_read_ver_vg4: {
5409 if (VT == MVT::nxv16i8) {
5410 SelectMultiVectorMove<12, 4>(
Node, 4, AArch64::ZAB0,
5411 AArch64::MOVA_4ZMXI_V_B);
5413 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5414 VT == MVT::nxv8bf16) {
5415 SelectMultiVectorMove<4, 4>(
Node, 4, AArch64::ZAH0,
5416 AArch64::MOVA_4ZMXI_V_H);
5418 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5419 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAS0,
5420 AArch64::MOVA_4ZMXI_V_S);
5422 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5423 SelectMultiVectorMove<0, 4>(
Node, 4, AArch64::ZAD0,
5424 AArch64::MOVA_4ZMXI_V_D);
5429 case Intrinsic::aarch64_sme_read_vg1x2: {
5430 SelectMultiVectorMove<7, 1>(
Node, 2, AArch64::ZA,
5431 AArch64::MOVA_VG2_2ZMXI);
5434 case Intrinsic::aarch64_sme_read_vg1x4: {
5435 SelectMultiVectorMove<7, 1>(
Node, 4, AArch64::ZA,
5436 AArch64::MOVA_VG4_4ZMXI);
5439 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5440 if (VT == MVT::nxv16i8) {
5441 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5443 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5444 VT == MVT::nxv8bf16) {
5445 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5447 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5448 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5450 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5451 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5456 case Intrinsic::aarch64_sme_readz_vert_x2: {
5457 if (VT == MVT::nxv16i8) {
5458 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5460 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5461 VT == MVT::nxv8bf16) {
5462 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5464 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5465 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5467 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5468 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5473 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5474 if (VT == MVT::nxv16i8) {
5475 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5477 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5478 VT == MVT::nxv8bf16) {
5479 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5481 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5482 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5484 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5485 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5490 case Intrinsic::aarch64_sme_readz_vert_x4: {
5491 if (VT == MVT::nxv16i8) {
5492 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5494 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5495 VT == MVT::nxv8bf16) {
5496 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5498 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5499 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5501 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5502 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5507 case Intrinsic::aarch64_sme_readz_x2: {
5508 SelectMultiVectorMoveZ(
Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5512 case Intrinsic::aarch64_sme_readz_x4: {
5513 SelectMultiVectorMoveZ(
Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5517 case Intrinsic::swift_async_context_addr: {
5520 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5522 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5523 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5524 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5528 CurDAG->RemoveDeadNode(
Node);
5530 auto &MF = CurDAG->getMachineFunction();
5531 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5535 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5536 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5537 Node->getValueType(0),
5538 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5539 AArch64::LUTI2_4ZTZI_S}))
5541 SelectMultiVectorLutiLane(
Node, 4, Opc, 3);
5544 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5545 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5546 Node->getValueType(0),
5547 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5549 SelectMultiVectorLutiLane(
Node, 4, Opc, 1);
5552 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5553 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5554 Node->getValueType(0),
5555 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5556 AArch64::LUTI2_2ZTZI_S}))
5558 SelectMultiVectorLutiLane(
Node, 2, Opc, 7);
5561 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5562 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
5563 Node->getValueType(0),
5564 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5565 AArch64::LUTI4_2ZTZI_S}))
5567 SelectMultiVectorLutiLane(
Node, 2, Opc, 3);
5570 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5571 SelectMultiVectorLuti(
Node, 4, AArch64::LUTI4_4ZZT2Z);
5574 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5575 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5576 Node->getValueType(0),
5577 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5578 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5580 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5581 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5582 Node->getValueType(0),
5583 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5584 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5586 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5587 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5588 Node->getValueType(0),
5589 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5590 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5592 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5593 if (
auto Opc = SelectOpcodeFromVT<SelectTypeKind::FP>(
5594 Node->getValueType(0),
5595 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5596 SelectCVTIntrinsicFP8(
Node, 2, Opc);
5601 unsigned IntNo =
Node->getConstantOperandVal(0);
5605 case Intrinsic::aarch64_tagp:
5609 case Intrinsic::ptrauth_auth:
5610 SelectPtrauthAuth(
Node);
5613 case Intrinsic::ptrauth_resign:
5614 SelectPtrauthResign(
Node);
5617 case Intrinsic::aarch64_neon_tbl2:
5618 SelectTable(
Node, 2,
5619 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5622 case Intrinsic::aarch64_neon_tbl3:
5623 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5624 : AArch64::TBLv16i8Three,
5627 case Intrinsic::aarch64_neon_tbl4:
5628 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5629 : AArch64::TBLv16i8Four,
5632 case Intrinsic::aarch64_neon_tbx2:
5633 SelectTable(
Node, 2,
5634 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5637 case Intrinsic::aarch64_neon_tbx3:
5638 SelectTable(
Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5639 : AArch64::TBXv16i8Three,
5642 case Intrinsic::aarch64_neon_tbx4:
5643 SelectTable(
Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5644 : AArch64::TBXv16i8Four,
5647 case Intrinsic::aarch64_sve_srshl_single_x2:
5648 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5649 Node->getValueType(0),
5650 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5651 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5652 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5654 case Intrinsic::aarch64_sve_srshl_single_x4:
5655 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5656 Node->getValueType(0),
5657 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5658 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5659 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5661 case Intrinsic::aarch64_sve_urshl_single_x2:
5662 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5663 Node->getValueType(0),
5664 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5665 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5666 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5668 case Intrinsic::aarch64_sve_urshl_single_x4:
5669 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5670 Node->getValueType(0),
5671 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5672 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5673 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5675 case Intrinsic::aarch64_sve_srshl_x2:
5676 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5677 Node->getValueType(0),
5678 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5679 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5680 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5682 case Intrinsic::aarch64_sve_srshl_x4:
5683 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5684 Node->getValueType(0),
5685 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5686 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5687 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5689 case Intrinsic::aarch64_sve_urshl_x2:
5690 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5691 Node->getValueType(0),
5692 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5693 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5694 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5696 case Intrinsic::aarch64_sve_urshl_x4:
5697 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5698 Node->getValueType(0),
5699 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5700 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5701 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5703 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5704 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5705 Node->getValueType(0),
5706 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5707 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5708 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5710 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5711 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5712 Node->getValueType(0),
5713 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5714 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5715 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5717 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5718 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5719 Node->getValueType(0),
5720 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5721 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5722 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5724 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5725 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5726 Node->getValueType(0),
5727 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5728 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5729 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5731 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5732 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5733 Node->getValueType(0),
5734 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5735 AArch64::FSCALE_2ZZ_D}))
5736 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5738 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5739 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5740 Node->getValueType(0),
5741 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5742 AArch64::FSCALE_4ZZ_D}))
5743 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5745 case Intrinsic::aarch64_sme_fp8_scale_x2:
5746 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5747 Node->getValueType(0),
5748 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5749 AArch64::FSCALE_2Z2Z_D}))
5750 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5752 case Intrinsic::aarch64_sme_fp8_scale_x4:
5753 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5754 Node->getValueType(0),
5755 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5756 AArch64::FSCALE_4Z4Z_D}))
5757 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5759 case Intrinsic::aarch64_sve_whilege_x2:
5760 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5761 Node->getValueType(0),
5762 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5763 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5764 SelectWhilePair(
Node,
Op);
5766 case Intrinsic::aarch64_sve_whilegt_x2:
5767 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5768 Node->getValueType(0),
5769 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5770 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5771 SelectWhilePair(
Node,
Op);
5773 case Intrinsic::aarch64_sve_whilehi_x2:
5774 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5775 Node->getValueType(0),
5776 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
5777 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
5778 SelectWhilePair(
Node,
Op);
5780 case Intrinsic::aarch64_sve_whilehs_x2:
5781 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5782 Node->getValueType(0),
5783 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
5784 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
5785 SelectWhilePair(
Node,
Op);
5787 case Intrinsic::aarch64_sve_whilele_x2:
5788 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5789 Node->getValueType(0),
5790 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
5791 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
5792 SelectWhilePair(
Node,
Op);
5794 case Intrinsic::aarch64_sve_whilelo_x2:
5795 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5796 Node->getValueType(0),
5797 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
5798 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
5799 SelectWhilePair(
Node,
Op);
5801 case Intrinsic::aarch64_sve_whilels_x2:
5802 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5803 Node->getValueType(0),
5804 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
5805 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
5806 SelectWhilePair(
Node,
Op);
5808 case Intrinsic::aarch64_sve_whilelt_x2:
5809 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int1>(
5810 Node->getValueType(0),
5811 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
5812 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
5813 SelectWhilePair(
Node,
Op);
5815 case Intrinsic::aarch64_sve_smax_single_x2:
5816 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5817 Node->getValueType(0),
5818 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
5819 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
5820 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5822 case Intrinsic::aarch64_sve_umax_single_x2:
5823 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5824 Node->getValueType(0),
5825 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
5826 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
5827 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5829 case Intrinsic::aarch64_sve_fmax_single_x2:
5830 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5831 Node->getValueType(0),
5832 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
5833 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
5834 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5836 case Intrinsic::aarch64_sve_smax_single_x4:
5837 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5838 Node->getValueType(0),
5839 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
5840 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
5841 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5843 case Intrinsic::aarch64_sve_umax_single_x4:
5844 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5845 Node->getValueType(0),
5846 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
5847 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
5848 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5850 case Intrinsic::aarch64_sve_fmax_single_x4:
5851 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5852 Node->getValueType(0),
5853 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
5854 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
5855 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5857 case Intrinsic::aarch64_sve_smin_single_x2:
5858 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5859 Node->getValueType(0),
5860 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
5861 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
5862 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5864 case Intrinsic::aarch64_sve_umin_single_x2:
5865 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5866 Node->getValueType(0),
5867 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
5868 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
5869 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5871 case Intrinsic::aarch64_sve_fmin_single_x2:
5872 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5873 Node->getValueType(0),
5874 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
5875 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
5876 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
5878 case Intrinsic::aarch64_sve_smin_single_x4:
5879 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5880 Node->getValueType(0),
5881 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
5882 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
5883 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5885 case Intrinsic::aarch64_sve_umin_single_x4:
5886 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5887 Node->getValueType(0),
5888 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
5889 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
5890 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5892 case Intrinsic::aarch64_sve_fmin_single_x4:
5893 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5894 Node->getValueType(0),
5895 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
5896 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
5897 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
5899 case Intrinsic::aarch64_sve_smax_x2:
5900 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5901 Node->getValueType(0),
5902 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
5903 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
5904 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5906 case Intrinsic::aarch64_sve_umax_x2:
5907 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5908 Node->getValueType(0),
5909 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
5910 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
5911 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5913 case Intrinsic::aarch64_sve_fmax_x2:
5914 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5915 Node->getValueType(0),
5916 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
5917 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
5918 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5920 case Intrinsic::aarch64_sve_smax_x4:
5921 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5922 Node->getValueType(0),
5923 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
5924 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
5925 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5927 case Intrinsic::aarch64_sve_umax_x4:
5928 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5929 Node->getValueType(0),
5930 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
5931 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
5932 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5934 case Intrinsic::aarch64_sve_fmax_x4:
5935 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5936 Node->getValueType(0),
5937 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
5938 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
5939 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5941 case Intrinsic::aarch64_sme_famax_x2:
5942 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5943 Node->getValueType(0),
5944 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
5945 AArch64::FAMAX_2Z2Z_D}))
5946 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5948 case Intrinsic::aarch64_sme_famax_x4:
5949 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5950 Node->getValueType(0),
5951 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
5952 AArch64::FAMAX_4Z4Z_D}))
5953 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5955 case Intrinsic::aarch64_sme_famin_x2:
5956 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5957 Node->getValueType(0),
5958 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
5959 AArch64::FAMIN_2Z2Z_D}))
5960 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5962 case Intrinsic::aarch64_sme_famin_x4:
5963 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5964 Node->getValueType(0),
5965 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
5966 AArch64::FAMIN_4Z4Z_D}))
5967 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5969 case Intrinsic::aarch64_sve_smin_x2:
5970 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5971 Node->getValueType(0),
5972 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
5973 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
5974 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5976 case Intrinsic::aarch64_sve_umin_x2:
5977 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5978 Node->getValueType(0),
5979 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
5980 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
5981 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5983 case Intrinsic::aarch64_sve_fmin_x2:
5984 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
5985 Node->getValueType(0),
5986 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
5987 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
5988 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
5990 case Intrinsic::aarch64_sve_smin_x4:
5991 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5992 Node->getValueType(0),
5993 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
5994 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
5995 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
5997 case Intrinsic::aarch64_sve_umin_x4:
5998 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
5999 Node->getValueType(0),
6000 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6001 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6002 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6004 case Intrinsic::aarch64_sve_fmin_x4:
6005 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6006 Node->getValueType(0),
6007 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6008 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6009 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6011 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6012 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6013 Node->getValueType(0),
6014 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6015 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6016 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6018 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6019 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6020 Node->getValueType(0),
6021 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6022 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6023 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6025 case Intrinsic::aarch64_sve_fminnm_single_x2:
6026 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6027 Node->getValueType(0),
6028 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6029 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6030 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6032 case Intrinsic::aarch64_sve_fminnm_single_x4:
6033 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6034 Node->getValueType(0),
6035 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6036 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6037 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6039 case Intrinsic::aarch64_sve_fmaxnm_x2:
6040 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6041 Node->getValueType(0),
6042 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6043 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6044 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6046 case Intrinsic::aarch64_sve_fmaxnm_x4:
6047 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6048 Node->getValueType(0),
6049 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6050 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6051 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6053 case Intrinsic::aarch64_sve_fminnm_x2:
6054 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6055 Node->getValueType(0),
6056 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6057 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6058 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op);
6060 case Intrinsic::aarch64_sve_fminnm_x4:
6061 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6062 Node->getValueType(0),
6063 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6064 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6065 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op);
6067 case Intrinsic::aarch64_sve_fcvtzs_x2:
6068 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6070 case Intrinsic::aarch64_sve_scvtf_x2:
6071 SelectCVTIntrinsic(
Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6073 case Intrinsic::aarch64_sve_fcvtzu_x2:
6074 SelectCVTIntrinsic(
Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6076 case Intrinsic::aarch64_sve_ucvtf_x2:
6077 SelectCVTIntrinsic(
Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6079 case Intrinsic::aarch64_sve_fcvtzs_x4:
6080 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6082 case Intrinsic::aarch64_sve_scvtf_x4:
6083 SelectCVTIntrinsic(
Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6085 case Intrinsic::aarch64_sve_fcvtzu_x4:
6086 SelectCVTIntrinsic(
Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6088 case Intrinsic::aarch64_sve_ucvtf_x4:
6089 SelectCVTIntrinsic(
Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6091 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6092 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6094 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6095 SelectUnaryMultiIntrinsic(
Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6097 case Intrinsic::aarch64_sve_sclamp_single_x2:
6098 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6099 Node->getValueType(0),
6100 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6101 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6102 SelectClamp(
Node, 2,
Op);
6104 case Intrinsic::aarch64_sve_uclamp_single_x2:
6105 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6106 Node->getValueType(0),
6107 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6108 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6109 SelectClamp(
Node, 2,
Op);
6111 case Intrinsic::aarch64_sve_fclamp_single_x2:
6112 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6113 Node->getValueType(0),
6114 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6115 AArch64::FCLAMP_VG2_2Z2Z_D}))
6116 SelectClamp(
Node, 2,
Op);
6118 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6119 SelectClamp(
Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6121 case Intrinsic::aarch64_sve_sclamp_single_x4:
6122 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6123 Node->getValueType(0),
6124 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6125 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6126 SelectClamp(
Node, 4,
Op);
6128 case Intrinsic::aarch64_sve_uclamp_single_x4:
6129 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6130 Node->getValueType(0),
6131 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6132 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6133 SelectClamp(
Node, 4,
Op);
6135 case Intrinsic::aarch64_sve_fclamp_single_x4:
6136 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::FP>(
6137 Node->getValueType(0),
6138 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6139 AArch64::FCLAMP_VG4_4Z4Z_D}))
6140 SelectClamp(
Node, 4,
Op);
6142 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6143 SelectClamp(
Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6145 case Intrinsic::aarch64_sve_add_single_x2:
6146 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6147 Node->getValueType(0),
6148 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6149 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6150 SelectDestructiveMultiIntrinsic(
Node, 2,
false,
Op);
6152 case Intrinsic::aarch64_sve_add_single_x4:
6153 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6154 Node->getValueType(0),
6155 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6156 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6157 SelectDestructiveMultiIntrinsic(
Node, 4,
false,
Op);
6159 case Intrinsic::aarch64_sve_zip_x2:
6160 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6161 Node->getValueType(0),
6162 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6163 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6164 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6166 case Intrinsic::aarch64_sve_zipq_x2:
6167 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6168 AArch64::ZIP_VG2_2ZZZ_Q);
6170 case Intrinsic::aarch64_sve_zip_x4:
6171 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6172 Node->getValueType(0),
6173 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6174 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6175 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6177 case Intrinsic::aarch64_sve_zipq_x4:
6178 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6179 AArch64::ZIP_VG4_4Z4Z_Q);
6181 case Intrinsic::aarch64_sve_uzp_x2:
6182 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6183 Node->getValueType(0),
6184 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6185 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6186 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6188 case Intrinsic::aarch64_sve_uzpq_x2:
6189 SelectUnaryMultiIntrinsic(
Node, 2,
false,
6190 AArch64::UZP_VG2_2ZZZ_Q);
6192 case Intrinsic::aarch64_sve_uzp_x4:
6193 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6194 Node->getValueType(0),
6195 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6196 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6197 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6199 case Intrinsic::aarch64_sve_uzpq_x4:
6200 SelectUnaryMultiIntrinsic(
Node, 4,
true,
6201 AArch64::UZP_VG4_4Z4Z_Q);
6203 case Intrinsic::aarch64_sve_sel_x2:
6204 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6205 Node->getValueType(0),
6206 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6207 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6208 SelectDestructiveMultiIntrinsic(
Node, 2,
true,
Op,
true);
6210 case Intrinsic::aarch64_sve_sel_x4:
6211 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6212 Node->getValueType(0),
6213 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6214 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6215 SelectDestructiveMultiIntrinsic(
Node, 4,
true,
Op,
true);
6217 case Intrinsic::aarch64_sve_frinta_x2:
6218 SelectFrintFromVT(
Node, 2, AArch64::FRINTA_2Z2Z_S);
6220 case Intrinsic::aarch64_sve_frinta_x4:
6221 SelectFrintFromVT(
Node, 4, AArch64::FRINTA_4Z4Z_S);
6223 case Intrinsic::aarch64_sve_frintm_x2:
6224 SelectFrintFromVT(
Node, 2, AArch64::FRINTM_2Z2Z_S);
6226 case Intrinsic::aarch64_sve_frintm_x4:
6227 SelectFrintFromVT(
Node, 4, AArch64::FRINTM_4Z4Z_S);
6229 case Intrinsic::aarch64_sve_frintn_x2:
6230 SelectFrintFromVT(
Node, 2, AArch64::FRINTN_2Z2Z_S);
6232 case Intrinsic::aarch64_sve_frintn_x4:
6233 SelectFrintFromVT(
Node, 4, AArch64::FRINTN_4Z4Z_S);
6235 case Intrinsic::aarch64_sve_frintp_x2:
6236 SelectFrintFromVT(
Node, 2, AArch64::FRINTP_2Z2Z_S);
6238 case Intrinsic::aarch64_sve_frintp_x4:
6239 SelectFrintFromVT(
Node, 4, AArch64::FRINTP_4Z4Z_S);
6241 case Intrinsic::aarch64_sve_sunpk_x2:
6242 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6243 Node->getValueType(0),
6244 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6245 AArch64::SUNPK_VG2_2ZZ_D}))
6246 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6248 case Intrinsic::aarch64_sve_uunpk_x2:
6249 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6250 Node->getValueType(0),
6251 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6252 AArch64::UUNPK_VG2_2ZZ_D}))
6253 SelectUnaryMultiIntrinsic(
Node, 2,
false,
Op);
6255 case Intrinsic::aarch64_sve_sunpk_x4:
6256 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6257 Node->getValueType(0),
6258 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6259 AArch64::SUNPK_VG4_4Z2Z_D}))
6260 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6262 case Intrinsic::aarch64_sve_uunpk_x4:
6263 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::Int>(
6264 Node->getValueType(0),
6265 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6266 AArch64::UUNPK_VG4_4Z2Z_D}))
6267 SelectUnaryMultiIntrinsic(
Node, 4,
true,
Op);
6269 case Intrinsic::aarch64_sve_pext_x2: {
6270 if (
auto Op = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
6271 Node->getValueType(0),
6272 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6273 AArch64::PEXT_2PCI_D}))
6274 SelectPExtPair(
Node,
Op);
6281 unsigned IntNo =
Node->getConstantOperandVal(1);
6282 if (
Node->getNumOperands() >= 3)
6283 VT =
Node->getOperand(2)->getValueType(0);
6287 case Intrinsic::aarch64_neon_st1x2: {
6288 if (VT == MVT::v8i8) {
6289 SelectStore(
Node, 2, AArch64::ST1Twov8b);
6291 }
else if (VT == MVT::v16i8) {
6292 SelectStore(
Node, 2, AArch64::ST1Twov16b);
6294 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6295 VT == MVT::v4bf16) {
6296 SelectStore(
Node, 2, AArch64::ST1Twov4h);
6298 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6299 VT == MVT::v8bf16) {
6300 SelectStore(
Node, 2, AArch64::ST1Twov8h);
6302 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6303 SelectStore(
Node, 2, AArch64::ST1Twov2s);
6305 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6306 SelectStore(
Node, 2, AArch64::ST1Twov4s);
6308 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6309 SelectStore(
Node, 2, AArch64::ST1Twov2d);
6311 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6312 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6317 case Intrinsic::aarch64_neon_st1x3: {
6318 if (VT == MVT::v8i8) {
6319 SelectStore(
Node, 3, AArch64::ST1Threev8b);
6321 }
else if (VT == MVT::v16i8) {
6322 SelectStore(
Node, 3, AArch64::ST1Threev16b);
6324 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6325 VT == MVT::v4bf16) {
6326 SelectStore(
Node, 3, AArch64::ST1Threev4h);
6328 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6329 VT == MVT::v8bf16) {
6330 SelectStore(
Node, 3, AArch64::ST1Threev8h);
6332 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6333 SelectStore(
Node, 3, AArch64::ST1Threev2s);
6335 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6336 SelectStore(
Node, 3, AArch64::ST1Threev4s);
6338 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6339 SelectStore(
Node, 3, AArch64::ST1Threev2d);
6341 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6342 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6347 case Intrinsic::aarch64_neon_st1x4: {
6348 if (VT == MVT::v8i8) {
6349 SelectStore(
Node, 4, AArch64::ST1Fourv8b);
6351 }
else if (VT == MVT::v16i8) {
6352 SelectStore(
Node, 4, AArch64::ST1Fourv16b);
6354 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6355 VT == MVT::v4bf16) {
6356 SelectStore(
Node, 4, AArch64::ST1Fourv4h);
6358 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6359 VT == MVT::v8bf16) {
6360 SelectStore(
Node, 4, AArch64::ST1Fourv8h);
6362 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6363 SelectStore(
Node, 4, AArch64::ST1Fourv2s);
6365 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6366 SelectStore(
Node, 4, AArch64::ST1Fourv4s);
6368 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6369 SelectStore(
Node, 4, AArch64::ST1Fourv2d);
6371 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6372 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6377 case Intrinsic::aarch64_neon_st2: {
6378 if (VT == MVT::v8i8) {
6379 SelectStore(
Node, 2, AArch64::ST2Twov8b);
6381 }
else if (VT == MVT::v16i8) {
6382 SelectStore(
Node, 2, AArch64::ST2Twov16b);
6384 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6385 VT == MVT::v4bf16) {
6386 SelectStore(
Node, 2, AArch64::ST2Twov4h);
6388 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6389 VT == MVT::v8bf16) {
6390 SelectStore(
Node, 2, AArch64::ST2Twov8h);
6392 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6393 SelectStore(
Node, 2, AArch64::ST2Twov2s);
6395 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6396 SelectStore(
Node, 2, AArch64::ST2Twov4s);
6398 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6399 SelectStore(
Node, 2, AArch64::ST2Twov2d);
6401 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6402 SelectStore(
Node, 2, AArch64::ST1Twov1d);
6407 case Intrinsic::aarch64_neon_st3: {
6408 if (VT == MVT::v8i8) {
6409 SelectStore(
Node, 3, AArch64::ST3Threev8b);
6411 }
else if (VT == MVT::v16i8) {
6412 SelectStore(
Node, 3, AArch64::ST3Threev16b);
6414 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6415 VT == MVT::v4bf16) {
6416 SelectStore(
Node, 3, AArch64::ST3Threev4h);
6418 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6419 VT == MVT::v8bf16) {
6420 SelectStore(
Node, 3, AArch64::ST3Threev8h);
6422 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6423 SelectStore(
Node, 3, AArch64::ST3Threev2s);
6425 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6426 SelectStore(
Node, 3, AArch64::ST3Threev4s);
6428 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6429 SelectStore(
Node, 3, AArch64::ST3Threev2d);
6431 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6432 SelectStore(
Node, 3, AArch64::ST1Threev1d);
6437 case Intrinsic::aarch64_neon_st4: {
6438 if (VT == MVT::v8i8) {
6439 SelectStore(
Node, 4, AArch64::ST4Fourv8b);
6441 }
else if (VT == MVT::v16i8) {
6442 SelectStore(
Node, 4, AArch64::ST4Fourv16b);
6444 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6445 VT == MVT::v4bf16) {
6446 SelectStore(
Node, 4, AArch64::ST4Fourv4h);
6448 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6449 VT == MVT::v8bf16) {
6450 SelectStore(
Node, 4, AArch64::ST4Fourv8h);
6452 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6453 SelectStore(
Node, 4, AArch64::ST4Fourv2s);
6455 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6456 SelectStore(
Node, 4, AArch64::ST4Fourv4s);
6458 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6459 SelectStore(
Node, 4, AArch64::ST4Fourv2d);
6461 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6462 SelectStore(
Node, 4, AArch64::ST1Fourv1d);
6467 case Intrinsic::aarch64_neon_st2lane: {
6468 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6469 SelectStoreLane(
Node, 2, AArch64::ST2i8);
6471 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6472 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6473 SelectStoreLane(
Node, 2, AArch64::ST2i16);
6475 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6477 SelectStoreLane(
Node, 2, AArch64::ST2i32);
6479 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6481 SelectStoreLane(
Node, 2, AArch64::ST2i64);
6486 case Intrinsic::aarch64_neon_st3lane: {
6487 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6488 SelectStoreLane(
Node, 3, AArch64::ST3i8);
6490 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6491 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6492 SelectStoreLane(
Node, 3, AArch64::ST3i16);
6494 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6496 SelectStoreLane(
Node, 3, AArch64::ST3i32);
6498 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6500 SelectStoreLane(
Node, 3, AArch64::ST3i64);
6505 case Intrinsic::aarch64_neon_st4lane: {
6506 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6507 SelectStoreLane(
Node, 4, AArch64::ST4i8);
6509 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6510 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6511 SelectStoreLane(
Node, 4, AArch64::ST4i16);
6513 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6515 SelectStoreLane(
Node, 4, AArch64::ST4i32);
6517 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6519 SelectStoreLane(
Node, 4, AArch64::ST4i64);
6524 case Intrinsic::aarch64_sve_st2q: {
6525 SelectPredicatedStore(
Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6528 case Intrinsic::aarch64_sve_st3q: {
6529 SelectPredicatedStore(
Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6532 case Intrinsic::aarch64_sve_st4q: {
6533 SelectPredicatedStore(
Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6536 case Intrinsic::aarch64_sve_st2: {
6537 if (VT == MVT::nxv16i8) {
6538 SelectPredicatedStore(
Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6540 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6541 VT == MVT::nxv8bf16) {
6542 SelectPredicatedStore(
Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6544 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6545 SelectPredicatedStore(
Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6547 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6548 SelectPredicatedStore(
Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6553 case Intrinsic::aarch64_sve_st3: {
6554 if (VT == MVT::nxv16i8) {
6555 SelectPredicatedStore(
Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6557 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6558 VT == MVT::nxv8bf16) {
6559 SelectPredicatedStore(
Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6561 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6562 SelectPredicatedStore(
Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6564 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6565 SelectPredicatedStore(
Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6570 case Intrinsic::aarch64_sve_st4: {
6571 if (VT == MVT::nxv16i8) {
6572 SelectPredicatedStore(
Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6574 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6575 VT == MVT::nxv8bf16) {
6576 SelectPredicatedStore(
Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6578 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6579 SelectPredicatedStore(
Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6581 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6582 SelectPredicatedStore(
Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6591 if (VT == MVT::v8i8) {
6592 SelectPostLoad(
Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6594 }
else if (VT == MVT::v16i8) {
6595 SelectPostLoad(
Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6597 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6598 SelectPostLoad(
Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6600 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6601 SelectPostLoad(
Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6603 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6604 SelectPostLoad(
Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6606 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6607 SelectPostLoad(
Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6609 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6610 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6612 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6613 SelectPostLoad(
Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6619 if (VT == MVT::v8i8) {
6620 SelectPostLoad(
Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6622 }
else if (VT == MVT::v16i8) {
6623 SelectPostLoad(
Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6625 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6626 SelectPostLoad(
Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6628 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6629 SelectPostLoad(
Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6631 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6632 SelectPostLoad(
Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6634 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6635 SelectPostLoad(
Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6637 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6638 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6640 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6641 SelectPostLoad(
Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6647 if (VT == MVT::v8i8) {
6648 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6650 }
else if (VT == MVT::v16i8) {
6651 SelectPostLoad(
Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6653 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6654 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6656 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6657 SelectPostLoad(
Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6659 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6660 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6662 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6663 SelectPostLoad(
Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6665 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6666 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6668 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6669 SelectPostLoad(
Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6675 if (VT == MVT::v8i8) {
6676 SelectPostLoad(
Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6678 }
else if (VT == MVT::v16i8) {
6679 SelectPostLoad(
Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6681 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6682 SelectPostLoad(
Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6684 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6685 SelectPostLoad(
Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6687 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6688 SelectPostLoad(
Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6690 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6691 SelectPostLoad(
Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6693 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6694 SelectPostLoad(
Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6696 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6697 SelectPostLoad(
Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
6703 if (VT == MVT::v8i8) {
6704 SelectPostLoad(
Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
6706 }
else if (VT == MVT::v16i8) {
6707 SelectPostLoad(
Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
6709 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6710 SelectPostLoad(
Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
6712 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6713 SelectPostLoad(
Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
6715 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6716 SelectPostLoad(
Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
6718 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6719 SelectPostLoad(
Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
6721 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6722 SelectPostLoad(
Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6724 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6725 SelectPostLoad(
Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
6731 if (VT == MVT::v8i8) {
6732 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
6734 }
else if (VT == MVT::v16i8) {
6735 SelectPostLoad(
Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
6737 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6738 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
6740 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6741 SelectPostLoad(
Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
6743 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6744 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
6746 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6747 SelectPostLoad(
Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
6749 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6750 SelectPostLoad(
Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6752 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6753 SelectPostLoad(
Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
6759 if (VT == MVT::v8i8) {
6760 SelectPostLoad(
Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
6762 }
else if (VT == MVT::v16i8) {
6763 SelectPostLoad(
Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
6765 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6766 SelectPostLoad(
Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
6768 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6769 SelectPostLoad(
Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
6771 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6772 SelectPostLoad(
Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
6774 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6775 SelectPostLoad(
Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
6777 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6778 SelectPostLoad(
Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
6780 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6781 SelectPostLoad(
Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
6787 if (VT == MVT::v8i8) {
6788 SelectPostLoad(
Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
6790 }
else if (VT == MVT::v16i8) {
6791 SelectPostLoad(
Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
6793 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6794 SelectPostLoad(
Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
6796 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6797 SelectPostLoad(
Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
6799 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6800 SelectPostLoad(
Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
6802 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6803 SelectPostLoad(
Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
6805 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6806 SelectPostLoad(
Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
6808 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6809 SelectPostLoad(
Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
6815 if (VT == MVT::v8i8) {
6816 SelectPostLoad(
Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
6818 }
else if (VT == MVT::v16i8) {
6819 SelectPostLoad(
Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
6821 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6822 SelectPostLoad(
Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
6824 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6825 SelectPostLoad(
Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
6827 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6828 SelectPostLoad(
Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
6830 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6831 SelectPostLoad(
Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
6833 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6834 SelectPostLoad(
Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
6836 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6837 SelectPostLoad(
Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
6843 if (VT == MVT::v8i8) {
6844 SelectPostLoad(
Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
6846 }
else if (VT == MVT::v16i8) {
6847 SelectPostLoad(
Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
6849 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6850 SelectPostLoad(
Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
6852 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6853 SelectPostLoad(
Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
6855 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6856 SelectPostLoad(
Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
6858 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6859 SelectPostLoad(
Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
6861 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6862 SelectPostLoad(
Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
6864 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6865 SelectPostLoad(
Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
6871 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6872 SelectPostLoadLane(
Node, 1, AArch64::LD1i8_POST);
6874 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6875 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6876 SelectPostLoadLane(
Node, 1, AArch64::LD1i16_POST);
6878 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6880 SelectPostLoadLane(
Node, 1, AArch64::LD1i32_POST);
6882 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6884 SelectPostLoadLane(
Node, 1, AArch64::LD1i64_POST);
6890 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6891 SelectPostLoadLane(
Node, 2, AArch64::LD2i8_POST);
6893 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6894 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6895 SelectPostLoadLane(
Node, 2, AArch64::LD2i16_POST);
6897 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6899 SelectPostLoadLane(
Node, 2, AArch64::LD2i32_POST);
6901 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6903 SelectPostLoadLane(
Node, 2, AArch64::LD2i64_POST);
6909 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6910 SelectPostLoadLane(
Node, 3, AArch64::LD3i8_POST);
6912 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6913 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6914 SelectPostLoadLane(
Node, 3, AArch64::LD3i16_POST);
6916 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6918 SelectPostLoadLane(
Node, 3, AArch64::LD3i32_POST);
6920 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6922 SelectPostLoadLane(
Node, 3, AArch64::LD3i64_POST);
6928 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6929 SelectPostLoadLane(
Node, 4, AArch64::LD4i8_POST);
6931 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6932 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6933 SelectPostLoadLane(
Node, 4, AArch64::LD4i16_POST);
6935 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6937 SelectPostLoadLane(
Node, 4, AArch64::LD4i32_POST);
6939 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6941 SelectPostLoadLane(
Node, 4, AArch64::LD4i64_POST);
6947 VT =
Node->getOperand(1).getValueType();
6948 if (VT == MVT::v8i8) {
6949 SelectPostStore(
Node, 2, AArch64::ST2Twov8b_POST);
6951 }
else if (VT == MVT::v16i8) {
6952 SelectPostStore(
Node, 2, AArch64::ST2Twov16b_POST);
6954 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6955 SelectPostStore(
Node, 2, AArch64::ST2Twov4h_POST);
6957 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6958 SelectPostStore(
Node, 2, AArch64::ST2Twov8h_POST);
6960 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6961 SelectPostStore(
Node, 2, AArch64::ST2Twov2s_POST);
6963 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6964 SelectPostStore(
Node, 2, AArch64::ST2Twov4s_POST);
6966 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6967 SelectPostStore(
Node, 2, AArch64::ST2Twov2d_POST);
6969 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6970 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
6976 VT =
Node->getOperand(1).getValueType();
6977 if (VT == MVT::v8i8) {
6978 SelectPostStore(
Node, 3, AArch64::ST3Threev8b_POST);
6980 }
else if (VT == MVT::v16i8) {
6981 SelectPostStore(
Node, 3, AArch64::ST3Threev16b_POST);
6983 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6984 SelectPostStore(
Node, 3, AArch64::ST3Threev4h_POST);
6986 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6987 SelectPostStore(
Node, 3, AArch64::ST3Threev8h_POST);
6989 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6990 SelectPostStore(
Node, 3, AArch64::ST3Threev2s_POST);
6992 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6993 SelectPostStore(
Node, 3, AArch64::ST3Threev4s_POST);
6995 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6996 SelectPostStore(
Node, 3, AArch64::ST3Threev2d_POST);
6998 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6999 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7005 VT =
Node->getOperand(1).getValueType();
7006 if (VT == MVT::v8i8) {
7007 SelectPostStore(
Node, 4, AArch64::ST4Fourv8b_POST);
7009 }
else if (VT == MVT::v16i8) {
7010 SelectPostStore(
Node, 4, AArch64::ST4Fourv16b_POST);
7012 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7013 SelectPostStore(
Node, 4, AArch64::ST4Fourv4h_POST);
7015 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7016 SelectPostStore(
Node, 4, AArch64::ST4Fourv8h_POST);
7018 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7019 SelectPostStore(
Node, 4, AArch64::ST4Fourv2s_POST);
7021 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7022 SelectPostStore(
Node, 4, AArch64::ST4Fourv4s_POST);
7024 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7025 SelectPostStore(
Node, 4, AArch64::ST4Fourv2d_POST);
7027 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7028 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7034 VT =
Node->getOperand(1).getValueType();
7035 if (VT == MVT::v8i8) {
7036 SelectPostStore(
Node, 2, AArch64::ST1Twov8b_POST);
7038 }
else if (VT == MVT::v16i8) {
7039 SelectPostStore(
Node, 2, AArch64::ST1Twov16b_POST);
7041 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7042 SelectPostStore(
Node, 2, AArch64::ST1Twov4h_POST);
7044 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7045 SelectPostStore(
Node, 2, AArch64::ST1Twov8h_POST);
7047 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7048 SelectPostStore(
Node, 2, AArch64::ST1Twov2s_POST);
7050 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7051 SelectPostStore(
Node, 2, AArch64::ST1Twov4s_POST);
7053 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7054 SelectPostStore(
Node, 2, AArch64::ST1Twov1d_POST);
7056 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7057 SelectPostStore(
Node, 2, AArch64::ST1Twov2d_POST);
7063 VT =
Node->getOperand(1).getValueType();
7064 if (VT == MVT::v8i8) {
7065 SelectPostStore(
Node, 3, AArch64::ST1Threev8b_POST);
7067 }
else if (VT == MVT::v16i8) {
7068 SelectPostStore(
Node, 3, AArch64::ST1Threev16b_POST);
7070 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7071 SelectPostStore(
Node, 3, AArch64::ST1Threev4h_POST);
7073 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7074 SelectPostStore(
Node, 3, AArch64::ST1Threev8h_POST);
7076 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7077 SelectPostStore(
Node, 3, AArch64::ST1Threev2s_POST);
7079 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7080 SelectPostStore(
Node, 3, AArch64::ST1Threev4s_POST);
7082 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7083 SelectPostStore(
Node, 3, AArch64::ST1Threev1d_POST);
7085 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7086 SelectPostStore(
Node, 3, AArch64::ST1Threev2d_POST);
7092 VT =
Node->getOperand(1).getValueType();
7093 if (VT == MVT::v8i8) {
7094 SelectPostStore(
Node, 4, AArch64::ST1Fourv8b_POST);
7096 }
else if (VT == MVT::v16i8) {
7097 SelectPostStore(
Node, 4, AArch64::ST1Fourv16b_POST);
7099 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7100 SelectPostStore(
Node, 4, AArch64::ST1Fourv4h_POST);
7102 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7103 SelectPostStore(
Node, 4, AArch64::ST1Fourv8h_POST);
7105 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7106 SelectPostStore(
Node, 4, AArch64::ST1Fourv2s_POST);
7108 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7109 SelectPostStore(
Node, 4, AArch64::ST1Fourv4s_POST);
7111 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7112 SelectPostStore(
Node, 4, AArch64::ST1Fourv1d_POST);
7114 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7115 SelectPostStore(
Node, 4, AArch64::ST1Fourv2d_POST);
7121 VT =
Node->getOperand(1).getValueType();
7122 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7123 SelectPostStoreLane(
Node, 2, AArch64::ST2i8_POST);
7125 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7126 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7127 SelectPostStoreLane(
Node, 2, AArch64::ST2i16_POST);
7129 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7131 SelectPostStoreLane(
Node, 2, AArch64::ST2i32_POST);
7133 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7135 SelectPostStoreLane(
Node, 2, AArch64::ST2i64_POST);
7141 VT =
Node->getOperand(1).getValueType();
7142 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7143 SelectPostStoreLane(
Node, 3, AArch64::ST3i8_POST);
7145 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7146 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7147 SelectPostStoreLane(
Node, 3, AArch64::ST3i16_POST);
7149 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7151 SelectPostStoreLane(
Node, 3, AArch64::ST3i32_POST);
7153 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7155 SelectPostStoreLane(
Node, 3, AArch64::ST3i64_POST);
7161 VT =
Node->getOperand(1).getValueType();
7162 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7163 SelectPostStoreLane(
Node, 4, AArch64::ST4i8_POST);
7165 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7166 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7167 SelectPostStoreLane(
Node, 4, AArch64::ST4i16_POST);
7169 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7171 SelectPostStoreLane(
Node, 4, AArch64::ST4i32_POST);
7173 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7175 SelectPostStoreLane(
Node, 4, AArch64::ST4i64_POST);
7181 if (VT == MVT::nxv16i8) {
7182 SelectPredicatedLoad(
Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B);
7184 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7185 VT == MVT::nxv8bf16) {
7186 SelectPredicatedLoad(
Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H);
7188 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7189 SelectPredicatedLoad(
Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W);
7191 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7192 SelectPredicatedLoad(
Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D);
7198 if (VT == MVT::nxv16i8) {
7199 SelectPredicatedLoad(
Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B);
7201 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7202 VT == MVT::nxv8bf16) {
7203 SelectPredicatedLoad(
Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H);
7205 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7206 SelectPredicatedLoad(
Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W);
7208 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7209 SelectPredicatedLoad(
Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D);
7215 if (VT == MVT::nxv16i8) {
7216 SelectPredicatedLoad(
Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B);
7218 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7219 VT == MVT::nxv8bf16) {
7220 SelectPredicatedLoad(
Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H);
7222 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7223 SelectPredicatedLoad(
Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W);
7225 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7226 SelectPredicatedLoad(
Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D);
7241 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7253 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7257 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7258 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7272 if (isa<MemSDNode>(Root))
7273 return cast<MemSDNode>(Root)->getMemoryVT();
7275 if (isa<MemIntrinsicSDNode>(Root))
7276 return cast<MemIntrinsicSDNode>(Root)->getMemoryVT();
7278 const unsigned Opcode = Root->
getOpcode();
7286 return cast<VTSDNode>(Root->
getOperand(3))->getVT();
7288 return cast<VTSDNode>(Root->
getOperand(4))->getVT();
7308 case Intrinsic::aarch64_sme_ldr:
7309 case Intrinsic::aarch64_sme_str:
7310 return MVT::nxv16i8;
7311 case Intrinsic::aarch64_sve_prf:
7316 case Intrinsic::aarch64_sve_ld2_sret:
7317 case Intrinsic::aarch64_sve_ld2q_sret:
7320 case Intrinsic::aarch64_sve_st2q:
7323 case Intrinsic::aarch64_sve_ld3_sret:
7324 case Intrinsic::aarch64_sve_ld3q_sret:
7327 case Intrinsic::aarch64_sve_st3q:
7330 case Intrinsic::aarch64_sve_ld4_sret:
7331 case Intrinsic::aarch64_sve_ld4q_sret:
7334 case Intrinsic::aarch64_sve_st4q:
7337 case Intrinsic::aarch64_sve_ld1udq:
7338 case Intrinsic::aarch64_sve_st1dq:
7339 return EVT(MVT::nxv1i64);
7340 case Intrinsic::aarch64_sve_ld1uwq:
7341 case Intrinsic::aarch64_sve_st1wq:
7342 return EVT(MVT::nxv1i32);
7349template <
int64_t Min,
int64_t Max>
7350bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(
SDNode *Root,
SDValue N,
7358 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
7363 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
7382 int64_t MulImm = cast<ConstantSDNode>(VScale.
getOperand(0))->getSExtValue();
7384 if ((MulImm % MemWidthBytes) != 0)
7387 int64_t
Offset = MulImm / MemWidthBytes;
7388 if (Offset < Min || Offset > Max)
7391 Base =
N.getOperand(0);
7393 int FI = cast<FrameIndexSDNode>(
Base)->getIndex();
7400 OffImm = CurDAG->getTargetConstant(
Offset,
SDLoc(
N), MVT::i64);
7406bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7424 if (
auto C = dyn_cast<ConstantSDNode>(RHS)) {
7425 int64_t ImmOff =
C->getSExtValue();
7426 unsigned Size = 1 << Scale;
7435 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7437 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64, Ops);
7447 if (
auto *
C = dyn_cast<ConstantSDNode>(ShiftRHS))
7448 if (
C->getZExtValue() == Scale) {
7457bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7464bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7465 EVT VT =
N.getValueType();
7469bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7473 if (CurDAG->isBaseWithConstantOffset(
N))
7474 if (
auto C = dyn_cast<ConstantSDNode>(
N.getOperand(1))) {
7475 int64_t ImmOff =
C->getSExtValue();
7476 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0))) {
7477 Base =
N.getOperand(0);
7478 Offset = CurDAG->getTargetConstant(ImmOff / Scale,
SDLoc(
N), MVT::i64);
7485 Offset = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
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 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.
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
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
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.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
uint8_t getStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
A description of a memory reference used in the backend.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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),...
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,...
SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
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)
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.
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.
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)
const SysReg * lookupSysRegByName(StringRef)
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
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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...
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.
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.
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.
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,...
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
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
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 isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.