22#include "llvm/IR/IntrinsicsAArch64.h"
31#define DEBUG_TYPE "aarch64-isel"
32#define PASS_NAME "AArch64 Instruction Selection"
35#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
36#pragma inline_depth(0)
52 AArch64DAGToDAGISel() =
delete;
64 void PreprocessISelDAG()
override;
68 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
70 std::vector<SDValue> &OutOps)
override;
72 template <
signed Low,
signed High,
signed Scale>
75 template <
signed Low,
signed High>
83 return SelectShiftedRegister(
N,
false,
Reg, Shift);
86 return SelectShiftedRegister(
N,
true,
Reg, Shift);
89 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
92 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
95 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
98 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
101 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
104 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
107 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
110 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
113 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
116 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
119 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
122 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
125 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
128 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
131 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
134 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
137 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
139 template <
unsigned Size,
unsigned Max>
143 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
146 int64_t
C = CI->getSExtValue();
154 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
161 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
167 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
172 N =
N->getOperand(0);
176 EVT VT =
N->getValueType(0);
177 EVT LVT =
N->getOperand(0).getValueType();
178 unsigned Index =
N->getConstantOperandVal(1);
182 Res =
N->getOperand(0);
187 if (
N.getOpcode() != AArch64ISD::VLSHR)
190 EVT VT =
Op.getValueType();
191 unsigned ShtAmt =
N->getConstantOperandVal(1);
196 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
198 Op.getOperand(1).getConstantOperandVal(0)
199 <<
Op.getOperand(1).getConstantOperandVal(1));
200 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
203 Op.getOperand(1).getConstantOperandVal(0));
207 if (Imm != 1ULL << (ShtAmt - 1))
210 Res1 =
Op.getOperand(0);
211 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
215 bool SelectDupZeroOrUndef(
SDValue N) {
216 switch(
N->getOpcode()) {
219 case AArch64ISD::DUP:
221 auto Opnd0 =
N->getOperand(0);
235 bool SelectAny(
SDValue) {
return true; }
238 switch(
N->getOpcode()) {
239 case AArch64ISD::DUP:
241 auto Opnd0 =
N->getOperand(0);
253 template <MVT::SimpleValueType VT,
bool Negate>
255 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT>
265 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
268 template <MVT::SimpleValueType VT,
bool Invert = false>
270 return SelectSVELogicalImm(
N, VT, Imm, Invert);
273 template <MVT::SimpleValueType VT>
275 return SelectSVEArithImm(
N, VT, Imm);
278 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
280 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
287 EVT EltVT =
N->getValueType(0).getVectorElementType();
288 return SelectSVEShiftImm(
N->getOperand(0), 1,
294 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
301 MulImm = 1LL << MulImm;
303 if ((MulImm % std::abs(Scale)) != 0)
307 if ((MulImm >= Min) && (MulImm <= Max)) {
308 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
315 template <
signed Max,
signed Scale>
322 if (MulImm >= 0 && MulImm <= Max) {
324 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
331 template <
unsigned BaseReg,
unsigned Max>
339 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
362 const unsigned SubRegs[]);
364 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
366 bool tryIndexedLoad(
SDNode *
N);
368 void SelectPtrauthAuth(
SDNode *
N);
369 void SelectPtrauthResign(
SDNode *
N);
371 bool trySelectStackSlotTagP(
SDNode *
N);
374 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
376 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
378 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
380 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
381 unsigned Opc_rr,
unsigned Opc_ri,
382 bool IsIntr =
false);
383 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
384 unsigned Scale,
unsigned Opc_ri,
386 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
387 bool IsZmMulti,
unsigned Opcode,
388 bool HasPred =
false);
390 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
391 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
394 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
395 bool IsTupleInput,
unsigned Opc);
396 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 template <
unsigned MaxIdx,
unsigned Scale>
399 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
401 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
402 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
403 unsigned BaseReg = 0);
406 template <
int64_t Min,
int64_t Max>
410 template <
unsigned Scale>
412 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
415 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
418 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
420 template <
unsigned MaxIdx,
unsigned Scale>
425 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
429 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
430 unsigned Opc_rr,
unsigned Opc_ri);
431 std::tuple<unsigned, SDValue, SDValue>
432 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
436 bool tryBitfieldExtractOp(
SDNode *
N);
437 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
438 bool tryBitfieldInsertOp(
SDNode *
N);
439 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
440 bool tryShiftAmountMod(
SDNode *
N);
442 bool tryReadRegister(
SDNode *
N);
443 bool tryWriteRegister(
SDNode *
N);
445 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
446 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
451#include "AArch64GenDAGISel.inc"
459 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
461 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
474 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
475 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
476 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
479 template<
unsigned RegW
idth>
481 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
483 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
485 template <
unsigned RegW
idth>
487 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
489 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
491 template<
unsigned RegW
idth>
493 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
499 bool SelectCMP_SWAP(
SDNode *
N);
510 bool AllowSaturation,
SDValue &Imm);
518 bool SelectAllActivePredicate(
SDValue N);
523 template <
bool MatchCBB>
533 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
537char AArch64DAGToDAGISelLegacy::ID = 0;
545 auto getFloatVT = [&](
EVT VT) {
547 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
548 return VT.changeElementType(*(DAG.getContext()),
549 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
554 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
555 auto bitcasted = DAG.getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
559 EVT OrigVT =
N.getValueType(0);
561 return DAG.getBitcast(OrigVT, OpNode);
568 Imm =
C->getZExtValue();
585 return N->getOpcode() ==
Opc &&
596 return Imm == ImmExpected;
600bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
602 std::vector<SDValue> &OutOps) {
603 switch(ConstraintID) {
606 case InlineAsm::ConstraintCode::m:
607 case InlineAsm::ConstraintCode::o:
608 case InlineAsm::ConstraintCode::Q:
612 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
614 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
616 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
617 dl,
Op.getValueType(),
619 OutOps.push_back(NewOp);
638 uint64_t Immed =
N.getNode()->getAsZExtVal();
641 if (Immed >> 12 == 0) {
643 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
651 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
652 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
669 uint64_t Immed =
N.getNode()->getAsZExtVal();
677 if (
N.getValueType() == MVT::i32)
678 Immed = ~((uint32_t)Immed) + 1;
680 Immed = ~Immed + 1ULL;
681 if (Immed & 0xFFFFFFFFFF000000ULL)
684 Immed &= 0xFFFFFFULL;
685 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
692 switch (
N.getOpcode()) {
718 unsigned ShiftVal = CSD->getZExtValue();
736bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
739 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
744 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
768 EVT VT =
N.getValueType();
769 if (VT != MVT::i32 && VT != MVT::i64)
772 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
778 unsigned LHSOpcode =
LHS->getOpcode();
792 unsigned LowZBits, MaskLen;
796 unsigned BitWidth =
N.getValueSizeInBits();
803 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
806 NewShiftC = LowZBits - ShiftAmtC;
807 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
813 NewShiftC = LowZBits + ShiftAmtC;
826 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
828 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
832 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
834 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
835 NewShiftAmt, BitWidthMinus1),
838 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
852 SrcVT =
N.getOperand(0).getValueType();
854 if (!IsLoadStore && SrcVT == MVT::i8)
856 else if (!IsLoadStore && SrcVT == MVT::i16)
858 else if (SrcVT == MVT::i32)
860 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
865 EVT SrcVT =
N.getOperand(0).getValueType();
866 if (!IsLoadStore && SrcVT == MVT::i8)
868 else if (!IsLoadStore && SrcVT == MVT::i16)
870 else if (SrcVT == MVT::i32)
872 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
900bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
903 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
908 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
909 V.getConstantOperandVal(1) <= 4 &&
922bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
924 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
934 unsigned BitSize =
N.getValueSizeInBits();
935 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
938 Reg =
N.getOperand(0);
939 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
940 return isWorthFoldingALU(
N,
true);
951 if (
N.getValueType() == MVT::i32)
959template<
signed Low,
signed High,
signed Scale>
965 if ((MulImm % std::abs(Scale)) == 0) {
966 int64_t RDVLImm = MulImm / Scale;
967 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
968 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
977template <
signed Low,
signed High>
978bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
983 if (MulImm >=
Low && MulImm <=
High) {
984 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
995 unsigned ShiftVal = 0;
1010 Reg =
N.getOperand(0).getOperand(0);
1022 Op =
Op->getOperand(0);
1024 Op.getOperand(0).getValueType().isFixedLengthVector())
1028 Reg =
N.getOperand(0);
1033 unsigned Opc =
N.getOpcode();
1051 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1053 return isWorthFoldingALU(
N);
1060 unsigned ShiftVal = 0;
1074 Reg =
N.getOperand(0);
1075 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1077 return isWorthFoldingALU(
N);
1086 for (
auto *
User :
N->users()) {
1113bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1114 unsigned BW,
unsigned Size,
1118 const DataLayout &
DL = CurDAG->getDataLayout();
1119 const TargetLowering *TLI = getTargetLowering();
1123 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1129 if (CurDAG->isBaseWithConstantOffset(
N)) {
1132 int64_t RHSC =
RHS->getSExtValue();
1134 int64_t
Range = 0x1LL << (BW - 1);
1136 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1137 RHSC < (
Range << Scale)) {
1138 Base =
N.getOperand(0);
1143 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1148 uint64_t RHSC =
RHS->getZExtValue();
1150 uint64_t
Range = 0x1ULL << BW;
1152 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1153 Base =
N.getOperand(0);
1158 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1169 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1176bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1179 const DataLayout &
DL = CurDAG->getDataLayout();
1180 const TargetLowering *TLI = getTargetLowering();
1184 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1189 GlobalAddressSDNode *GAN =
1191 Base =
N.getOperand(0);
1201 if (CurDAG->isBaseWithConstantOffset(
N)) {
1203 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1206 Base =
N.getOperand(0);
1211 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1219 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1227 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1236bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1239 if (!CurDAG->isBaseWithConstantOffset(
N))
1242 int64_t RHSC =
RHS->getSExtValue();
1243 if (RHSC >= -256 && RHSC < 256) {
1244 Base =
N.getOperand(0);
1247 const TargetLowering *TLI = getTargetLowering();
1248 Base = CurDAG->getTargetFrameIndex(
1251 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1261 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1268bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1288 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1294 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1297 return isWorthFoldingAddr(
N,
Size);
1300bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1318 const SDNode *
Node =
N.getNode();
1319 for (SDNode *UI :
Node->users()) {
1325 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1328 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1331 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1336 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1339 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1344 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1348 if (IsExtendedRegisterWorthFolding &&
1355 if (isWorthFoldingAddr(
LHS,
Size))
1360 if (IsExtendedRegisterWorthFolding &&
1367 if (isWorthFoldingAddr(
RHS,
Size))
1379 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1382 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1384 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1385 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1389bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1402 const SDNode *
Node =
N.getNode();
1403 for (SDNode *UI :
Node->users()) {
1420 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1430 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1437 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1440 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1443 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1448 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1451 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1458 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1459 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1465 static const unsigned RegClassIDs[] = {
1466 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1467 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1468 AArch64::dsub2, AArch64::dsub3};
1474 static const unsigned RegClassIDs[] = {
1475 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1476 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1477 AArch64::qsub2, AArch64::qsub3};
1483 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1484 AArch64::ZPR3RegClassID,
1485 AArch64::ZPR4RegClassID};
1486 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1487 AArch64::zsub2, AArch64::zsub3};
1497 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1498 AArch64::ZPR4Mul4RegClassID};
1499 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1500 AArch64::zsub2, AArch64::zsub3};
1505 const unsigned RegClassIDs[],
1506 const unsigned SubRegs[]) {
1509 if (Regs.
size() == 1)
1520 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1523 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1524 Ops.push_back(Regs[i]);
1525 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1529 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1533void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1536 EVT VT =
N->getValueType(0);
1538 unsigned ExtOff = isExt;
1541 unsigned Vec0Off = ExtOff + 1;
1547 Ops.push_back(
N->getOperand(1));
1548 Ops.push_back(RegSeq);
1549 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1550 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1553static std::tuple<SDValue, SDValue>
1574 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1579 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1581 return std::make_tuple(
1586void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1591 SDValue AUTDisc =
N->getOperand(3);
1594 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1596 SDValue AUTAddrDisc, AUTConstDisc;
1597 std::tie(AUTConstDisc, AUTAddrDisc) =
1601 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1603 if (
N->getNumOperands() > 4)
1604 Ops.push_back(
N->getOperand(4));
1607 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1608 ReplaceNode(
N, AUT);
1610 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1611 AArch64::X16, Val,
SDValue());
1614 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1615 ReplaceNode(
N, AUT);
1619void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1629 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1634 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1635 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1637 SDValue AUTAddrDisc, AUTConstDisc;
1638 std::tie(AUTConstDisc, AUTAddrDisc) =
1641 SDValue PACAddrDisc, PACConstDisc;
1642 std::tie(PACConstDisc, PACAddrDisc) =
1645 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1646 AArch64::X16, Val,
SDValue());
1649 SDValue Addend =
N->getOperand(OffsetBase + 6);
1650 SDValue IncomingChain =
N->getOperand(0);
1651 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1652 PACKey, PACConstDisc, PACAddrDisc,
1653 Addend, IncomingChain, X16Copy.
getValue(1)};
1655 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1656 MVT::i64, MVT::Other,
Ops);
1657 ReplaceNode(
N, AUTRELLOADPAC);
1659 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1660 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1662 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1663 ReplaceNode(
N, AUTPAC);
1667bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1669 if (
LD->isUnindexed())
1671 EVT VT =
LD->getMemoryVT();
1672 EVT DstVT =
N->getValueType(0);
1676 int OffsetVal = (int)
OffsetOp->getZExtValue();
1681 unsigned Opcode = 0;
1684 bool InsertTo64 =
false;
1686 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1687 else if (VT == MVT::i32) {
1689 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1691 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1693 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1699 }
else if (VT == MVT::i16) {
1701 if (DstVT == MVT::i64)
1702 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1704 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1706 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1707 InsertTo64 = DstVT == MVT::i64;
1712 }
else if (VT == MVT::i8) {
1714 if (DstVT == MVT::i64)
1715 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1717 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1719 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1720 InsertTo64 = DstVT == MVT::i64;
1725 }
else if (VT == MVT::f16) {
1726 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1727 }
else if (VT == MVT::bf16) {
1728 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1729 }
else if (VT == MVT::f32) {
1730 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1731 }
else if (VT == MVT::f64 ||
1733 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1735 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1737 if (IsPre || OffsetVal != 8)
1741 Opcode = AArch64::LD1Onev8b_POST;
1744 Opcode = AArch64::LD1Onev4h_POST;
1747 Opcode = AArch64::LD1Onev2s_POST;
1750 Opcode = AArch64::LD1Onev1d_POST;
1756 if (IsPre || OffsetVal != 16)
1760 Opcode = AArch64::LD1Onev16b_POST;
1763 Opcode = AArch64::LD1Onev8h_POST;
1766 Opcode = AArch64::LD1Onev4s_POST;
1769 Opcode = AArch64::LD1Onev2d_POST;
1781 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1782 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1784 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1794 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1795 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1796 MVT::i64, LoadedVal,
SubReg),
1800 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1803 CurDAG->RemoveDeadNode(
N);
1807void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1808 unsigned SubRegIdx) {
1810 EVT VT =
N->getValueType(0);
1816 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1818 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1820 for (
unsigned i = 0; i < NumVecs; ++i)
1822 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1829 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1833 CurDAG->RemoveDeadNode(
N);
1836void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1837 unsigned Opc,
unsigned SubRegIdx) {
1839 EVT VT =
N->getValueType(0);
1846 const EVT ResTys[] = {MVT::i64,
1847 MVT::Untyped, MVT::Other};
1849 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1857 ReplaceUses(
SDValue(
N, 0), SuperReg);
1859 for (
unsigned i = 0; i < NumVecs; ++i)
1861 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1865 CurDAG->RemoveDeadNode(
N);
1871std::tuple<unsigned, SDValue, SDValue>
1872AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1878 SDValue NewOffset = OldOffset;
1880 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1881 N, OldBase, NewBase, NewOffset);
1885 const bool IsRegReg =
1886 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1889 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1902template <SelectTypeKind Kind>
1914 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1919 if (EltVT != MVT::i1)
1923 if (EltVT == MVT::bf16)
1925 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1955void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
1958 if (
Imm->getZExtValue() > 1)
1962 EVT VT =
N->getValueType(0);
1964 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1967 for (
unsigned I = 0;
I < 2; ++
I)
1968 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1969 AArch64::psub0 +
I,
DL, VT, SuperReg));
1971 CurDAG->RemoveDeadNode(
N);
1974void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
1976 EVT VT =
N->getValueType(0);
1980 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1983 for (
unsigned I = 0;
I < 2; ++
I)
1984 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1985 AArch64::psub0 +
I,
DL, VT, SuperReg));
1987 CurDAG->RemoveDeadNode(
N);
1990void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
1992 EVT VT =
N->getValueType(0);
1996 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
1998 for (
unsigned i = 0; i < NumVecs; ++i)
1999 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2000 AArch64::zsub0 + i,
DL, VT, SuperReg));
2002 CurDAG->RemoveDeadNode(
N);
2005void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2008 EVT VT =
N->getValueType(0);
2010 Ops.push_back(
N->getOperand(0));
2013 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2016 for (
unsigned i = 0; i < NumVecs; ++i)
2017 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2018 AArch64::zsub0 + i,
DL, VT, SuperReg));
2021 unsigned ChainIdx = NumVecs;
2023 CurDAG->RemoveDeadNode(
N);
2026void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2031 assert(Opcode != 0 &&
"Unexpected opcode");
2034 EVT VT =
N->getValueType(0);
2035 SDUse *OpsIter =
N->op_begin() + 1;
2038 auto GetMultiVecOperand = [&]() {
2041 return createZMulTuple(Regs);
2045 Ops.push_back(*OpsIter++);
2047 Ops.push_back(GetMultiVecOperand());
2049 Ops.push_back(GetMultiVecOperand());
2051 Ops.push_back(*OpsIter++);
2054 Ops.append(OpsIter,
N->op_end());
2056 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2058 for (
unsigned i = 0; i < NumVecs; ++i)
2059 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2060 AArch64::zsub0 + i,
DL, VT, SuperReg));
2062 CurDAG->RemoveDeadNode(
N);
2065void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2066 unsigned Scale,
unsigned Opc_ri,
2067 unsigned Opc_rr,
bool IsIntr) {
2068 assert(Scale < 5 &&
"Invalid scaling value.");
2070 EVT VT =
N->getValueType(0);
2077 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2078 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2084 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2086 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2088 for (
unsigned i = 0; i < NumVecs; ++i)
2089 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2090 AArch64::zsub0 + i,
DL, VT, SuperReg));
2093 unsigned ChainIdx = NumVecs;
2095 CurDAG->RemoveDeadNode(
N);
2098void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2103 assert(Scale < 4 &&
"Invalid scaling value.");
2105 EVT VT =
N->getValueType(0);
2113 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2119 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2121 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2123 for (
unsigned i = 0; i < NumVecs; ++i)
2124 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2125 AArch64::zsub0 + i,
DL, VT, SuperReg));
2128 unsigned ChainIdx = NumVecs;
2130 CurDAG->RemoveDeadNode(
N);
2133void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2135 if (
N->getValueType(0) != MVT::nxv4f32)
2137 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2140void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2141 unsigned NumOutVecs,
2145 if (
Imm->getZExtValue() > MaxImm)
2149 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2155 EVT VT =
Node->getValueType(0);
2158 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2161 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2162 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2163 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2166 unsigned ChainIdx = NumOutVecs;
2168 CurDAG->RemoveDeadNode(Node);
2171void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2172 unsigned NumOutVecs,
2175 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2180 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2184 EVT VT =
Node->getValueType(0);
2187 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2190 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2191 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2192 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2195 unsigned ChainIdx = NumOutVecs;
2197 CurDAG->RemoveDeadNode(Node);
2200void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2203 EVT VT =
N->getValueType(0);
2206 SDValue Zd = createZMulTuple(Regs);
2207 SDValue Zn =
N->getOperand(1 + NumVecs);
2208 SDValue Zm =
N->getOperand(2 + NumVecs);
2214 for (
unsigned i = 0; i < NumVecs; ++i)
2215 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2216 AArch64::zsub0 + i,
DL, VT, SuperReg));
2218 CurDAG->RemoveDeadNode(
N);
2248template <
unsigned MaxIdx,
unsigned Scale>
2249void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2250 unsigned BaseReg,
unsigned Op) {
2251 unsigned TileNum = 0;
2252 if (BaseReg != AArch64::ZA)
2253 TileNum =
N->getConstantOperandVal(2);
2259 if (BaseReg == AArch64::ZA)
2264 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2270 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2272 EVT VT =
N->getValueType(0);
2273 for (
unsigned I = 0;
I < NumVecs; ++
I)
2275 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2278 unsigned ChainIdx = NumVecs;
2280 CurDAG->RemoveDeadNode(
N);
2283void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2284 unsigned Op,
unsigned MaxIdx,
2285 unsigned Scale,
unsigned BaseReg) {
2290 if (BaseReg != AArch64::ZA)
2294 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2301 if (BaseReg != AArch64::ZA )
2302 Ops.push_back(
N->getOperand(2));
2305 Ops.push_back(
N->getOperand(0));
2306 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2308 EVT VT =
N->getValueType(0);
2309 for (
unsigned I = 0;
I < NumVecs; ++
I)
2311 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2315 unsigned ChainIdx = NumVecs;
2317 CurDAG->RemoveDeadNode(
N);
2320void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2321 unsigned NumOutVecs,
2325 EVT VT =
N->getValueType(0);
2326 unsigned NumInVecs =
N->getNumOperands() - 1;
2330 assert((NumInVecs == 2 || NumInVecs == 4) &&
2331 "Don't know how to handle multi-register input!");
2333 Ops.push_back(createZMulTuple(Regs));
2336 for (
unsigned I = 0;
I < NumInVecs;
I++)
2337 Ops.push_back(
N->getOperand(1 +
I));
2340 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2343 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2344 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2345 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2346 CurDAG->RemoveDeadNode(
N);
2349void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2352 EVT VT =
N->getOperand(2)->getValueType(0);
2360 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2369void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2370 unsigned Scale,
unsigned Opc_rr,
2376 SDValue RegSeq = createZTuple(Regs);
2382 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2383 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2389 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2397 const DataLayout &
DL = CurDAG->getDataLayout();
2398 const TargetLowering *TLI = getTargetLowering();
2402 int FI = FINode->getIndex();
2404 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2411void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2414 EVT VT =
N->getOperand(2)->getValueType(0);
2415 const EVT ResTys[] = {MVT::i64,
2427 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2467void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2470 EVT VT =
N->getValueType(0);
2482 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2484 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2486 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2488 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2492 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2493 AArch64::qsub2, AArch64::qsub3 };
2494 for (
unsigned i = 0; i < NumVecs; ++i) {
2495 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2502 CurDAG->RemoveDeadNode(
N);
2505void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2508 EVT VT =
N->getValueType(0);
2520 const EVT ResTys[] = {MVT::i64,
2523 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2526 CurDAG->getTargetConstant(LaneNo, dl,
2531 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2543 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2544 AArch64::qsub2, AArch64::qsub3 };
2545 for (
unsigned i = 0; i < NumVecs; ++i) {
2546 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2556 CurDAG->RemoveDeadNode(
N);
2559void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2562 EVT VT =
N->getOperand(2)->getValueType(0);
2574 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2576 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2578 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2587void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2590 EVT VT =
N->getOperand(2)->getValueType(0);
2602 const EVT ResTys[] = {MVT::i64,
2605 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2607 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2611 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2622 unsigned &LSB,
unsigned &MSB,
2623 unsigned NumberOfIgnoredLowBits,
2624 bool BiggerPattern) {
2626 "N must be a AND operation to call this function");
2628 EVT VT =
N->getValueType(0);
2633 assert((VT == MVT::i32 || VT == MVT::i64) &&
2634 "Type checking must have been done before calling this function");
2648 const SDNode *Op0 =
N->getOperand(0).getNode();
2655 if (AndImm & (AndImm + 1))
2658 bool ClampMSB =
false;
2678 ClampMSB = (VT == MVT::i32);
2679 }
else if (BiggerPattern) {
2685 Opd0 =
N->getOperand(0);
2691 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2694 <<
": Found large shift immediate, this should not happen\n"));
2708 MSB = MSB > 31 ? 31 : MSB;
2710 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2715 SDValue &Opd0,
unsigned &Immr,
2719 EVT VT =
N->getValueType(0);
2721 assert((VT == MVT::i32 || VT == MVT::i64) &&
2722 "Type checking must have been done before calling this function");
2726 Op =
Op->getOperand(0);
2727 VT =
Op->getValueType(0);
2736 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2740 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2741 Opd0 =
Op.getOperand(0);
2743 Imms = ShiftImm + Width - 1;
2771 Opd0 =
N->getOperand(0).getOperand(0);
2781 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2788 unsigned &Immr,
unsigned &Imms,
2789 bool BiggerPattern) {
2791 "N must be a SHR/SRA operation to call this function");
2793 EVT VT =
N->getValueType(0);
2798 assert((VT == MVT::i32 || VT == MVT::i64) &&
2799 "Type checking must have been done before calling this function");
2809 Opd0 =
N->getOperand(0).getOperand(0);
2810 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2816 Opd0 =
N->getOperand(0).getOperand(0);
2819 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2820 }
else if (BiggerPattern) {
2824 Opd0 =
N->getOperand(0);
2833 <<
": Found large shift immediate, this should not happen\n"));
2842 "bad amount in shift node!");
2843 int immr = SrlImm - ShlImm;
2848 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2850 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2854bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2857 EVT VT =
N->getValueType(0);
2858 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2859 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2870 unsigned Immr = ShiftImm;
2872 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2873 CurDAG->getTargetConstant(Imms, dl, VT)};
2874 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2879 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2880 unsigned NumberOfIgnoredLowBits = 0,
2881 bool BiggerPattern =
false) {
2882 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2885 switch (
N->getOpcode()) {
2887 if (!
N->isMachineOpcode())
2892 NumberOfIgnoredLowBits, BiggerPattern);
2901 unsigned NOpc =
N->getMachineOpcode();
2905 case AArch64::SBFMWri:
2906 case AArch64::UBFMWri:
2907 case AArch64::SBFMXri:
2908 case AArch64::UBFMXri:
2910 Opd0 =
N->getOperand(0);
2911 Immr =
N->getConstantOperandVal(1);
2912 Imms =
N->getConstantOperandVal(2);
2919bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
2920 unsigned Opc, Immr, Imms;
2925 EVT VT =
N->getValueType(0);
2930 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2931 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2932 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2934 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
2935 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2941 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2942 CurDAG->getTargetConstant(Imms, dl, VT)};
2943 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
2952 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2953 assert((VT == MVT::i32 || VT == MVT::i64) &&
2954 "i32 or i64 mask type expected!");
2958 APInt SignificantDstMask =
2962 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2963 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2996 APInt OpUsefulBits(UsefulBits);
3000 OpUsefulBits <<= MSB - Imm + 1;
3005 OpUsefulBits <<= Imm;
3007 OpUsefulBits <<= MSB + 1;
3010 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
3016 UsefulBits &= OpUsefulBits;
3033 APInt Mask(UsefulBits);
3034 Mask.clearAllBits();
3042 Mask.lshrInPlace(ShiftAmt);
3048 Mask.lshrInPlace(ShiftAmt);
3064 APInt OpUsefulBits(UsefulBits);
3078 OpUsefulBits <<= Width;
3081 if (
Op.getOperand(1) == Orig) {
3083 Mask = ResultUsefulBits & OpUsefulBits;
3087 if (
Op.getOperand(0) == Orig)
3089 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3095 OpUsefulBits <<= Width;
3097 OpUsefulBits <<= LSB;
3099 if (
Op.getOperand(1) == Orig) {
3101 Mask = ResultUsefulBits & OpUsefulBits;
3102 Mask.lshrInPlace(LSB);
3105 if (
Op.getOperand(0) == Orig)
3106 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3123 case AArch64::ANDSWri:
3124 case AArch64::ANDSXri:
3125 case AArch64::ANDWri:
3126 case AArch64::ANDXri:
3130 case AArch64::UBFMWri:
3131 case AArch64::UBFMXri:
3134 case AArch64::ORRWrs:
3135 case AArch64::ORRXrs:
3140 case AArch64::BFMWri:
3141 case AArch64::BFMXri:
3144 case AArch64::STRBBui:
3145 case AArch64::STURBBi:
3151 case AArch64::STRHHui:
3152 case AArch64::STURHHi:
3165 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3167 UsefulBits =
APInt(Bitwidth, 0);
3176 UsersUsefulBits |= UsefulBitsForUse;
3181 UsefulBits &= UsersUsefulBits;
3191 EVT VT =
Op.getValueType();
3194 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3197 if (ShlAmount > 0) {
3200 UBFMOpc, dl, VT,
Op,
3205 assert(ShlAmount < 0 &&
"expected right shift");
3206 int ShrAmount = -ShlAmount;
3218 const uint64_t NonZeroBits,
3225 const uint64_t NonZeroBits,
3232 bool BiggerPattern,
SDValue &Src,
3233 int &DstLSB,
int &Width) {
3234 EVT VT =
Op.getValueType();
3243 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3247 switch (
Op.getOpcode()) {
3252 NonZeroBits, Src, DstLSB, Width);
3255 NonZeroBits, Src, DstLSB, Width);
3268 EVT VT =
Op.getValueType();
3269 assert((VT == MVT::i32 || VT == MVT::i64) &&
3270 "Caller guarantees VT is one of i32 or i64");
3283 assert((~AndImm & NonZeroBits) == 0 &&
3284 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3313 if (!BiggerPattern && !AndOp0.
hasOneUse())
3332 <<
"Found large Width in bit-field-positioning -- this indicates no "
3333 "proper combining / constant folding was performed\n");
3342 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3357 "Op.getNode() should be a SHL node to call this function");
3359 "Op.getNode() should shift ShlImm to call this function");
3366 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3390 EVT VT =
Op.getValueType();
3391 assert((VT == MVT::i32 || VT == MVT::i64) &&
3392 "Caller guarantees that type is i32 or i64");
3399 if (!BiggerPattern && !
Op.hasOneUse())
3408 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3416 assert(VT == MVT::i32 || VT == MVT::i64);
3427 EVT VT =
N->getValueType(0);
3428 if (VT != MVT::i32 && VT != MVT::i64)
3446 if (!
And.hasOneUse() ||
3456 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3463 if ((OrImm & NotKnownZero) != 0) {
3475 unsigned ImmS = Width - 1;
3481 bool IsBFI = LSB != 0;
3486 unsigned OrChunks = 0, BFIChunks = 0;
3487 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3488 if (((OrImm >> Shift) & 0xFFFF) != 0)
3490 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3493 if (BFIChunks > OrChunks)
3499 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3507 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3516 if (!Dst.hasOneUse())
3519 EVT VT = Dst.getValueType();
3520 assert((VT == MVT::i32 || VT == MVT::i64) &&
3521 "Caller should guarantee that VT is one of i32 or i64");
3549 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3550 unsigned MaskWidth =
3553 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3559 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3560 ShiftedOperand =
SDValue(UBFMNode, 0);
3589 const bool BiggerPattern) {
3590 EVT VT =
N->getValueType(0);
3591 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3592 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3593 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3594 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3595 assert((VT == MVT::i32 || VT == MVT::i64) &&
3596 "Expect result type to be i32 or i64 since N is combinable to BFM");
3603 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3606 if (BiggerPattern) {
3629 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3691 EVT VT =
N->getValueType(0);
3692 if (VT != MVT::i32 && VT != MVT::i64)
3700 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3701 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3721 for (
int I = 0;
I < 4; ++
I) {
3724 unsigned ImmR, ImmS;
3725 bool BiggerPattern =
I / 2;
3726 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3728 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3734 NumberOfIgnoredLowBits, BiggerPattern)) {
3737 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3738 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3743 Width = ImmS - ImmR + 1;
3754 Src, DstLSB, Width)) {
3762 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3772 APInt BitsToBeInserted =
3775 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3799 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3832 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3834 if (Src->hasOneUse() &&
3837 Src = Src->getOperand(0);
3847 unsigned ImmS = Width - 1;
3853 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3861bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3870 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3883bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3887 EVT VT =
N->getValueType(0);
3888 if (VT != MVT::i32 && VT != MVT::i64)
3894 Op0, DstLSB, Width))
3900 unsigned ImmS = Width - 1;
3903 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3904 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3905 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3906 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3912bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
3913 EVT VT =
N->getValueType(0);
3916 switch (
N->getOpcode()) {
3918 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3921 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3924 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3927 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3935 if (VT == MVT::i32) {
3938 }
else if (VT == MVT::i64) {
3944 SDValue ShiftAmt =
N->getOperand(1);
3964 (Add0Imm %
Size == 0)) {
3970 if (SubVT == MVT::i32) {
3971 NegOpc = AArch64::SUBWrr;
3972 ZeroReg = AArch64::WZR;
3974 assert(SubVT == MVT::i64);
3975 NegOpc = AArch64::SUBXrr;
3976 ZeroReg = AArch64::XZR;
3979 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3980 MachineSDNode *Neg =
3981 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3982 NewShiftAmt =
SDValue(Neg, 0);
3990 if (SubVT == MVT::i32) {
3991 NotOpc = AArch64::ORNWrr;
3992 ZeroReg = AArch64::WZR;
3994 assert(SubVT == MVT::i64);
3995 NotOpc = AArch64::ORNXrr;
3996 ZeroReg = AArch64::XZR;
3999 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4000 MachineSDNode *
Not =
4001 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4002 NewShiftAmt =
SDValue(Not, 0);
4023 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4024 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4025 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4027 NewShiftAmt =
SDValue(Ext, 0);
4031 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4038 bool isReciprocal) {
4041 FVal = CN->getValueAPF();
4044 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4054 if (
unsigned FBits =
4063bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4064 unsigned RegWidth) {
4069bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4070 unsigned RegWidth) {
4071 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4072 N.getValueType().getScalarSizeInBits() ==
4073 N.getOperand(0).getValueType().getScalarSizeInBits())
4074 N =
N.getOperand(0);
4076 auto ImmToFloat = [RegWidth](APInt
Imm) {
4079 return APFloat(APFloat::IEEEhalf(), Imm);
4081 return APFloat(APFloat::IEEEsingle(), Imm);
4083 return APFloat(APFloat::IEEEdouble(), Imm);
4090 switch (
N->getOpcode()) {
4091 case AArch64ISD::MOVIshift:
4092 FVal = ImmToFloat(APInt(RegWidth,
N.getConstantOperandVal(0)
4093 <<
N.getConstantOperandVal(1)));
4095 case AArch64ISD::FMOV:
4096 assert(RegWidth == 32 || RegWidth == 64);
4100 N.getConstantOperandVal(0))));
4103 N.getConstantOperandVal(0))));
4105 case AArch64ISD::DUP:
4107 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4117 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(
N), MVT::i32);
4124bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4126 unsigned RegWidth) {
4136 RegString.
split(Fields,
':');
4138 if (Fields.
size() == 1)
4142 &&
"Invalid number of fields in read register string");
4145 bool AllIntFields =
true;
4149 AllIntFields &= !
Field.getAsInteger(10, IntField);
4150 Ops.push_back(IntField);
4154 "Unexpected non-integer value in special register string.");
4159 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4160 (
Ops[3] << 3) | (
Ops[4]);
4167bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4169 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4172 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4174 unsigned Opcode64Bit = AArch64::MRS;
4179 const auto *TheReg =
4180 AArch64SysReg::lookupSysRegByName(RegString->getString());
4181 if (TheReg && TheReg->Readable &&
4182 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4183 Imm = TheReg->Encoding;
4189 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4190 Opcode64Bit = AArch64::ADR;
4198 SDValue InChain =
N->getOperand(0);
4199 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4200 if (!ReadIs128Bit) {
4201 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4202 {SysRegImm, InChain});
4204 SDNode *MRRS = CurDAG->getMachineNode(
4206 {MVT::Untyped , MVT::Other },
4207 {SysRegImm, InChain});
4211 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4213 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4219 ReplaceUses(
SDValue(
N, 2), OutChain);
4228bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4230 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4233 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4235 if (!WriteIs128Bit) {
4241 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4244 "Expected a constant integer expression.");
4245 unsigned Reg = PMapper->Encoding;
4246 uint64_t Immed =
N->getConstantOperandVal(2);
4247 CurDAG->SelectNodeTo(
4248 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4249 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4255 if (trySelectPState(
4256 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4257 AArch64::MSRpstateImm4))
4259 if (trySelectPState(
4260 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4261 AArch64::MSRpstateImm1))
4270 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4271 if (TheReg && TheReg->Writeable &&
4272 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4273 Imm = TheReg->Encoding;
4282 if (!WriteIs128Bit) {
4283 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4284 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4285 N->getOperand(2), InChain);
4289 SDNode *Pair = CurDAG->getMachineNode(
4290 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4291 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4294 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4296 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4298 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4299 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4307bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4312 if (Subtarget->hasLSE())
return false;
4314 if (MemTy == MVT::i8)
4315 Opcode = AArch64::CMP_SWAP_8;
4316 else if (MemTy == MVT::i16)
4317 Opcode = AArch64::CMP_SWAP_16;
4318 else if (MemTy == MVT::i32)
4319 Opcode = AArch64::CMP_SWAP_32;
4320 else if (MemTy == MVT::i64)
4321 Opcode = AArch64::CMP_SWAP_64;
4325 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4326 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4328 SDNode *CmpSwap = CurDAG->getMachineNode(
4330 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4337 CurDAG->RemoveDeadNode(
N);
4342bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4343 SDValue &Shift,
bool Negate) {
4357 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4364 if ((Val & ~0xff) == 0) {
4365 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4370 if ((Val & ~0xff00) == 0) {
4371 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4383bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4407 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4408 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4415 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4416 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4420 if (Val <= 65280 && Val % 256 == 0) {
4421 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4422 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4433bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4443 int32_t ImmVal, ShiftVal;
4448 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4449 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4453bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4455 int64_t ImmVal = CNode->getSExtValue();
4457 if (ImmVal >= -128 && ImmVal < 128) {
4458 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4465bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4467 uint64_t ImmVal = CNode->getZExtValue();
4477 ImmVal &= 0xFFFFFFFF;
4486 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4493bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4497 ImmVal = CI->getZExtValue();
4499 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4510 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4519bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4520 uint64_t
High,
bool AllowSaturation,
4523 uint64_t ImmVal = CN->getZExtValue();
4530 if (ImmVal >
High) {
4531 if (!AllowSaturation)
4536 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4543bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4557 const TargetLowering *TLI = getTargetLowering();
4560 SDValue FiOp = CurDAG->getTargetFrameIndex(
4562 int TagOffset =
N->getConstantOperandVal(3);
4564 SDNode *Out = CurDAG->getMachineNode(
4565 AArch64::TAGPstack,
DL, MVT::i64,
4566 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4567 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4568 ReplaceNode(
N, Out);
4572void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4574 "llvm.aarch64.tagp third argument must be an immediate");
4575 if (trySelectStackSlotTagP(
N))
4582 int TagOffset =
N->getConstantOperandVal(3);
4583 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4584 {
N->getOperand(1),
N->getOperand(2)});
4585 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4586 {
SDValue(N1, 0),
N->getOperand(2)});
4587 SDNode *N3 = CurDAG->getMachineNode(
4588 AArch64::ADDG,
DL, MVT::i64,
4589 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4590 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4594bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4598 if (
N->getConstantOperandVal(2) != 0)
4600 if (!
N->getOperand(0).isUndef())
4604 EVT VT =
N->getValueType(0);
4605 EVT InVT =
N->getOperand(1).getValueType();
4616 "Expected to insert into a packed scalable vector!");
4619 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4620 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4621 N->getOperand(1), RC));
4625bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4629 if (
N->getConstantOperandVal(1) != 0)
4633 EVT VT =
N->getValueType(0);
4634 EVT InVT =
N->getOperand(0).getValueType();
4645 "Expected to extract from a packed scalable vector!");
4648 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4649 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4650 N->getOperand(0), RC));
4654bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4660 EVT VT =
N->getValueType(0);
4673 (Subtarget->hasSVE2() ||
4674 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4675 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4678 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4682 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4683 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4684 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4691 bool IsXOROperand =
true;
4693 IsXOROperand =
false;
4699 APInt ShlAmt, ShrAmt;
4707 if (!IsXOROperand) {
4709 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4712 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4713 SDNode *SubRegToReg =
4714 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4725 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4726 AArch64::XAR_ZZZI_D})) {
4727 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4752 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4762 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4770 bool IsXOROperand =
true;
4772 IsXOROperand =
false;
4775 R1 =
XOR.getOperand(0);
4776 R2 =
XOR.getOperand(1);
4786 if (ShAmt + HsAmt != VTSizeInBits)
4789 if (!IsXOROperand) {
4792 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4801 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4807 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4808 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4810 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4813 if (
R2.getValueType() == VT)
4814 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4822 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4827 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4833 SDNode *XAR =
nullptr;
4837 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4838 AArch64::XAR_ZZZI_D}))
4839 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4841 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4844 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4850 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4851 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4854 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4855 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4861 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4865 ReplaceNode(
N, XAR);
4869void AArch64DAGToDAGISel::Select(SDNode *Node) {
4871 if (
Node->isMachineOpcode()) {
4873 Node->setNodeId(-1);
4878 EVT VT =
Node->getValueType(0);
4880 switch (
Node->getOpcode()) {
4885 if (SelectCMP_SWAP(Node))
4890 case AArch64ISD::MRRS:
4891 if (tryReadRegister(Node))
4896 case AArch64ISD::MSRR:
4897 if (tryWriteRegister(Node))
4904 if (tryIndexedLoad(Node))
4913 if (tryBitfieldExtractOp(Node))
4915 if (tryBitfieldInsertInZeroOp(Node))
4920 if (tryShiftAmountMod(Node))
4925 if (tryBitfieldExtractOpFromSExt(Node))
4930 if (tryBitfieldInsertOp(Node))
4932 if (trySelectXAR(Node))
4937 if (trySelectCastScalableToFixedLengthVector(Node))
4943 if (trySelectCastFixedLengthToScalableVector(Node))
4952 if (ConstNode->
isZero()) {
4953 if (VT == MVT::i32) {
4955 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
4956 ReplaceNode(Node,
New.getNode());
4958 }
else if (VT == MVT::i64) {
4960 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
4961 ReplaceNode(Node,
New.getNode());
4972 const TargetLowering *TLI = getTargetLowering();
4973 SDValue TFI = CurDAG->getTargetFrameIndex(
4976 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4977 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4978 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
4982 unsigned IntNo =
Node->getConstantOperandVal(1);
4986 case Intrinsic::aarch64_gcsss: {
4990 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4992 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4993 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4994 MVT::Other, Zero,
SDValue(SS1, 0));
4995 ReplaceNode(Node, SS2);
4998 case Intrinsic::aarch64_ldaxp:
4999 case Intrinsic::aarch64_ldxp: {
5001 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5006 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5007 MVT::Other, MemAddr, Chain);
5010 MachineMemOperand *MemOp =
5013 ReplaceNode(Node, Ld);
5016 case Intrinsic::aarch64_stlxp:
5017 case Intrinsic::aarch64_stxp: {
5019 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5027 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
5029 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5031 MachineMemOperand *MemOp =
5035 ReplaceNode(Node, St);
5038 case Intrinsic::aarch64_neon_ld1x2:
5039 if (VT == MVT::v8i8) {
5040 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5042 }
else if (VT == MVT::v16i8) {
5043 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5045 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5046 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5048 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5049 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5051 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5052 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5054 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5055 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5057 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5058 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5060 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5061 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5065 case Intrinsic::aarch64_neon_ld1x3:
5066 if (VT == MVT::v8i8) {
5067 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5069 }
else if (VT == MVT::v16i8) {
5070 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5072 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5073 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5075 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5076 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5078 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5079 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5081 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5082 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5084 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5085 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5087 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5088 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5092 case Intrinsic::aarch64_neon_ld1x4:
5093 if (VT == MVT::v8i8) {
5094 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5096 }
else if (VT == MVT::v16i8) {
5097 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5099 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5100 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5102 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5103 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5105 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5106 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5108 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5109 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5111 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5112 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5114 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5115 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5119 case Intrinsic::aarch64_neon_ld2:
5120 if (VT == MVT::v8i8) {
5121 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5123 }
else if (VT == MVT::v16i8) {
5124 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5126 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5127 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5129 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5130 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5132 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5133 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5135 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5136 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5138 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5139 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5141 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5142 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5146 case Intrinsic::aarch64_neon_ld3:
5147 if (VT == MVT::v8i8) {
5148 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5150 }
else if (VT == MVT::v16i8) {
5151 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5153 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5154 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5156 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5157 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5159 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5160 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5162 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5163 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5165 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5166 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5168 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5169 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5173 case Intrinsic::aarch64_neon_ld4:
5174 if (VT == MVT::v8i8) {
5175 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5177 }
else if (VT == MVT::v16i8) {
5178 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5180 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5181 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5183 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5184 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5186 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5187 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5189 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5190 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5192 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5193 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5195 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5196 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5200 case Intrinsic::aarch64_neon_ld2r:
5201 if (VT == MVT::v8i8) {
5202 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5204 }
else if (VT == MVT::v16i8) {
5205 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5207 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5208 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5210 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5211 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5213 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5214 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5216 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5217 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5219 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5220 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5222 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5223 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5227 case Intrinsic::aarch64_neon_ld3r:
5228 if (VT == MVT::v8i8) {
5229 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5231 }
else if (VT == MVT::v16i8) {
5232 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5234 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5235 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5237 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5238 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5240 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5241 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5243 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5244 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5246 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5247 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5249 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5250 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5254 case Intrinsic::aarch64_neon_ld4r:
5255 if (VT == MVT::v8i8) {
5256 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5258 }
else if (VT == MVT::v16i8) {
5259 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5261 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5262 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5264 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5265 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5267 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5268 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5270 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5271 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5273 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5274 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5276 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5277 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5281 case Intrinsic::aarch64_neon_ld2lane:
5282 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5283 SelectLoadLane(Node, 2, AArch64::LD2i8);
5285 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5286 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5287 SelectLoadLane(Node, 2, AArch64::LD2i16);
5289 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5291 SelectLoadLane(Node, 2, AArch64::LD2i32);
5293 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5295 SelectLoadLane(Node, 2, AArch64::LD2i64);
5299 case Intrinsic::aarch64_neon_ld3lane:
5300 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5301 SelectLoadLane(Node, 3, AArch64::LD3i8);
5303 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5304 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5305 SelectLoadLane(Node, 3, AArch64::LD3i16);
5307 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5309 SelectLoadLane(Node, 3, AArch64::LD3i32);
5311 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5313 SelectLoadLane(Node, 3, AArch64::LD3i64);
5317 case Intrinsic::aarch64_neon_ld4lane:
5318 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5319 SelectLoadLane(Node, 4, AArch64::LD4i8);
5321 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5322 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5323 SelectLoadLane(Node, 4, AArch64::LD4i16);
5325 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5327 SelectLoadLane(Node, 4, AArch64::LD4i32);
5329 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5331 SelectLoadLane(Node, 4, AArch64::LD4i64);
5335 case Intrinsic::aarch64_ld64b:
5336 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5338 case Intrinsic::aarch64_sve_ld2q_sret: {
5339 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5342 case Intrinsic::aarch64_sve_ld3q_sret: {
5343 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5346 case Intrinsic::aarch64_sve_ld4q_sret: {
5347 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5350 case Intrinsic::aarch64_sve_ld2_sret: {
5351 if (VT == MVT::nxv16i8) {
5352 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5355 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5356 VT == MVT::nxv8bf16) {
5357 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5360 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5361 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5364 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5365 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5371 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5372 if (VT == MVT::nxv16i8) {
5373 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5374 SelectContiguousMultiVectorLoad(
5375 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5376 else if (Subtarget->hasSVE2p1())
5377 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5382 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5383 VT == MVT::nxv8bf16) {
5384 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5385 SelectContiguousMultiVectorLoad(
5386 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5387 else if (Subtarget->hasSVE2p1())
5388 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5393 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5394 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5395 SelectContiguousMultiVectorLoad(
5396 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5397 else if (Subtarget->hasSVE2p1())
5398 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5403 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5404 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5405 SelectContiguousMultiVectorLoad(
5406 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5407 else if (Subtarget->hasSVE2p1())
5408 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5416 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5417 if (VT == MVT::nxv16i8) {
5418 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5419 SelectContiguousMultiVectorLoad(
5420 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5421 else if (Subtarget->hasSVE2p1())
5422 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5427 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5428 VT == MVT::nxv8bf16) {
5429 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5430 SelectContiguousMultiVectorLoad(
5431 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5432 else if (Subtarget->hasSVE2p1())
5433 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5438 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5439 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5440 SelectContiguousMultiVectorLoad(
5441 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5442 else if (Subtarget->hasSVE2p1())
5443 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5448 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5449 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5450 SelectContiguousMultiVectorLoad(
5451 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5452 else if (Subtarget->hasSVE2p1())
5453 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5461 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5462 if (VT == MVT::nxv16i8) {
5463 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5464 SelectContiguousMultiVectorLoad(Node, 2, 0,
5465 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5466 AArch64::LDNT1B_2Z_PSEUDO);
5467 else if (Subtarget->hasSVE2p1())
5468 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5469 AArch64::LDNT1B_2Z);
5473 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5474 VT == MVT::nxv8bf16) {
5475 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5476 SelectContiguousMultiVectorLoad(Node, 2, 1,
5477 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5478 AArch64::LDNT1H_2Z_PSEUDO);
5479 else if (Subtarget->hasSVE2p1())
5480 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5481 AArch64::LDNT1H_2Z);
5485 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5486 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5487 SelectContiguousMultiVectorLoad(Node, 2, 2,
5488 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5489 AArch64::LDNT1W_2Z_PSEUDO);
5490 else if (Subtarget->hasSVE2p1())
5491 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5492 AArch64::LDNT1W_2Z);
5496 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5497 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5498 SelectContiguousMultiVectorLoad(Node, 2, 3,
5499 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5500 AArch64::LDNT1D_2Z_PSEUDO);
5501 else if (Subtarget->hasSVE2p1())
5502 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5503 AArch64::LDNT1D_2Z);
5510 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5511 if (VT == MVT::nxv16i8) {
5512 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5513 SelectContiguousMultiVectorLoad(Node, 4, 0,
5514 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5515 AArch64::LDNT1B_4Z_PSEUDO);
5516 else if (Subtarget->hasSVE2p1())
5517 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5518 AArch64::LDNT1B_4Z);
5522 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5523 VT == MVT::nxv8bf16) {
5524 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5525 SelectContiguousMultiVectorLoad(Node, 4, 1,
5526 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5527 AArch64::LDNT1H_4Z_PSEUDO);
5528 else if (Subtarget->hasSVE2p1())
5529 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5530 AArch64::LDNT1H_4Z);
5534 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5535 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5536 SelectContiguousMultiVectorLoad(Node, 4, 2,
5537 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5538 AArch64::LDNT1W_4Z_PSEUDO);
5539 else if (Subtarget->hasSVE2p1())
5540 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5541 AArch64::LDNT1W_4Z);
5545 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5546 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5547 SelectContiguousMultiVectorLoad(Node, 4, 3,
5548 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5549 AArch64::LDNT1D_4Z_PSEUDO);
5550 else if (Subtarget->hasSVE2p1())
5551 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5552 AArch64::LDNT1D_4Z);
5559 case Intrinsic::aarch64_sve_ld3_sret: {
5560 if (VT == MVT::nxv16i8) {
5561 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5564 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5565 VT == MVT::nxv8bf16) {
5566 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5569 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5570 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5573 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5574 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5580 case Intrinsic::aarch64_sve_ld4_sret: {
5581 if (VT == MVT::nxv16i8) {
5582 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5585 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5586 VT == MVT::nxv8bf16) {
5587 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5590 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5591 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5594 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5595 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5601 case Intrinsic::aarch64_sme_read_hor_vg2: {
5602 if (VT == MVT::nxv16i8) {
5603 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5604 AArch64::MOVA_2ZMXI_H_B);
5606 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5607 VT == MVT::nxv8bf16) {
5608 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5609 AArch64::MOVA_2ZMXI_H_H);
5611 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5612 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5613 AArch64::MOVA_2ZMXI_H_S);
5615 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5616 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5617 AArch64::MOVA_2ZMXI_H_D);
5622 case Intrinsic::aarch64_sme_read_ver_vg2: {
5623 if (VT == MVT::nxv16i8) {
5624 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5625 AArch64::MOVA_2ZMXI_V_B);
5627 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5628 VT == MVT::nxv8bf16) {
5629 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5630 AArch64::MOVA_2ZMXI_V_H);
5632 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5633 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5634 AArch64::MOVA_2ZMXI_V_S);
5636 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5637 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5638 AArch64::MOVA_2ZMXI_V_D);
5643 case Intrinsic::aarch64_sme_read_hor_vg4: {
5644 if (VT == MVT::nxv16i8) {
5645 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5646 AArch64::MOVA_4ZMXI_H_B);
5648 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5649 VT == MVT::nxv8bf16) {
5650 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5651 AArch64::MOVA_4ZMXI_H_H);
5653 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5654 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5655 AArch64::MOVA_4ZMXI_H_S);
5657 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5658 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5659 AArch64::MOVA_4ZMXI_H_D);
5664 case Intrinsic::aarch64_sme_read_ver_vg4: {
5665 if (VT == MVT::nxv16i8) {
5666 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5667 AArch64::MOVA_4ZMXI_V_B);
5669 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5670 VT == MVT::nxv8bf16) {
5671 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5672 AArch64::MOVA_4ZMXI_V_H);
5674 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5675 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5676 AArch64::MOVA_4ZMXI_V_S);
5678 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5679 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5680 AArch64::MOVA_4ZMXI_V_D);
5685 case Intrinsic::aarch64_sme_read_vg1x2: {
5686 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5687 AArch64::MOVA_VG2_2ZMXI);
5690 case Intrinsic::aarch64_sme_read_vg1x4: {
5691 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5692 AArch64::MOVA_VG4_4ZMXI);
5695 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5696 if (VT == MVT::nxv16i8) {
5697 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5699 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5700 VT == MVT::nxv8bf16) {
5701 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5703 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5704 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5706 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5707 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5712 case Intrinsic::aarch64_sme_readz_vert_x2: {
5713 if (VT == MVT::nxv16i8) {
5714 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5716 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5717 VT == MVT::nxv8bf16) {
5718 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5720 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5721 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5723 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5724 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5729 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5730 if (VT == MVT::nxv16i8) {
5731 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5733 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5734 VT == MVT::nxv8bf16) {
5735 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5737 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5738 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5740 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5741 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5746 case Intrinsic::aarch64_sme_readz_vert_x4: {
5747 if (VT == MVT::nxv16i8) {
5748 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5750 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5751 VT == MVT::nxv8bf16) {
5752 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5754 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5755 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5757 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5758 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5763 case Intrinsic::aarch64_sme_readz_x2: {
5764 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5768 case Intrinsic::aarch64_sme_readz_x4: {
5769 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5773 case Intrinsic::swift_async_context_addr: {
5776 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5778 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5779 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5780 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5782 ReplaceUses(
SDValue(Node, 0), Res);
5784 CurDAG->RemoveDeadNode(Node);
5786 auto &MF = CurDAG->getMachineFunction();
5787 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5788 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5791 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5793 Node->getValueType(0),
5794 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5795 AArch64::LUTI2_4ZTZI_S}))
5797 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5800 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5802 Node->getValueType(0),
5803 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5805 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5808 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5810 Node->getValueType(0),
5811 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5812 AArch64::LUTI2_2ZTZI_S}))
5814 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5817 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5819 Node->getValueType(0),
5820 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5821 AArch64::LUTI4_2ZTZI_S}))
5823 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5826 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5827 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5830 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5832 Node->getValueType(0),
5833 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5834 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5836 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5838 Node->getValueType(0),
5839 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5840 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5842 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5844 Node->getValueType(0),
5845 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5846 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5848 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5850 Node->getValueType(0),
5851 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5852 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5854 case Intrinsic::ptrauth_resign_load_relative:
5855 SelectPtrauthResign(Node);
5860 unsigned IntNo =
Node->getConstantOperandVal(0);
5864 case Intrinsic::aarch64_tagp:
5868 case Intrinsic::ptrauth_auth:
5869 SelectPtrauthAuth(Node);
5872 case Intrinsic::ptrauth_resign:
5873 SelectPtrauthResign(Node);
5876 case Intrinsic::aarch64_neon_tbl2:
5877 SelectTable(Node, 2,
5878 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5881 case Intrinsic::aarch64_neon_tbl3:
5882 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5883 : AArch64::TBLv16i8Three,
5886 case Intrinsic::aarch64_neon_tbl4:
5887 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5888 : AArch64::TBLv16i8Four,
5891 case Intrinsic::aarch64_neon_tbx2:
5892 SelectTable(Node, 2,
5893 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5896 case Intrinsic::aarch64_neon_tbx3:
5897 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5898 : AArch64::TBXv16i8Three,
5901 case Intrinsic::aarch64_neon_tbx4:
5902 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5903 : AArch64::TBXv16i8Four,
5906 case Intrinsic::aarch64_sve_srshl_single_x2:
5908 Node->getValueType(0),
5909 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5910 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5911 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5913 case Intrinsic::aarch64_sve_srshl_single_x4:
5915 Node->getValueType(0),
5916 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5917 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5918 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5920 case Intrinsic::aarch64_sve_urshl_single_x2:
5922 Node->getValueType(0),
5923 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5924 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5925 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5927 case Intrinsic::aarch64_sve_urshl_single_x4:
5929 Node->getValueType(0),
5930 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5931 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5932 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5934 case Intrinsic::aarch64_sve_srshl_x2:
5936 Node->getValueType(0),
5937 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5938 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5939 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5941 case Intrinsic::aarch64_sve_srshl_x4:
5943 Node->getValueType(0),
5944 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5945 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5946 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5948 case Intrinsic::aarch64_sve_urshl_x2:
5950 Node->getValueType(0),
5951 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5952 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5953 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5955 case Intrinsic::aarch64_sve_urshl_x4:
5957 Node->getValueType(0),
5958 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5959 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5960 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5962 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5964 Node->getValueType(0),
5965 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5966 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5967 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5969 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5971 Node->getValueType(0),
5972 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5973 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5974 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5976 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5978 Node->getValueType(0),
5979 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5980 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5981 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5983 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5985 Node->getValueType(0),
5986 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5987 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5988 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5990 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5992 Node->getValueType(0),
5993 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5994 AArch64::FSCALE_2ZZ_D}))
5995 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5997 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5999 Node->getValueType(0),
6000 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6001 AArch64::FSCALE_4ZZ_D}))
6002 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6004 case Intrinsic::aarch64_sme_fp8_scale_x2:
6006 Node->getValueType(0),
6007 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6008 AArch64::FSCALE_2Z2Z_D}))
6009 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6011 case Intrinsic::aarch64_sme_fp8_scale_x4:
6013 Node->getValueType(0),
6014 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6015 AArch64::FSCALE_4Z4Z_D}))
6016 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6018 case Intrinsic::aarch64_sve_whilege_x2:
6020 Node->getValueType(0),
6021 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6022 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6023 SelectWhilePair(Node,
Op);
6025 case Intrinsic::aarch64_sve_whilegt_x2:
6027 Node->getValueType(0),
6028 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6029 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6030 SelectWhilePair(Node,
Op);
6032 case Intrinsic::aarch64_sve_whilehi_x2:
6034 Node->getValueType(0),
6035 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6036 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6037 SelectWhilePair(Node,
Op);
6039 case Intrinsic::aarch64_sve_whilehs_x2:
6041 Node->getValueType(0),
6042 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6043 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6044 SelectWhilePair(Node,
Op);
6046 case Intrinsic::aarch64_sve_whilele_x2:
6048 Node->getValueType(0),
6049 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6050 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6051 SelectWhilePair(Node,
Op);
6053 case Intrinsic::aarch64_sve_whilelo_x2:
6055 Node->getValueType(0),
6056 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6057 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6058 SelectWhilePair(Node,
Op);
6060 case Intrinsic::aarch64_sve_whilels_x2:
6062 Node->getValueType(0),
6063 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6064 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6065 SelectWhilePair(Node,
Op);
6067 case Intrinsic::aarch64_sve_whilelt_x2:
6069 Node->getValueType(0),
6070 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6071 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6072 SelectWhilePair(Node,
Op);
6074 case Intrinsic::aarch64_sve_smax_single_x2:
6076 Node->getValueType(0),
6077 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6078 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6079 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6081 case Intrinsic::aarch64_sve_umax_single_x2:
6083 Node->getValueType(0),
6084 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6085 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6086 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6088 case Intrinsic::aarch64_sve_fmax_single_x2:
6090 Node->getValueType(0),
6091 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6092 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6093 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6095 case Intrinsic::aarch64_sve_smax_single_x4:
6097 Node->getValueType(0),
6098 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6099 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6100 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6102 case Intrinsic::aarch64_sve_umax_single_x4:
6104 Node->getValueType(0),
6105 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6106 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6107 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6109 case Intrinsic::aarch64_sve_fmax_single_x4:
6111 Node->getValueType(0),
6112 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6113 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6114 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6116 case Intrinsic::aarch64_sve_smin_single_x2:
6118 Node->getValueType(0),
6119 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6120 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6121 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6123 case Intrinsic::aarch64_sve_umin_single_x2:
6125 Node->getValueType(0),
6126 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6127 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6128 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6130 case Intrinsic::aarch64_sve_fmin_single_x2:
6132 Node->getValueType(0),
6133 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6134 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6135 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6137 case Intrinsic::aarch64_sve_smin_single_x4:
6139 Node->getValueType(0),
6140 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6141 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6142 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6144 case Intrinsic::aarch64_sve_umin_single_x4:
6146 Node->getValueType(0),
6147 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6148 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6149 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6151 case Intrinsic::aarch64_sve_fmin_single_x4:
6153 Node->getValueType(0),
6154 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6155 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6156 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6158 case Intrinsic::aarch64_sve_smax_x2:
6160 Node->getValueType(0),
6161 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6162 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6163 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6165 case Intrinsic::aarch64_sve_umax_x2:
6167 Node->getValueType(0),
6168 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6169 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6170 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6172 case Intrinsic::aarch64_sve_fmax_x2:
6174 Node->getValueType(0),
6175 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6176 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6177 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6179 case Intrinsic::aarch64_sve_smax_x4:
6181 Node->getValueType(0),
6182 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6183 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6184 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6186 case Intrinsic::aarch64_sve_umax_x4:
6188 Node->getValueType(0),
6189 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6190 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6191 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6193 case Intrinsic::aarch64_sve_fmax_x4:
6195 Node->getValueType(0),
6196 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6197 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6198 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6200 case Intrinsic::aarch64_sme_famax_x2:
6202 Node->getValueType(0),
6203 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6204 AArch64::FAMAX_2Z2Z_D}))
6205 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6207 case Intrinsic::aarch64_sme_famax_x4:
6209 Node->getValueType(0),
6210 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6211 AArch64::FAMAX_4Z4Z_D}))
6212 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6214 case Intrinsic::aarch64_sme_famin_x2:
6216 Node->getValueType(0),
6217 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6218 AArch64::FAMIN_2Z2Z_D}))
6219 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6221 case Intrinsic::aarch64_sme_famin_x4:
6223 Node->getValueType(0),
6224 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6225 AArch64::FAMIN_4Z4Z_D}))
6226 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6228 case Intrinsic::aarch64_sve_smin_x2:
6230 Node->getValueType(0),
6231 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6232 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6233 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6235 case Intrinsic::aarch64_sve_umin_x2:
6237 Node->getValueType(0),
6238 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6239 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6240 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6242 case Intrinsic::aarch64_sve_fmin_x2:
6244 Node->getValueType(0),
6245 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6246 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6247 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6249 case Intrinsic::aarch64_sve_smin_x4:
6251 Node->getValueType(0),
6252 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6253 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6254 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6256 case Intrinsic::aarch64_sve_umin_x4:
6258 Node->getValueType(0),
6259 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6260 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6261 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6263 case Intrinsic::aarch64_sve_fmin_x4:
6265 Node->getValueType(0),
6266 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6267 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6268 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6270 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6272 Node->getValueType(0),
6273 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6274 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6275 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6277 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6279 Node->getValueType(0),
6280 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6281 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6282 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6284 case Intrinsic::aarch64_sve_fminnm_single_x2:
6286 Node->getValueType(0),
6287 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6288 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6289 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6291 case Intrinsic::aarch64_sve_fminnm_single_x4:
6293 Node->getValueType(0),
6294 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6295 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6296 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6298 case Intrinsic::aarch64_sve_fscale_single_x4:
6299 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6301 case Intrinsic::aarch64_sve_fscale_single_x2:
6302 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6304 case Intrinsic::aarch64_sve_fmul_single_x4:
6306 Node->getValueType(0),
6307 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6308 AArch64::FMUL_4ZZ_D}))
6309 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6311 case Intrinsic::aarch64_sve_fmul_single_x2:
6313 Node->getValueType(0),
6314 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6315 AArch64::FMUL_2ZZ_D}))
6316 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6318 case Intrinsic::aarch64_sve_fmaxnm_x2:
6320 Node->getValueType(0),
6321 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6322 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6323 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6325 case Intrinsic::aarch64_sve_fmaxnm_x4:
6327 Node->getValueType(0),
6328 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6329 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6330 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6332 case Intrinsic::aarch64_sve_fminnm_x2:
6334 Node->getValueType(0),
6335 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6336 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6337 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6339 case Intrinsic::aarch64_sve_fminnm_x4:
6341 Node->getValueType(0),
6342 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6343 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6344 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6346 case Intrinsic::aarch64_sve_aese_lane_x2:
6347 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6349 case Intrinsic::aarch64_sve_aesd_lane_x2:
6350 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6352 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6353 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6355 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6356 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6358 case Intrinsic::aarch64_sve_aese_lane_x4:
6359 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6361 case Intrinsic::aarch64_sve_aesd_lane_x4:
6362 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6364 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6365 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6367 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6368 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6370 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6371 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6373 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6377 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6379 for (
unsigned I = 0;
I < 2;
I++)
6381 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6383 CurDAG->RemoveDeadNode(Node);
6386 case Intrinsic::aarch64_sve_fscale_x4:
6387 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6389 case Intrinsic::aarch64_sve_fscale_x2:
6390 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6392 case Intrinsic::aarch64_sve_fmul_x4:
6394 Node->getValueType(0),
6395 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6396 AArch64::FMUL_4Z4Z_D}))
6397 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6399 case Intrinsic::aarch64_sve_fmul_x2:
6401 Node->getValueType(0),
6402 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6403 AArch64::FMUL_2Z2Z_D}))
6404 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6406 case Intrinsic::aarch64_sve_fcvtzs_x2:
6407 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6409 case Intrinsic::aarch64_sve_scvtf_x2:
6410 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6412 case Intrinsic::aarch64_sve_fcvtzu_x2:
6413 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6415 case Intrinsic::aarch64_sve_ucvtf_x2:
6416 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6418 case Intrinsic::aarch64_sve_fcvtzs_x4:
6419 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6421 case Intrinsic::aarch64_sve_scvtf_x4:
6422 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6424 case Intrinsic::aarch64_sve_fcvtzu_x4:
6425 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6427 case Intrinsic::aarch64_sve_ucvtf_x4:
6428 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6430 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6431 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6433 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6434 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6436 case Intrinsic::aarch64_sve_sclamp_single_x2:
6438 Node->getValueType(0),
6439 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6440 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6441 SelectClamp(Node, 2,
Op);
6443 case Intrinsic::aarch64_sve_uclamp_single_x2:
6445 Node->getValueType(0),
6446 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6447 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6448 SelectClamp(Node, 2,
Op);
6450 case Intrinsic::aarch64_sve_fclamp_single_x2:
6452 Node->getValueType(0),
6453 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6454 AArch64::FCLAMP_VG2_2Z2Z_D}))
6455 SelectClamp(Node, 2,
Op);
6457 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6458 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6460 case Intrinsic::aarch64_sve_sclamp_single_x4:
6462 Node->getValueType(0),
6463 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6464 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6465 SelectClamp(Node, 4,
Op);
6467 case Intrinsic::aarch64_sve_uclamp_single_x4:
6469 Node->getValueType(0),
6470 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6471 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6472 SelectClamp(Node, 4,
Op);
6474 case Intrinsic::aarch64_sve_fclamp_single_x4:
6476 Node->getValueType(0),
6477 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6478 AArch64::FCLAMP_VG4_4Z4Z_D}))
6479 SelectClamp(Node, 4,
Op);
6481 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6482 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6484 case Intrinsic::aarch64_sve_add_single_x2:
6486 Node->getValueType(0),
6487 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6488 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6489 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6491 case Intrinsic::aarch64_sve_add_single_x4:
6493 Node->getValueType(0),
6494 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6495 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6496 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6498 case Intrinsic::aarch64_sve_zip_x2:
6500 Node->getValueType(0),
6501 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6502 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6503 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6505 case Intrinsic::aarch64_sve_zipq_x2:
6506 SelectUnaryMultiIntrinsic(Node, 2,
false,
6507 AArch64::ZIP_VG2_2ZZZ_Q);
6509 case Intrinsic::aarch64_sve_zip_x4:
6511 Node->getValueType(0),
6512 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6513 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6514 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6516 case Intrinsic::aarch64_sve_zipq_x4:
6517 SelectUnaryMultiIntrinsic(Node, 4,
true,
6518 AArch64::ZIP_VG4_4Z4Z_Q);
6520 case Intrinsic::aarch64_sve_uzp_x2:
6522 Node->getValueType(0),
6523 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6524 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6525 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6527 case Intrinsic::aarch64_sve_uzpq_x2:
6528 SelectUnaryMultiIntrinsic(Node, 2,
false,
6529 AArch64::UZP_VG2_2ZZZ_Q);
6531 case Intrinsic::aarch64_sve_uzp_x4:
6533 Node->getValueType(0),
6534 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6535 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6536 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6538 case Intrinsic::aarch64_sve_uzpq_x4:
6539 SelectUnaryMultiIntrinsic(Node, 4,
true,
6540 AArch64::UZP_VG4_4Z4Z_Q);
6542 case Intrinsic::aarch64_sve_sel_x2:
6544 Node->getValueType(0),
6545 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6546 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6547 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6549 case Intrinsic::aarch64_sve_sel_x4:
6551 Node->getValueType(0),
6552 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6553 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6554 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6556 case Intrinsic::aarch64_sve_frinta_x2:
6557 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6559 case Intrinsic::aarch64_sve_frinta_x4:
6560 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6562 case Intrinsic::aarch64_sve_frintm_x2:
6563 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6565 case Intrinsic::aarch64_sve_frintm_x4:
6566 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6568 case Intrinsic::aarch64_sve_frintn_x2:
6569 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6571 case Intrinsic::aarch64_sve_frintn_x4:
6572 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6574 case Intrinsic::aarch64_sve_frintp_x2:
6575 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6577 case Intrinsic::aarch64_sve_frintp_x4:
6578 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6580 case Intrinsic::aarch64_sve_sunpk_x2:
6582 Node->getValueType(0),
6583 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6584 AArch64::SUNPK_VG2_2ZZ_D}))
6585 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6587 case Intrinsic::aarch64_sve_uunpk_x2:
6589 Node->getValueType(0),
6590 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6591 AArch64::UUNPK_VG2_2ZZ_D}))
6592 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6594 case Intrinsic::aarch64_sve_sunpk_x4:
6596 Node->getValueType(0),
6597 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6598 AArch64::SUNPK_VG4_4Z2Z_D}))
6599 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6601 case Intrinsic::aarch64_sve_uunpk_x4:
6603 Node->getValueType(0),
6604 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6605 AArch64::UUNPK_VG4_4Z2Z_D}))
6606 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6608 case Intrinsic::aarch64_sve_pext_x2: {
6610 Node->getValueType(0),
6611 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6612 AArch64::PEXT_2PCI_D}))
6613 SelectPExtPair(Node,
Op);
6620 unsigned IntNo =
Node->getConstantOperandVal(1);
6621 if (
Node->getNumOperands() >= 3)
6622 VT =
Node->getOperand(2)->getValueType(0);
6626 case Intrinsic::aarch64_neon_st1x2: {
6627 if (VT == MVT::v8i8) {
6628 SelectStore(Node, 2, AArch64::ST1Twov8b);
6630 }
else if (VT == MVT::v16i8) {
6631 SelectStore(Node, 2, AArch64::ST1Twov16b);
6633 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6634 VT == MVT::v4bf16) {
6635 SelectStore(Node, 2, AArch64::ST1Twov4h);
6637 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6638 VT == MVT::v8bf16) {
6639 SelectStore(Node, 2, AArch64::ST1Twov8h);
6641 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6642 SelectStore(Node, 2, AArch64::ST1Twov2s);
6644 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6645 SelectStore(Node, 2, AArch64::ST1Twov4s);
6647 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6648 SelectStore(Node, 2, AArch64::ST1Twov2d);
6650 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6651 SelectStore(Node, 2, AArch64::ST1Twov1d);
6656 case Intrinsic::aarch64_neon_st1x3: {
6657 if (VT == MVT::v8i8) {
6658 SelectStore(Node, 3, AArch64::ST1Threev8b);
6660 }
else if (VT == MVT::v16i8) {
6661 SelectStore(Node, 3, AArch64::ST1Threev16b);
6663 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6664 VT == MVT::v4bf16) {
6665 SelectStore(Node, 3, AArch64::ST1Threev4h);
6667 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6668 VT == MVT::v8bf16) {
6669 SelectStore(Node, 3, AArch64::ST1Threev8h);
6671 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6672 SelectStore(Node, 3, AArch64::ST1Threev2s);
6674 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6675 SelectStore(Node, 3, AArch64::ST1Threev4s);
6677 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6678 SelectStore(Node, 3, AArch64::ST1Threev2d);
6680 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6681 SelectStore(Node, 3, AArch64::ST1Threev1d);
6686 case Intrinsic::aarch64_neon_st1x4: {
6687 if (VT == MVT::v8i8) {
6688 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6690 }
else if (VT == MVT::v16i8) {
6691 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6693 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6694 VT == MVT::v4bf16) {
6695 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6697 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6698 VT == MVT::v8bf16) {
6699 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6701 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6702 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6704 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6705 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6707 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6708 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6710 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6711 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6716 case Intrinsic::aarch64_neon_st2: {
6717 if (VT == MVT::v8i8) {
6718 SelectStore(Node, 2, AArch64::ST2Twov8b);
6720 }
else if (VT == MVT::v16i8) {
6721 SelectStore(Node, 2, AArch64::ST2Twov16b);
6723 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6724 VT == MVT::v4bf16) {
6725 SelectStore(Node, 2, AArch64::ST2Twov4h);
6727 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6728 VT == MVT::v8bf16) {
6729 SelectStore(Node, 2, AArch64::ST2Twov8h);
6731 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6732 SelectStore(Node, 2, AArch64::ST2Twov2s);
6734 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6735 SelectStore(Node, 2, AArch64::ST2Twov4s);
6737 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6738 SelectStore(Node, 2, AArch64::ST2Twov2d);
6740 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6741 SelectStore(Node, 2, AArch64::ST1Twov1d);
6746 case Intrinsic::aarch64_neon_st3: {
6747 if (VT == MVT::v8i8) {
6748 SelectStore(Node, 3, AArch64::ST3Threev8b);
6750 }
else if (VT == MVT::v16i8) {
6751 SelectStore(Node, 3, AArch64::ST3Threev16b);
6753 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6754 VT == MVT::v4bf16) {
6755 SelectStore(Node, 3, AArch64::ST3Threev4h);
6757 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6758 VT == MVT::v8bf16) {
6759 SelectStore(Node, 3, AArch64::ST3Threev8h);
6761 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6762 SelectStore(Node, 3, AArch64::ST3Threev2s);
6764 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6765 SelectStore(Node, 3, AArch64::ST3Threev4s);
6767 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6768 SelectStore(Node, 3, AArch64::ST3Threev2d);
6770 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6771 SelectStore(Node, 3, AArch64::ST1Threev1d);
6776 case Intrinsic::aarch64_neon_st4: {
6777 if (VT == MVT::v8i8) {
6778 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6780 }
else if (VT == MVT::v16i8) {
6781 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6783 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6784 VT == MVT::v4bf16) {
6785 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6787 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6788 VT == MVT::v8bf16) {
6789 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6791 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6792 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6794 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6795 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6797 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6798 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6800 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6801 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6806 case Intrinsic::aarch64_neon_st2lane: {
6807 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6808 SelectStoreLane(Node, 2, AArch64::ST2i8);
6810 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6811 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6812 SelectStoreLane(Node, 2, AArch64::ST2i16);
6814 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6816 SelectStoreLane(Node, 2, AArch64::ST2i32);
6818 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6820 SelectStoreLane(Node, 2, AArch64::ST2i64);
6825 case Intrinsic::aarch64_neon_st3lane: {
6826 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6827 SelectStoreLane(Node, 3, AArch64::ST3i8);
6829 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6830 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6831 SelectStoreLane(Node, 3, AArch64::ST3i16);
6833 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6835 SelectStoreLane(Node, 3, AArch64::ST3i32);
6837 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6839 SelectStoreLane(Node, 3, AArch64::ST3i64);
6844 case Intrinsic::aarch64_neon_st4lane: {
6845 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6846 SelectStoreLane(Node, 4, AArch64::ST4i8);
6848 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6849 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6850 SelectStoreLane(Node, 4, AArch64::ST4i16);
6852 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6854 SelectStoreLane(Node, 4, AArch64::ST4i32);
6856 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6858 SelectStoreLane(Node, 4, AArch64::ST4i64);
6863 case Intrinsic::aarch64_sve_st2q: {
6864 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6867 case Intrinsic::aarch64_sve_st3q: {
6868 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6871 case Intrinsic::aarch64_sve_st4q: {
6872 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6875 case Intrinsic::aarch64_sve_st2: {
6876 if (VT == MVT::nxv16i8) {
6877 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6879 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6880 VT == MVT::nxv8bf16) {
6881 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6883 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6884 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6886 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6887 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6892 case Intrinsic::aarch64_sve_st3: {
6893 if (VT == MVT::nxv16i8) {
6894 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6896 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6897 VT == MVT::nxv8bf16) {
6898 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6900 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6901 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6903 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6904 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6909 case Intrinsic::aarch64_sve_st4: {
6910 if (VT == MVT::nxv16i8) {
6911 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6913 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6914 VT == MVT::nxv8bf16) {
6915 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6917 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6918 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6920 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6921 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6929 case AArch64ISD::LD2post: {
6930 if (VT == MVT::v8i8) {
6931 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6933 }
else if (VT == MVT::v16i8) {
6934 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6936 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6937 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6939 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6940 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6942 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6943 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6945 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6946 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6948 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6949 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6951 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6952 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6957 case AArch64ISD::LD3post: {
6958 if (VT == MVT::v8i8) {
6959 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6961 }
else if (VT == MVT::v16i8) {
6962 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6964 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6965 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6967 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6968 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6970 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6971 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6973 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6974 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6976 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6977 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6979 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6980 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6985 case AArch64ISD::LD4post: {
6986 if (VT == MVT::v8i8) {
6987 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6989 }
else if (VT == MVT::v16i8) {
6990 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6992 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6993 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6995 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6996 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6998 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6999 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7001 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7002 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7004 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7005 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7007 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7008 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7013 case AArch64ISD::LD1x2post: {
7014 if (VT == MVT::v8i8) {
7015 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7017 }
else if (VT == MVT::v16i8) {
7018 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7020 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7021 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7023 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7024 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7026 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7027 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7029 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7030 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7032 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7033 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7035 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7036 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7041 case AArch64ISD::LD1x3post: {
7042 if (VT == MVT::v8i8) {
7043 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7045 }
else if (VT == MVT::v16i8) {
7046 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7048 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7049 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7051 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7052 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7054 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7055 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7057 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7058 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7060 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7061 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7063 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7064 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7069 case AArch64ISD::LD1x4post: {
7070 if (VT == MVT::v8i8) {
7071 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7073 }
else if (VT == MVT::v16i8) {
7074 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7076 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7077 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7079 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7080 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7082 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7083 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7085 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7086 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7088 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7089 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7091 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7092 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7097 case AArch64ISD::LD1DUPpost: {
7098 if (VT == MVT::v8i8) {
7099 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7101 }
else if (VT == MVT::v16i8) {
7102 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7104 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7105 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7107 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7108 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7110 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7111 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7113 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7114 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7116 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7117 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7119 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7120 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7125 case AArch64ISD::LD2DUPpost: {
7126 if (VT == MVT::v8i8) {
7127 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7129 }
else if (VT == MVT::v16i8) {
7130 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7132 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7133 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7135 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7136 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7138 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7139 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7141 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7142 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7144 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7145 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7147 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7148 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7153 case AArch64ISD::LD3DUPpost: {
7154 if (VT == MVT::v8i8) {
7155 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7157 }
else if (VT == MVT::v16i8) {
7158 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7160 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7161 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7163 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7164 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7166 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7167 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7169 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7170 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7172 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7173 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7175 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7176 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7181 case AArch64ISD::LD4DUPpost: {
7182 if (VT == MVT::v8i8) {
7183 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7185 }
else if (VT == MVT::v16i8) {
7186 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7188 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7189 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7191 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7192 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7194 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7195 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7197 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7198 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7200 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7201 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7203 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7204 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7209 case AArch64ISD::LD1LANEpost: {
7210 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7211 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7213 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7214 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7215 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7217 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7219 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7221 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7223 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7228 case AArch64ISD::LD2LANEpost: {
7229 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7230 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7232 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7233 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7234 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7236 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7238 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7240 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7242 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7247 case AArch64ISD::LD3LANEpost: {
7248 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7249 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7251 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7252 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7253 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7255 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7257 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7259 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7261 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7266 case AArch64ISD::LD4LANEpost: {
7267 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7268 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7270 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7271 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7272 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7274 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7276 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7278 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7280 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7285 case AArch64ISD::ST2post: {
7286 VT =
Node->getOperand(1).getValueType();
7287 if (VT == MVT::v8i8) {
7288 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7290 }
else if (VT == MVT::v16i8) {
7291 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7293 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7294 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7296 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7297 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7299 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7300 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7302 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7303 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7305 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7306 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7308 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7309 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7314 case AArch64ISD::ST3post: {
7315 VT =
Node->getOperand(1).getValueType();
7316 if (VT == MVT::v8i8) {
7317 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7319 }
else if (VT == MVT::v16i8) {
7320 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7322 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7323 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7325 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7326 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7328 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7329 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7331 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7332 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7334 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7335 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7337 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7338 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7343 case AArch64ISD::ST4post: {
7344 VT =
Node->getOperand(1).getValueType();
7345 if (VT == MVT::v8i8) {
7346 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7348 }
else if (VT == MVT::v16i8) {
7349 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7351 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7352 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7354 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7355 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7357 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7358 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7360 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7361 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7363 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7364 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7366 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7367 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7372 case AArch64ISD::ST1x2post: {
7373 VT =
Node->getOperand(1).getValueType();
7374 if (VT == MVT::v8i8) {
7375 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7377 }
else if (VT == MVT::v16i8) {
7378 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7380 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7381 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7383 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7384 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7386 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7387 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7389 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7390 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7392 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7393 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7395 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7396 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7401 case AArch64ISD::ST1x3post: {
7402 VT =
Node->getOperand(1).getValueType();
7403 if (VT == MVT::v8i8) {
7404 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7406 }
else if (VT == MVT::v16i8) {
7407 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7409 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7410 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7412 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7413 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7415 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7416 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7418 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7419 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7421 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7422 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7424 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7425 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7430 case AArch64ISD::ST1x4post: {
7431 VT =
Node->getOperand(1).getValueType();
7432 if (VT == MVT::v8i8) {
7433 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7435 }
else if (VT == MVT::v16i8) {
7436 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7438 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7439 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7441 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7442 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7444 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7445 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7447 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7448 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7450 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7451 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7453 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7454 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7459 case AArch64ISD::ST2LANEpost: {
7460 VT =
Node->getOperand(1).getValueType();
7461 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7462 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7464 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7465 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7466 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7468 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7470 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7472 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7474 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7479 case AArch64ISD::ST3LANEpost: {
7480 VT =
Node->getOperand(1).getValueType();
7481 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7482 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7484 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7485 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7486 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7488 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7490 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7492 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7494 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7499 case AArch64ISD::ST4LANEpost: {
7500 VT =
Node->getOperand(1).getValueType();
7501 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7502 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7504 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7505 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7506 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7508 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7510 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7512 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7514 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7529 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7541 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7545 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7546 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7561 return MemIntr->getMemoryVT();
7568 DataVT = Load->getValueType(0);
7570 DataVT = Load->getValueType(0);
7572 DataVT = Store->getValue().getValueType();
7574 DataVT = Store->getValue().getValueType();
7581 const unsigned Opcode = Root->
getOpcode();
7585 case AArch64ISD::LD1_MERGE_ZERO:
7586 case AArch64ISD::LD1S_MERGE_ZERO:
7587 case AArch64ISD::LDNF1_MERGE_ZERO:
7588 case AArch64ISD::LDNF1S_MERGE_ZERO:
7590 case AArch64ISD::ST1_PRED:
7602 case Intrinsic::aarch64_sme_ldr:
7603 case Intrinsic::aarch64_sme_str:
7604 return MVT::nxv16i8;
7605 case Intrinsic::aarch64_sve_prf:
7610 case Intrinsic::aarch64_sve_ld2_sret:
7611 case Intrinsic::aarch64_sve_ld2q_sret:
7614 case Intrinsic::aarch64_sve_st2q:
7617 case Intrinsic::aarch64_sve_ld3_sret:
7618 case Intrinsic::aarch64_sve_ld3q_sret:
7621 case Intrinsic::aarch64_sve_st3q:
7624 case Intrinsic::aarch64_sve_ld4_sret:
7625 case Intrinsic::aarch64_sve_ld4q_sret:
7628 case Intrinsic::aarch64_sve_st4q:
7631 case Intrinsic::aarch64_sve_ld1udq:
7632 case Intrinsic::aarch64_sve_st1dq:
7633 return EVT(MVT::nxv1i64);
7634 case Intrinsic::aarch64_sve_ld1uwq:
7635 case Intrinsic::aarch64_sve_st1wq:
7636 return EVT(MVT::nxv1i32);
7643template <
int64_t Min,
int64_t Max>
7644bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7648 const DataLayout &
DL = CurDAG->getDataLayout();
7649 const MachineFrameInfo &MFI = MF->getFrameInfo();
7657 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7671 int64_t MulImm = std::numeric_limits<int64_t>::max();
7675 int64_t ByteOffset =
C->getSExtValue();
7676 const auto KnownVScale =
7679 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7682 MulImm = ByteOffset / KnownVScale;
7689 if ((MulImm % MemWidthBytes) != 0)
7692 int64_t
Offset = MulImm / MemWidthBytes;
7696 Base =
N.getOperand(0);
7705 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7711bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7730 int64_t ImmOff =
C->getSExtValue();
7731 unsigned Size = 1 << Scale;
7740 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7742 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7753 if (
C->getZExtValue() == Scale) {
7762bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7763 const AArch64TargetLowering *TLI =
7764 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7769bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7770 EVT VT =
N.getValueType();
7774bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7779 int64_t ImmOff =
C->getSExtValue();
7780 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7781 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7786 if (
SDValue C = MatchConstantOffset(
N)) {
7787 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7793 if (CurDAG->isBaseWithConstantOffset(
N)) {
7794 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7795 Base =
N.getOperand(0);
7803 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7807bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7827 uint64_t LowerBound = 0, UpperBound = 64;
7845 if (CN->getAPIntValue().uge(LowerBound) &&
7846 CN->getAPIntValue().ult(UpperBound)) {
7848 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7856template <
bool MatchCBB>
7863 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7865 Reg =
N.getOperand(0);
7867 SDLoc(
N), MVT::i32);
7875 Reg =
N.getOperand(0);
7884void AArch64DAGToDAGISel::PreprocessISelDAG() {
7885 bool MadeChange =
false;
7891 switch (
N.getOpcode()) {
7893 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
7894 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
7895 ScalarTy ==
N.getOperand(0).getValueType())
7905 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
7911 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(&
N, 0), Result);
7917 CurDAG->RemoveDeadNodes();
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static SDValue addBitcastHints(SelectionDAG &DAG, SDNode &N)
addBitcastHints - This method adds bitcast hints to the operands of a node to help instruction select...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static bool isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static SDValue WidenVector(SDValue V64Reg, SelectionDAG &DAG)
WidenVector - Given a value in the V64 register class, produce the equivalent value in the V128 regis...
static Register createDTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of D-registers using the registers in Regs.
static Register createQTuple(ArrayRef< Register > Regs, MachineIRBuilder &MIB)
Create a tuple of Q-registers using the registers in Regs.
static Register createTuple(ArrayRef< Register > Regs, const unsigned RegClassIDs[], const unsigned SubRegs[], MachineIRBuilder &MIB)
Create a REG_SEQUENCE instruction using the registers in Regs.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const AArch64RegisterInfo * getRegisterInfo() const override
bool isLittleEndian() const
bool isStreaming() const
Returns true if the function has a streaming body.
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
unsigned getSVEVectorSizeInBits() const
bool isAllActivePredicate(SelectionDAG &DAG, SDValue N) const
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
void flipAllBits()
Toggle every bit to its opposite value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getOpcode() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
unsigned getID() const
Return the register class ID number.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint32_t parseGenericRegister(StringRef Name)
static uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize)
decodeLogicalImmediate - Decode a logical immediate value in the form "N:immr:imms" (where the immr a...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t decodeAdvSIMDModImmType12(uint8_t Imm)
static uint64_t decodeAdvSIMDModImmType11(uint8_t Imm)
unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET)
Mapping from extend bits to required operation: shifter: 000 ==> uxtb 001 ==> uxth 010 ==> uxtw 011 =...
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
static constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Not(const Pred &P) -> Not< Pred >
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Undef
Value of the register doesn't matter.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.
unsigned getBitWidth() const
Get the bit width of this value.