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;
67 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
69 std::vector<SDValue> &OutOps)
override;
71 template <
signed Low,
signed High,
signed Scale>
74 template <
signed Low,
signed High>
82 return SelectShiftedRegister(
N,
false,
Reg, Shift);
85 return SelectShiftedRegister(
N,
true,
Reg, Shift);
88 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
91 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
94 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
97 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
100 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
103 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
106 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
109 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
112 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
115 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
118 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
121 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
124 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
127 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
130 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
133 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
136 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
138 template <
unsigned Size,
unsigned Max>
142 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
145 int64_t
C = CI->getSExtValue();
153 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
160 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
166 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
171 N =
N->getOperand(0);
175 EVT VT =
N->getValueType(0);
176 EVT LVT =
N->getOperand(0).getValueType();
177 unsigned Index =
N->getConstantOperandVal(1);
181 Res =
N->getOperand(0);
186 if (
N.getOpcode() != AArch64ISD::VLSHR)
189 EVT VT =
Op.getValueType();
190 unsigned ShtAmt =
N->getConstantOperandVal(1);
195 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
197 Op.getOperand(1).getConstantOperandVal(0)
198 <<
Op.getOperand(1).getConstantOperandVal(1));
199 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
202 Op.getOperand(1).getConstantOperandVal(0));
206 if (Imm != 1ULL << (ShtAmt - 1))
209 Res1 =
Op.getOperand(0);
210 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
214 bool SelectDupZeroOrUndef(
SDValue N) {
215 switch(
N->getOpcode()) {
218 case AArch64ISD::DUP:
220 auto Opnd0 =
N->getOperand(0);
234 bool SelectAny(
SDValue) {
return true; }
237 switch(
N->getOpcode()) {
238 case AArch64ISD::DUP:
240 auto Opnd0 =
N->getOperand(0);
252 template <MVT::SimpleValueType VT,
bool Negate>
254 return SelectSVEAddSubImm(
N, VT, Imm, Shift, Negate);
257 template <MVT::SimpleValueType VT,
bool Negate>
259 return SelectSVEAddSubSSatImm(
N, VT, Imm, Shift, Negate);
262 template <MVT::SimpleValueType VT>
264 return SelectSVECpyDupImm(
N, VT, Imm, Shift);
267 template <MVT::SimpleValueType VT,
bool Invert = false>
269 return SelectSVELogicalImm(
N, VT, Imm, Invert);
272 template <MVT::SimpleValueType VT>
274 return SelectSVEArithImm(
N, VT, Imm);
277 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
279 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation, Imm);
286 EVT EltVT =
N->getValueType(0).getVectorElementType();
287 return SelectSVEShiftImm(
N->getOperand(0), 1,
293 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
300 MulImm = 1LL << MulImm;
302 if ((MulImm % std::abs(Scale)) != 0)
306 if ((MulImm >= Min) && (MulImm <= Max)) {
307 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
314 template <
signed Max,
signed Scale>
321 if (MulImm >= 0 && MulImm <= Max) {
323 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
330 template <
unsigned BaseReg,
unsigned Max>
338 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
361 const unsigned SubRegs[]);
363 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
365 bool tryIndexedLoad(
SDNode *
N);
367 void SelectPtrauthAuth(
SDNode *
N);
368 void SelectPtrauthResign(
SDNode *
N);
370 bool trySelectStackSlotTagP(
SDNode *
N);
373 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
375 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
377 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
378 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
379 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
380 unsigned Opc_rr,
unsigned Opc_ri,
381 bool IsIntr =
false);
382 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
383 unsigned Scale,
unsigned Opc_ri,
385 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
386 bool IsZmMulti,
unsigned Opcode,
387 bool HasPred =
false);
389 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
390 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
391 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
392 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
393 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
394 bool IsTupleInput,
unsigned Opc);
395 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
397 template <
unsigned MaxIdx,
unsigned Scale>
398 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
400 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
401 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
402 unsigned BaseReg = 0);
405 template <
int64_t Min,
int64_t Max>
409 template <
unsigned Scale>
411 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
414 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
417 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc);
419 template <
unsigned MaxIdx,
unsigned Scale>
424 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
425 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
426 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
427 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
428 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
429 unsigned Opc_rr,
unsigned Opc_ri);
430 std::tuple<unsigned, SDValue, SDValue>
431 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
435 bool tryBitfieldExtractOp(
SDNode *
N);
436 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
437 bool tryBitfieldInsertOp(
SDNode *
N);
438 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
439 bool tryShiftAmountMod(
SDNode *
N);
441 bool tryReadRegister(
SDNode *
N);
442 bool tryWriteRegister(
SDNode *
N);
444 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
445 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
450#include "AArch64GenDAGISel.inc"
458 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
460 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
473 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
474 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
475 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
478 template<
unsigned RegW
idth>
480 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
482 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
484 template <
unsigned RegW
idth>
486 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
488 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
490 template<
unsigned RegW
idth>
492 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
498 bool SelectCMP_SWAP(
SDNode *
N);
509 bool AllowSaturation,
SDValue &Imm);
517 bool SelectAllActivePredicate(
SDValue N);
522 template <
bool MatchCBB>
532 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
536char AArch64DAGToDAGISelLegacy::ID = 0;
544 Imm =
C->getZExtValue();
561 return N->getOpcode() ==
Opc &&
572 return Imm == ImmExpected;
576bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
578 std::vector<SDValue> &OutOps) {
579 switch(ConstraintID) {
582 case InlineAsm::ConstraintCode::m:
583 case InlineAsm::ConstraintCode::o:
584 case InlineAsm::ConstraintCode::Q:
588 const TargetRegisterClass *TRC =
TRI->getPointerRegClass();
590 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
592 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
593 dl,
Op.getValueType(),
595 OutOps.push_back(NewOp);
614 uint64_t Immed =
N.getNode()->getAsZExtVal();
617 if (Immed >> 12 == 0) {
619 }
else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
627 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
628 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
645 uint64_t Immed =
N.getNode()->getAsZExtVal();
653 if (
N.getValueType() == MVT::i32)
654 Immed = ~((uint32_t)Immed) + 1;
656 Immed = ~Immed + 1ULL;
657 if (Immed & 0xFFFFFFFFFF000000ULL)
660 Immed &= 0xFFFFFFULL;
661 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
668 switch (
N.getOpcode()) {
694 unsigned ShiftVal = CSD->getZExtValue();
712bool AArch64DAGToDAGISel::isWorthFoldingAddr(
SDValue V,
unsigned Size)
const {
715 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
720 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
744 EVT VT =
N.getValueType();
745 if (VT != MVT::i32 && VT != MVT::i64)
748 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
754 unsigned LHSOpcode =
LHS->getOpcode();
768 unsigned LowZBits, MaskLen;
772 unsigned BitWidth =
N.getValueSizeInBits();
779 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
782 NewShiftC = LowZBits - ShiftAmtC;
783 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
789 NewShiftC = LowZBits + ShiftAmtC;
802 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
804 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
808 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
810 Reg =
SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
811 NewShiftAmt, BitWidthMinus1),
814 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
828 SrcVT =
N.getOperand(0).getValueType();
830 if (!IsLoadStore && SrcVT == MVT::i8)
832 else if (!IsLoadStore && SrcVT == MVT::i16)
834 else if (SrcVT == MVT::i32)
836 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
841 EVT SrcVT =
N.getOperand(0).getValueType();
842 if (!IsLoadStore && SrcVT == MVT::i8)
844 else if (!IsLoadStore && SrcVT == MVT::i16)
846 else if (SrcVT == MVT::i32)
848 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
876bool AArch64DAGToDAGISel::isWorthFoldingALU(
SDValue V,
bool LSL)
const {
879 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
884 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
885 V.getConstantOperandVal(1) <= 4 &&
898bool AArch64DAGToDAGISel::SelectShiftedRegister(
SDValue N,
bool AllowROR,
900 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
910 unsigned BitSize =
N.getValueSizeInBits();
911 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
914 Reg =
N.getOperand(0);
915 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
916 return isWorthFoldingALU(
N,
true);
927 if (
N.getValueType() == MVT::i32)
935template<
signed Low,
signed High,
signed Scale>
941 if ((MulImm % std::abs(Scale)) == 0) {
942 int64_t RDVLImm = MulImm / Scale;
943 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
944 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
953template <
signed Low,
signed High>
954bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(
SDValue N,
SDValue &Imm) {
959 if (MulImm >=
Low && MulImm <=
High) {
960 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
971 unsigned ShiftVal = 0;
986 Reg =
N.getOperand(0).getOperand(0);
992 Reg =
N.getOperand(0);
997 unsigned Opc =
N.getOpcode();
1015 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1017 return isWorthFoldingALU(
N);
1024 unsigned ShiftVal = 0;
1038 Reg =
N.getOperand(0);
1039 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1041 return isWorthFoldingALU(
N);
1050 for (
auto *
User :
N->users()) {
1077bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
1078 unsigned BW,
unsigned Size,
1082 const DataLayout &
DL = CurDAG->getDataLayout();
1083 const TargetLowering *TLI = getTargetLowering();
1087 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1093 if (CurDAG->isBaseWithConstantOffset(
N)) {
1096 int64_t RHSC =
RHS->getSExtValue();
1098 int64_t
Range = 0x1LL << (BW - 1);
1100 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1101 RHSC < (
Range << Scale)) {
1102 Base =
N.getOperand(0);
1107 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1112 uint64_t RHSC =
RHS->getZExtValue();
1114 uint64_t
Range = 0x1ULL << BW;
1116 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1117 Base =
N.getOperand(0);
1122 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1133 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1140bool AArch64DAGToDAGISel::SelectAddrModeIndexed(
SDValue N,
unsigned Size,
1143 const DataLayout &
DL = CurDAG->getDataLayout();
1144 const TargetLowering *TLI = getTargetLowering();
1148 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1153 GlobalAddressSDNode *GAN =
1155 Base =
N.getOperand(0);
1165 if (CurDAG->isBaseWithConstantOffset(
N)) {
1167 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1170 Base =
N.getOperand(0);
1175 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1183 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1191 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1200bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(
SDValue N,
unsigned Size,
1203 if (!CurDAG->isBaseWithConstantOffset(
N))
1206 int64_t RHSC =
RHS->getSExtValue();
1207 if (RHSC >= -256 && RHSC < 256) {
1208 Base =
N.getOperand(0);
1211 const TargetLowering *TLI = getTargetLowering();
1212 Base = CurDAG->getTargetFrameIndex(
1215 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1225 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1232bool AArch64DAGToDAGISel::SelectExtendedSHL(
SDValue N,
unsigned Size,
1252 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1258 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1261 return isWorthFoldingAddr(
N,
Size);
1264bool AArch64DAGToDAGISel::SelectAddrModeWRO(
SDValue N,
unsigned Size,
1282 const SDNode *
Node =
N.getNode();
1283 for (SDNode *UI :
Node->users()) {
1289 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1292 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1295 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1300 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1303 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1308 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1312 if (IsExtendedRegisterWorthFolding &&
1319 if (isWorthFoldingAddr(
LHS,
Size))
1324 if (IsExtendedRegisterWorthFolding &&
1331 if (isWorthFoldingAddr(
RHS,
Size))
1343 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1346 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1348 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1349 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1353bool AArch64DAGToDAGISel::SelectAddrModeXRO(
SDValue N,
unsigned Size,
1366 const SDNode *
Node =
N.getNode();
1367 for (SDNode *UI :
Node->users()) {
1384 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1394 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1401 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1404 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1407 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1412 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1415 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1422 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1423 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1429 static const unsigned RegClassIDs[] = {
1430 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1431 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1432 AArch64::dsub2, AArch64::dsub3};
1438 static const unsigned RegClassIDs[] = {
1439 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1440 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1441 AArch64::qsub2, AArch64::qsub3};
1447 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1448 AArch64::ZPR3RegClassID,
1449 AArch64::ZPR4RegClassID};
1450 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1451 AArch64::zsub2, AArch64::zsub3};
1461 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1462 AArch64::ZPR4Mul4RegClassID};
1463 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1464 AArch64::zsub2, AArch64::zsub3};
1469 const unsigned RegClassIDs[],
1470 const unsigned SubRegs[]) {
1473 if (Regs.
size() == 1)
1484 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1487 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1488 Ops.push_back(Regs[i]);
1489 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1493 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1497void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1500 EVT VT =
N->getValueType(0);
1502 unsigned ExtOff = isExt;
1505 unsigned Vec0Off = ExtOff + 1;
1511 Ops.push_back(
N->getOperand(1));
1512 Ops.push_back(RegSeq);
1513 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1514 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1517static std::tuple<SDValue, SDValue>
1538 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1543 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1545 return std::make_tuple(
1550void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1555 SDValue AUTDisc =
N->getOperand(3);
1558 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1560 SDValue AUTAddrDisc, AUTConstDisc;
1561 std::tie(AUTConstDisc, AUTAddrDisc) =
1565 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1567 if (
N->getNumOperands() > 4)
1568 Ops.push_back(
N->getOperand(4));
1571 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1572 ReplaceNode(
N, AUT);
1574 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1575 AArch64::X16, Val,
SDValue());
1578 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1579 ReplaceNode(
N, AUT);
1583void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1593 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1598 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1599 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1601 SDValue AUTAddrDisc, AUTConstDisc;
1602 std::tie(AUTConstDisc, AUTAddrDisc) =
1605 SDValue PACAddrDisc, PACConstDisc;
1606 std::tie(PACConstDisc, PACAddrDisc) =
1609 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1610 AArch64::X16, Val,
SDValue());
1613 SDValue Addend =
N->getOperand(OffsetBase + 6);
1614 SDValue IncomingChain =
N->getOperand(0);
1615 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1616 PACKey, PACConstDisc, PACAddrDisc,
1617 Addend, IncomingChain, X16Copy.
getValue(1)};
1619 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1620 MVT::i64, MVT::Other,
Ops);
1621 ReplaceNode(
N, AUTRELLOADPAC);
1623 SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1624 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1626 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1627 ReplaceNode(
N, AUTPAC);
1631bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1633 if (
LD->isUnindexed())
1635 EVT VT =
LD->getMemoryVT();
1636 EVT DstVT =
N->getValueType(0);
1640 int OffsetVal = (int)
OffsetOp->getZExtValue();
1645 unsigned Opcode = 0;
1648 bool InsertTo64 =
false;
1650 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1651 else if (VT == MVT::i32) {
1653 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1655 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1657 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1663 }
else if (VT == MVT::i16) {
1665 if (DstVT == MVT::i64)
1666 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1668 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1670 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1671 InsertTo64 = DstVT == MVT::i64;
1676 }
else if (VT == MVT::i8) {
1678 if (DstVT == MVT::i64)
1679 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1681 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1683 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1684 InsertTo64 = DstVT == MVT::i64;
1689 }
else if (VT == MVT::f16) {
1690 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1691 }
else if (VT == MVT::bf16) {
1692 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1693 }
else if (VT == MVT::f32) {
1694 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1695 }
else if (VT == MVT::f64 ||
1697 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1699 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1701 if (IsPre || OffsetVal != 8)
1705 Opcode = AArch64::LD1Onev8b_POST;
1708 Opcode = AArch64::LD1Onev4h_POST;
1711 Opcode = AArch64::LD1Onev2s_POST;
1714 Opcode = AArch64::LD1Onev1d_POST;
1720 if (IsPre || OffsetVal != 16)
1724 Opcode = AArch64::LD1Onev16b_POST;
1727 Opcode = AArch64::LD1Onev8h_POST;
1730 Opcode = AArch64::LD1Onev4s_POST;
1733 Opcode = AArch64::LD1Onev2d_POST;
1745 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1746 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1748 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1758 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1759 LoadedVal =
SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1760 MVT::i64, LoadedVal,
SubReg),
1764 ReplaceUses(
SDValue(
N, 0), LoadedVal);
1767 CurDAG->RemoveDeadNode(
N);
1771void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1772 unsigned SubRegIdx) {
1774 EVT VT =
N->getValueType(0);
1780 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
1782 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1784 for (
unsigned i = 0; i < NumVecs; ++i)
1786 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1793 MachineMemOperand *MemOp = MemIntr->getMemOperand();
1797 CurDAG->RemoveDeadNode(
N);
1800void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
1801 unsigned Opc,
unsigned SubRegIdx) {
1803 EVT VT =
N->getValueType(0);
1810 const EVT ResTys[] = {MVT::i64,
1811 MVT::Untyped, MVT::Other};
1813 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
1821 ReplaceUses(
SDValue(
N, 0), SuperReg);
1823 for (
unsigned i = 0; i < NumVecs; ++i)
1825 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
1829 CurDAG->RemoveDeadNode(
N);
1835std::tuple<unsigned, SDValue, SDValue>
1836AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
1842 SDValue NewOffset = OldOffset;
1844 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
1845 N, OldBase, NewBase, NewOffset);
1849 const bool IsRegReg =
1850 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
1853 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
1866template <SelectTypeKind Kind>
1878 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
1883 if (EltVT != MVT::i1)
1887 if (EltVT == MVT::bf16)
1889 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
1919void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
1922 if (
Imm->getZExtValue() > 1)
1926 EVT VT =
N->getValueType(0);
1928 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1931 for (
unsigned I = 0;
I < 2; ++
I)
1932 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1933 AArch64::psub0 +
I,
DL, VT, SuperReg));
1935 CurDAG->RemoveDeadNode(
N);
1938void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
1940 EVT VT =
N->getValueType(0);
1944 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
1947 for (
unsigned I = 0;
I < 2; ++
I)
1948 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
1949 AArch64::psub0 +
I,
DL, VT, SuperReg));
1951 CurDAG->RemoveDeadNode(
N);
1954void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
1956 EVT VT =
N->getValueType(0);
1960 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
1962 for (
unsigned i = 0; i < NumVecs; ++i)
1963 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1964 AArch64::zsub0 + i,
DL, VT, SuperReg));
1966 CurDAG->RemoveDeadNode(
N);
1969void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
1972 EVT VT =
N->getValueType(0);
1974 Ops.push_back(
N->getOperand(0));
1977 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
1980 for (
unsigned i = 0; i < NumVecs; ++i)
1981 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
1982 AArch64::zsub0 + i,
DL, VT, SuperReg));
1985 unsigned ChainIdx = NumVecs;
1987 CurDAG->RemoveDeadNode(
N);
1990void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
1995 assert(Opcode != 0 &&
"Unexpected opcode");
1998 EVT VT =
N->getValueType(0);
1999 SDUse *OpsIter =
N->op_begin() + 1;
2002 auto GetMultiVecOperand = [&]() {
2005 return createZMulTuple(Regs);
2009 Ops.push_back(*OpsIter++);
2011 Ops.push_back(GetMultiVecOperand());
2013 Ops.push_back(GetMultiVecOperand());
2015 Ops.push_back(*OpsIter++);
2018 Ops.append(OpsIter,
N->op_end());
2020 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2022 for (
unsigned i = 0; i < NumVecs; ++i)
2023 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2024 AArch64::zsub0 + i,
DL, VT, SuperReg));
2026 CurDAG->RemoveDeadNode(
N);
2029void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2030 unsigned Scale,
unsigned Opc_ri,
2031 unsigned Opc_rr,
bool IsIntr) {
2032 assert(Scale < 5 &&
"Invalid scaling value.");
2034 EVT VT =
N->getValueType(0);
2041 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2042 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2048 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2050 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2052 for (
unsigned i = 0; i < NumVecs; ++i)
2053 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2054 AArch64::zsub0 + i,
DL, VT, SuperReg));
2057 unsigned ChainIdx = NumVecs;
2059 CurDAG->RemoveDeadNode(
N);
2062void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2067 assert(Scale < 4 &&
"Invalid scaling value.");
2069 EVT VT =
N->getValueType(0);
2077 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2083 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2085 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2087 for (
unsigned i = 0; i < NumVecs; ++i)
2088 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2089 AArch64::zsub0 + i,
DL, VT, SuperReg));
2092 unsigned ChainIdx = NumVecs;
2094 CurDAG->RemoveDeadNode(
N);
2097void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2099 if (
N->getValueType(0) != MVT::nxv4f32)
2101 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2104void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2105 unsigned NumOutVecs,
2109 if (
Imm->getZExtValue() > MaxImm)
2113 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2119 EVT VT =
Node->getValueType(0);
2122 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2125 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2126 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2127 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2130 unsigned ChainIdx = NumOutVecs;
2132 CurDAG->RemoveDeadNode(Node);
2135void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2136 unsigned NumOutVecs,
2139 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2144 createZMulTuple({
Node->getOperand(3),
Node->getOperand(4)}),
2148 EVT VT =
Node->getValueType(0);
2151 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2154 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2155 ReplaceUses(
SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2156 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2159 unsigned ChainIdx = NumOutVecs;
2161 CurDAG->RemoveDeadNode(Node);
2164void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2167 EVT VT =
N->getValueType(0);
2170 SDValue Zd = createZMulTuple(Regs);
2171 SDValue Zn =
N->getOperand(1 + NumVecs);
2172 SDValue Zm =
N->getOperand(2 + NumVecs);
2178 for (
unsigned i = 0; i < NumVecs; ++i)
2179 ReplaceUses(
SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2180 AArch64::zsub0 + i,
DL, VT, SuperReg));
2182 CurDAG->RemoveDeadNode(
N);
2212template <
unsigned MaxIdx,
unsigned Scale>
2213void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2214 unsigned BaseReg,
unsigned Op) {
2215 unsigned TileNum = 0;
2216 if (BaseReg != AArch64::ZA)
2217 TileNum =
N->getConstantOperandVal(2);
2223 if (BaseReg == AArch64::ZA)
2228 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2234 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2236 EVT VT =
N->getValueType(0);
2237 for (
unsigned I = 0;
I < NumVecs; ++
I)
2239 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2242 unsigned ChainIdx = NumVecs;
2244 CurDAG->RemoveDeadNode(
N);
2247void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2248 unsigned Op,
unsigned MaxIdx,
2249 unsigned Scale,
unsigned BaseReg) {
2254 if (BaseReg != AArch64::ZA)
2258 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2265 if (BaseReg != AArch64::ZA )
2266 Ops.push_back(
N->getOperand(2));
2269 Ops.push_back(
N->getOperand(0));
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,
2279 unsigned ChainIdx = NumVecs;
2281 CurDAG->RemoveDeadNode(
N);
2284void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2285 unsigned NumOutVecs,
2289 EVT VT =
N->getValueType(0);
2290 unsigned NumInVecs =
N->getNumOperands() - 1;
2294 assert((NumInVecs == 2 || NumInVecs == 4) &&
2295 "Don't know how to handle multi-register input!");
2297 Ops.push_back(createZMulTuple(Regs));
2300 for (
unsigned I = 0;
I < NumInVecs;
I++)
2301 Ops.push_back(
N->getOperand(1 +
I));
2304 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2307 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2308 ReplaceUses(
SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2309 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2310 CurDAG->RemoveDeadNode(
N);
2313void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2316 EVT VT =
N->getOperand(2)->getValueType(0);
2324 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2333void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2334 unsigned Scale,
unsigned Opc_rr,
2340 SDValue RegSeq = createZTuple(Regs);
2346 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2347 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2353 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2361 const DataLayout &
DL = CurDAG->getDataLayout();
2362 const TargetLowering *TLI = getTargetLowering();
2366 int FI = FINode->getIndex();
2368 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
2375void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2378 EVT VT =
N->getOperand(2)->getValueType(0);
2379 const EVT ResTys[] = {MVT::i64,
2391 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2431void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2434 EVT VT =
N->getValueType(0);
2446 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2448 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2450 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2452 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2456 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2457 AArch64::qsub2, AArch64::qsub3 };
2458 for (
unsigned i = 0; i < NumVecs; ++i) {
2459 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2466 CurDAG->RemoveDeadNode(
N);
2469void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2472 EVT VT =
N->getValueType(0);
2484 const EVT ResTys[] = {MVT::i64,
2487 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2490 CurDAG->getTargetConstant(LaneNo, dl,
2495 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2507 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2508 AArch64::qsub2, AArch64::qsub3 };
2509 for (
unsigned i = 0; i < NumVecs; ++i) {
2510 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2520 CurDAG->RemoveDeadNode(
N);
2523void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2526 EVT VT =
N->getOperand(2)->getValueType(0);
2538 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2540 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2542 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2551void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2554 EVT VT =
N->getOperand(2)->getValueType(0);
2566 const EVT ResTys[] = {MVT::i64,
2569 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2571 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2575 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2586 unsigned &LSB,
unsigned &MSB,
2587 unsigned NumberOfIgnoredLowBits,
2588 bool BiggerPattern) {
2590 "N must be a AND operation to call this function");
2592 EVT VT =
N->getValueType(0);
2597 assert((VT == MVT::i32 || VT == MVT::i64) &&
2598 "Type checking must have been done before calling this function");
2612 const SDNode *Op0 =
N->getOperand(0).getNode();
2619 if (AndImm & (AndImm + 1))
2622 bool ClampMSB =
false;
2642 ClampMSB = (VT == MVT::i32);
2643 }
else if (BiggerPattern) {
2649 Opd0 =
N->getOperand(0);
2655 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2658 <<
": Found large shift immediate, this should not happen\n"));
2672 MSB = MSB > 31 ? 31 : MSB;
2674 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2679 SDValue &Opd0,
unsigned &Immr,
2683 EVT VT =
N->getValueType(0);
2685 assert((VT == MVT::i32 || VT == MVT::i64) &&
2686 "Type checking must have been done before calling this function");
2690 Op =
Op->getOperand(0);
2691 VT =
Op->getValueType(0);
2700 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2704 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2705 Opd0 =
Op.getOperand(0);
2707 Imms = ShiftImm + Width - 1;
2735 Opd0 =
N->getOperand(0).getOperand(0);
2745 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2752 unsigned &Immr,
unsigned &Imms,
2753 bool BiggerPattern) {
2755 "N must be a SHR/SRA operation to call this function");
2757 EVT VT =
N->getValueType(0);
2762 assert((VT == MVT::i32 || VT == MVT::i64) &&
2763 "Type checking must have been done before calling this function");
2773 Opd0 =
N->getOperand(0).getOperand(0);
2774 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
2780 Opd0 =
N->getOperand(0).getOperand(0);
2783 assert(VT == MVT::i64 &&
"the promoted type should be i64");
2784 }
else if (BiggerPattern) {
2788 Opd0 =
N->getOperand(0);
2797 <<
": Found large shift immediate, this should not happen\n"));
2806 "bad amount in shift node!");
2807 int immr = SrlImm - ShlImm;
2812 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
2814 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
2818bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
2821 EVT VT =
N->getValueType(0);
2822 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
2823 if (VT != MVT::i64 || NarrowVT != MVT::i32)
2834 unsigned Immr = ShiftImm;
2836 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2837 CurDAG->getTargetConstant(Imms, dl, VT)};
2838 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
2843 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
2844 unsigned NumberOfIgnoredLowBits = 0,
2845 bool BiggerPattern =
false) {
2846 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
2849 switch (
N->getOpcode()) {
2851 if (!
N->isMachineOpcode())
2856 NumberOfIgnoredLowBits, BiggerPattern);
2865 unsigned NOpc =
N->getMachineOpcode();
2869 case AArch64::SBFMWri:
2870 case AArch64::UBFMWri:
2871 case AArch64::SBFMXri:
2872 case AArch64::UBFMXri:
2874 Opd0 =
N->getOperand(0);
2875 Immr =
N->getConstantOperandVal(1);
2876 Imms =
N->getConstantOperandVal(2);
2883bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
2884 unsigned Opc, Immr, Imms;
2889 EVT VT =
N->getValueType(0);
2894 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
2895 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
2896 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
2898 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
2899 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
2905 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
2906 CurDAG->getTargetConstant(Imms, dl, VT)};
2907 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
2916 unsigned NumberOfIgnoredHighBits,
EVT VT) {
2917 assert((VT == MVT::i32 || VT == MVT::i64) &&
2918 "i32 or i64 mask type expected!");
2922 APInt SignificantDstMask =
2926 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
2927 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
2960 APInt OpUsefulBits(UsefulBits);
2964 OpUsefulBits <<= MSB - Imm + 1;
2969 OpUsefulBits <<= Imm;
2971 OpUsefulBits <<= MSB + 1;
2974 OpUsefulBits <<= OpUsefulBits.
getBitWidth() - Imm;
2980 UsefulBits &= OpUsefulBits;
2997 APInt Mask(UsefulBits);
2998 Mask.clearAllBits();
3006 Mask.lshrInPlace(ShiftAmt);
3012 Mask.lshrInPlace(ShiftAmt);
3028 APInt OpUsefulBits(UsefulBits);
3042 OpUsefulBits <<= Width;
3045 if (
Op.getOperand(1) == Orig) {
3047 Mask = ResultUsefulBits & OpUsefulBits;
3051 if (
Op.getOperand(0) == Orig)
3053 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3059 OpUsefulBits <<= Width;
3061 OpUsefulBits <<= LSB;
3063 if (
Op.getOperand(1) == Orig) {
3065 Mask = ResultUsefulBits & OpUsefulBits;
3066 Mask.lshrInPlace(LSB);
3069 if (
Op.getOperand(0) == Orig)
3070 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3087 case AArch64::ANDSWri:
3088 case AArch64::ANDSXri:
3089 case AArch64::ANDWri:
3090 case AArch64::ANDXri:
3094 case AArch64::UBFMWri:
3095 case AArch64::UBFMXri:
3098 case AArch64::ORRWrs:
3099 case AArch64::ORRXrs:
3104 case AArch64::BFMWri:
3105 case AArch64::BFMXri:
3108 case AArch64::STRBBui:
3109 case AArch64::STURBBi:
3115 case AArch64::STRHHui:
3116 case AArch64::STURHHi:
3129 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3131 UsefulBits =
APInt(Bitwidth, 0);
3140 UsersUsefulBits |= UsefulBitsForUse;
3145 UsefulBits &= UsersUsefulBits;
3155 EVT VT =
Op.getValueType();
3158 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3161 if (ShlAmount > 0) {
3164 UBFMOpc, dl, VT,
Op,
3169 assert(ShlAmount < 0 &&
"expected right shift");
3170 int ShrAmount = -ShlAmount;
3182 const uint64_t NonZeroBits,
3189 const uint64_t NonZeroBits,
3196 bool BiggerPattern,
SDValue &Src,
3197 int &DstLSB,
int &Width) {
3198 EVT VT =
Op.getValueType();
3207 const uint64_t NonZeroBits = (~Known.Zero).getZExtValue();
3211 switch (
Op.getOpcode()) {
3216 NonZeroBits, Src, DstLSB, Width);
3219 NonZeroBits, Src, DstLSB, Width);
3232 EVT VT =
Op.getValueType();
3233 assert((VT == MVT::i32 || VT == MVT::i64) &&
3234 "Caller guarantees VT is one of i32 or i64");
3247 assert((~AndImm & NonZeroBits) == 0 &&
3248 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3277 if (!BiggerPattern && !AndOp0.
hasOneUse())
3296 <<
"Found large Width in bit-field-positioning -- this indicates no "
3297 "proper combining / constant folding was performed\n");
3306 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3321 "Op.getNode() should be a SHL node to call this function");
3323 "Op.getNode() should shift ShlImm to call this function");
3330 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3354 EVT VT =
Op.getValueType();
3355 assert((VT == MVT::i32 || VT == MVT::i64) &&
3356 "Caller guarantees that type is i32 or i64");
3363 if (!BiggerPattern && !
Op.hasOneUse())
3372 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3380 assert(VT == MVT::i32 || VT == MVT::i64);
3391 EVT VT =
N->getValueType(0);
3392 if (VT != MVT::i32 && VT != MVT::i64)
3410 if (!
And.hasOneUse() ||
3420 uint64_t NotKnownZero = (~Known.Zero).getZExtValue();
3427 if ((OrImm & NotKnownZero) != 0) {
3439 unsigned ImmS = Width - 1;
3445 bool IsBFI = LSB != 0;
3450 unsigned OrChunks = 0, BFIChunks = 0;
3451 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3452 if (((OrImm >> Shift) & 0xFFFF) != 0)
3454 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3457 if (BFIChunks > OrChunks)
3463 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3471 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3480 if (!Dst.hasOneUse())
3483 EVT VT = Dst.getValueType();
3484 assert((VT == MVT::i32 || VT == MVT::i64) &&
3485 "Caller should guarantee that VT is one of i32 or i64");
3513 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3514 unsigned MaskWidth =
3517 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3523 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3524 ShiftedOperand =
SDValue(UBFMNode, 0);
3553 const bool BiggerPattern) {
3554 EVT VT =
N->getValueType(0);
3555 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3556 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3557 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3558 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3559 assert((VT == MVT::i32 || VT == MVT::i64) &&
3560 "Expect result type to be i32 or i64 since N is combinable to BFM");
3567 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3570 if (BiggerPattern) {
3593 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3655 EVT VT =
N->getValueType(0);
3656 if (VT != MVT::i32 && VT != MVT::i64)
3664 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3665 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3685 for (
int I = 0;
I < 4; ++
I) {
3688 unsigned ImmR, ImmS;
3689 bool BiggerPattern =
I / 2;
3690 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3692 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3698 NumberOfIgnoredLowBits, BiggerPattern)) {
3701 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3702 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3707 Width = ImmS - ImmR + 1;
3718 Src, DstLSB, Width)) {
3726 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
3736 APInt BitsToBeInserted =
3739 if ((BitsToBeInserted & ~Known.
Zero) != 0)
3763 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3796 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3798 if (Src->hasOneUse() &&
3801 Src = Src->getOperand(0);
3811 unsigned ImmS = Width - 1;
3817 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3825bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
3834 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
3847bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
3851 EVT VT =
N->getValueType(0);
3852 if (VT != MVT::i32 && VT != MVT::i64)
3858 Op0, DstLSB, Width))
3864 unsigned ImmS = Width - 1;
3867 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
3868 CurDAG->getTargetConstant(ImmS,
DL, VT)};
3869 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3870 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3876bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
3877 EVT VT =
N->getValueType(0);
3880 switch (
N->getOpcode()) {
3882 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
3885 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
3888 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
3891 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
3899 if (VT == MVT::i32) {
3902 }
else if (VT == MVT::i64) {
3908 SDValue ShiftAmt =
N->getOperand(1);
3928 (Add0Imm %
Size == 0)) {
3934 if (SubVT == MVT::i32) {
3935 NegOpc = AArch64::SUBWrr;
3936 ZeroReg = AArch64::WZR;
3938 assert(SubVT == MVT::i64);
3939 NegOpc = AArch64::SUBXrr;
3940 ZeroReg = AArch64::XZR;
3943 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3944 MachineSDNode *Neg =
3945 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
3946 NewShiftAmt =
SDValue(Neg, 0);
3954 if (SubVT == MVT::i32) {
3955 NotOpc = AArch64::ORNWrr;
3956 ZeroReg = AArch64::WZR;
3958 assert(SubVT == MVT::i64);
3959 NotOpc = AArch64::ORNXrr;
3960 ZeroReg = AArch64::XZR;
3963 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
3964 MachineSDNode *
Not =
3965 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
3966 NewShiftAmt =
SDValue(Not, 0);
3987 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
3988 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
3989 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
3991 NewShiftAmt =
SDValue(Ext, 0);
3995 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4002 bool isReciprocal) {
4005 FVal = CN->getValueAPF();
4008 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4018 if (
unsigned FBits =
4027bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
4028 unsigned RegWidth) {
4033bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
4034 unsigned RegWidth) {
4035 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4036 N.getValueType().getScalarSizeInBits() ==
4037 N.getOperand(0).getValueType().getScalarSizeInBits())
4038 N =
N.getOperand(0);
4040 auto ImmToFloat = [RegWidth](APInt
Imm) {
4043 return APFloat(APFloat::IEEEhalf(), Imm);
4045 return APFloat(APFloat::IEEEsingle(), Imm);
4047 return APFloat(APFloat::IEEEdouble(), Imm);
4054 switch (
N->getOpcode()) {
4055 case AArch64ISD::MOVIshift:
4056 FVal = ImmToFloat(APInt(RegWidth,
N.getConstantOperandVal(0)
4057 <<
N.getConstantOperandVal(1)));
4059 case AArch64ISD::FMOV:
4060 assert(RegWidth == 32 || RegWidth == 64);
4064 N.getConstantOperandVal(0))));
4067 N.getConstantOperandVal(0))));
4069 case AArch64ISD::DUP:
4071 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4081 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(
N), MVT::i32);
4088bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(
SDValue N,
4090 unsigned RegWidth) {
4100 RegString.
split(Fields,
':');
4102 if (Fields.
size() == 1)
4106 &&
"Invalid number of fields in read register string");
4109 bool AllIntFields =
true;
4113 AllIntFields &= !
Field.getAsInteger(10, IntField);
4114 Ops.push_back(IntField);
4118 "Unexpected non-integer value in special register string.");
4123 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) |
4124 (
Ops[3] << 3) | (
Ops[4]);
4131bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4133 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4136 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4138 unsigned Opcode64Bit = AArch64::MRS;
4143 const auto *TheReg =
4144 AArch64SysReg::lookupSysRegByName(RegString->getString());
4145 if (TheReg && TheReg->Readable &&
4146 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4147 Imm = TheReg->Encoding;
4153 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4154 Opcode64Bit = AArch64::ADR;
4162 SDValue InChain =
N->getOperand(0);
4163 SDValue SysRegImm = CurDAG->getTargetConstant(Imm,
DL, MVT::i32);
4164 if (!ReadIs128Bit) {
4165 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4166 {SysRegImm, InChain});
4168 SDNode *MRRS = CurDAG->getMachineNode(
4170 {MVT::Untyped , MVT::Other },
4171 {SysRegImm, InChain});
4175 SDValue Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4177 SDValue Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4183 ReplaceUses(
SDValue(
N, 2), OutChain);
4192bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4194 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4197 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4199 if (!WriteIs128Bit) {
4205 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4208 "Expected a constant integer expression.");
4209 unsigned Reg = PMapper->Encoding;
4210 uint64_t Immed =
N->getConstantOperandVal(2);
4211 CurDAG->SelectNodeTo(
4212 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4213 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4219 if (trySelectPState(
4220 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4221 AArch64::MSRpstateImm4))
4223 if (trySelectPState(
4224 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4225 AArch64::MSRpstateImm1))
4234 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4235 if (TheReg && TheReg->Writeable &&
4236 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4237 Imm = TheReg->Encoding;
4246 if (!WriteIs128Bit) {
4247 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4248 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4249 N->getOperand(2), InChain);
4253 SDNode *Pair = CurDAG->getMachineNode(
4254 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4255 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4258 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4260 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4262 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4263 CurDAG->getTargetConstant(Imm,
DL, MVT::i32),
4271bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4276 if (Subtarget->hasLSE())
return false;
4278 if (MemTy == MVT::i8)
4279 Opcode = AArch64::CMP_SWAP_8;
4280 else if (MemTy == MVT::i16)
4281 Opcode = AArch64::CMP_SWAP_16;
4282 else if (MemTy == MVT::i32)
4283 Opcode = AArch64::CMP_SWAP_32;
4284 else if (MemTy == MVT::i64)
4285 Opcode = AArch64::CMP_SWAP_64;
4289 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4290 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4292 SDNode *CmpSwap = CurDAG->getMachineNode(
4294 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4301 CurDAG->RemoveDeadNode(
N);
4306bool AArch64DAGToDAGISel::SelectSVEAddSubImm(
SDValue N, MVT VT,
SDValue &Imm,
4307 SDValue &Shift,
bool Negate) {
4321 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4328 if ((Val & ~0xff) == 0) {
4329 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4334 if ((Val & ~0xff00) == 0) {
4335 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4347bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(
SDValue N, MVT VT,
4371 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4372 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4379 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4380 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4384 if (Val <= 65280 && Val % 256 == 0) {
4385 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4386 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4397bool AArch64DAGToDAGISel::SelectSVECpyDupImm(
SDValue N, MVT VT,
SDValue &Imm,
4407 int32_t ImmVal, ShiftVal;
4412 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4413 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4417bool AArch64DAGToDAGISel::SelectSVESignedArithImm(
SDValue N,
SDValue &Imm) {
4419 int64_t ImmVal = CNode->getSExtValue();
4421 if (ImmVal >= -128 && ImmVal < 128) {
4422 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4429bool AArch64DAGToDAGISel::SelectSVEArithImm(
SDValue N, MVT VT,
SDValue &Imm) {
4431 uint64_t ImmVal = CNode->getZExtValue();
4441 ImmVal &= 0xFFFFFFFF;
4450 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4457bool AArch64DAGToDAGISel::SelectSVELogicalImm(
SDValue N, MVT VT,
SDValue &Imm,
4461 ImmVal = CI->getZExtValue();
4463 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4474 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4483bool AArch64DAGToDAGISel::SelectSVEShiftImm(
SDValue N, uint64_t
Low,
4484 uint64_t
High,
bool AllowSaturation,
4487 uint64_t ImmVal = CN->getZExtValue();
4494 if (ImmVal >
High) {
4495 if (!AllowSaturation)
4500 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4507bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4521 const TargetLowering *TLI = getTargetLowering();
4524 SDValue FiOp = CurDAG->getTargetFrameIndex(
4526 int TagOffset =
N->getConstantOperandVal(3);
4528 SDNode *Out = CurDAG->getMachineNode(
4529 AArch64::TAGPstack,
DL, MVT::i64,
4530 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4531 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4532 ReplaceNode(
N, Out);
4536void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4538 "llvm.aarch64.tagp third argument must be an immediate");
4539 if (trySelectStackSlotTagP(
N))
4546 int TagOffset =
N->getConstantOperandVal(3);
4547 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4548 {
N->getOperand(1),
N->getOperand(2)});
4549 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4550 {
SDValue(N1, 0),
N->getOperand(2)});
4551 SDNode *N3 = CurDAG->getMachineNode(
4552 AArch64::ADDG,
DL, MVT::i64,
4553 {
SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4554 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4558bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4562 if (
N->getConstantOperandVal(2) != 0)
4564 if (!
N->getOperand(0).isUndef())
4568 EVT VT =
N->getValueType(0);
4569 EVT InVT =
N->getOperand(1).getValueType();
4580 "Expected to insert into a packed scalable vector!");
4583 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4584 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4585 N->getOperand(1), RC));
4589bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4593 if (
N->getConstantOperandVal(1) != 0)
4597 EVT VT =
N->getValueType(0);
4598 EVT InVT =
N->getOperand(0).getValueType();
4609 "Expected to extract from a packed scalable vector!");
4612 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4613 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4614 N->getOperand(0), RC));
4618bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4624 EVT VT =
N->getValueType(0);
4637 (Subtarget->hasSVE2() ||
4638 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4639 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4642 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4646 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4647 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4648 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4655 bool IsXOROperand =
true;
4657 IsXOROperand =
false;
4663 APInt ShlAmt, ShrAmt;
4671 if (!IsXOROperand) {
4673 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4676 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4677 SDNode *SubRegToReg =
4678 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4689 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4690 AArch64::XAR_ZZZI_D})) {
4691 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4716 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
4726 if (N0->
getOpcode() != AArch64ISD::VSHL ||
4734 bool IsXOROperand =
true;
4736 IsXOROperand =
false;
4739 R1 =
XOR.getOperand(0);
4740 R2 =
XOR.getOperand(1);
4750 if (ShAmt + HsAmt != VTSizeInBits)
4753 if (!IsXOROperand) {
4756 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
4765 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
4771 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
4772 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4774 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4777 if (
R2.getValueType() == VT)
4778 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
4786 R1 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
4791 R2 =
SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
4797 SDNode *XAR =
nullptr;
4801 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4802 AArch64::XAR_ZZZI_D}))
4803 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
4805 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
4808 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
4814 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4815 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
4818 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
4819 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4825 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
4829 ReplaceNode(
N, XAR);
4833void AArch64DAGToDAGISel::Select(SDNode *Node) {
4835 if (
Node->isMachineOpcode()) {
4837 Node->setNodeId(-1);
4842 EVT VT =
Node->getValueType(0);
4844 switch (
Node->getOpcode()) {
4849 if (SelectCMP_SWAP(Node))
4854 case AArch64ISD::MRRS:
4855 if (tryReadRegister(Node))
4860 case AArch64ISD::MSRR:
4861 if (tryWriteRegister(Node))
4868 if (tryIndexedLoad(Node))
4877 if (tryBitfieldExtractOp(Node))
4879 if (tryBitfieldInsertInZeroOp(Node))
4884 if (tryShiftAmountMod(Node))
4889 if (tryBitfieldExtractOpFromSExt(Node))
4894 if (tryBitfieldInsertOp(Node))
4896 if (trySelectXAR(Node))
4901 if (trySelectCastScalableToFixedLengthVector(Node))
4907 if (trySelectCastFixedLengthToScalableVector(Node))
4916 if (ConstNode->
isZero()) {
4917 if (VT == MVT::i32) {
4919 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32);
4920 ReplaceNode(Node,
New.getNode());
4922 }
else if (VT == MVT::i64) {
4924 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64);
4925 ReplaceNode(Node,
New.getNode());
4936 const TargetLowering *TLI = getTargetLowering();
4937 SDValue TFI = CurDAG->getTargetFrameIndex(
4940 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
4941 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
4942 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
4946 unsigned IntNo =
Node->getConstantOperandVal(1);
4950 case Intrinsic::aarch64_gcsss: {
4954 SDValue Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
4956 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
4957 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
4958 MVT::Other, Zero,
SDValue(SS1, 0));
4959 ReplaceNode(Node, SS2);
4962 case Intrinsic::aarch64_ldaxp:
4963 case Intrinsic::aarch64_ldxp: {
4965 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
4970 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
4971 MVT::Other, MemAddr, Chain);
4974 MachineMemOperand *MemOp =
4977 ReplaceNode(Node, Ld);
4980 case Intrinsic::aarch64_stlxp:
4981 case Intrinsic::aarch64_stxp: {
4983 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
4991 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain};
4993 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
4995 MachineMemOperand *MemOp =
4999 ReplaceNode(Node, St);
5002 case Intrinsic::aarch64_neon_ld1x2:
5003 if (VT == MVT::v8i8) {
5004 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5006 }
else if (VT == MVT::v16i8) {
5007 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5009 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5010 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5012 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5013 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5015 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5016 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5018 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5019 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5021 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5022 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5024 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5025 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5029 case Intrinsic::aarch64_neon_ld1x3:
5030 if (VT == MVT::v8i8) {
5031 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5033 }
else if (VT == MVT::v16i8) {
5034 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5036 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5037 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5039 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5040 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5042 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5043 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5045 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5046 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5048 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5049 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5051 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5052 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5056 case Intrinsic::aarch64_neon_ld1x4:
5057 if (VT == MVT::v8i8) {
5058 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5060 }
else if (VT == MVT::v16i8) {
5061 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5063 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5064 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5066 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5067 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5069 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5070 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5072 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5073 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5075 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5076 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5078 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5079 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5083 case Intrinsic::aarch64_neon_ld2:
5084 if (VT == MVT::v8i8) {
5085 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5087 }
else if (VT == MVT::v16i8) {
5088 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5090 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5091 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5093 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5094 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5096 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5097 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5099 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5100 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5102 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5103 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5105 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5106 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5110 case Intrinsic::aarch64_neon_ld3:
5111 if (VT == MVT::v8i8) {
5112 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5114 }
else if (VT == MVT::v16i8) {
5115 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5117 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5118 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5120 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5121 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5123 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5124 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5126 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5127 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5129 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5130 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5132 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5133 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5137 case Intrinsic::aarch64_neon_ld4:
5138 if (VT == MVT::v8i8) {
5139 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5141 }
else if (VT == MVT::v16i8) {
5142 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5144 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5145 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5147 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5148 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5150 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5151 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5153 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5154 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5156 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5157 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5159 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5160 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5164 case Intrinsic::aarch64_neon_ld2r:
5165 if (VT == MVT::v8i8) {
5166 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5168 }
else if (VT == MVT::v16i8) {
5169 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5171 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5172 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5174 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5175 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5177 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5178 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5180 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5181 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5183 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5184 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5186 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5187 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5191 case Intrinsic::aarch64_neon_ld3r:
5192 if (VT == MVT::v8i8) {
5193 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5195 }
else if (VT == MVT::v16i8) {
5196 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5198 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5199 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5201 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5202 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5204 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5205 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5207 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5208 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5210 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5211 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5213 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5214 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5218 case Intrinsic::aarch64_neon_ld4r:
5219 if (VT == MVT::v8i8) {
5220 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5222 }
else if (VT == MVT::v16i8) {
5223 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5225 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5226 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5228 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5229 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5231 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5232 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5234 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5235 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5237 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5238 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5240 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5241 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5245 case Intrinsic::aarch64_neon_ld2lane:
5246 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5247 SelectLoadLane(Node, 2, AArch64::LD2i8);
5249 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5250 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5251 SelectLoadLane(Node, 2, AArch64::LD2i16);
5253 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5255 SelectLoadLane(Node, 2, AArch64::LD2i32);
5257 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5259 SelectLoadLane(Node, 2, AArch64::LD2i64);
5263 case Intrinsic::aarch64_neon_ld3lane:
5264 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5265 SelectLoadLane(Node, 3, AArch64::LD3i8);
5267 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5268 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5269 SelectLoadLane(Node, 3, AArch64::LD3i16);
5271 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5273 SelectLoadLane(Node, 3, AArch64::LD3i32);
5275 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5277 SelectLoadLane(Node, 3, AArch64::LD3i64);
5281 case Intrinsic::aarch64_neon_ld4lane:
5282 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5283 SelectLoadLane(Node, 4, AArch64::LD4i8);
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, 4, AArch64::LD4i16);
5289 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5291 SelectLoadLane(Node, 4, AArch64::LD4i32);
5293 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5295 SelectLoadLane(Node, 4, AArch64::LD4i64);
5299 case Intrinsic::aarch64_ld64b:
5300 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5302 case Intrinsic::aarch64_sve_ld2q_sret: {
5303 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5306 case Intrinsic::aarch64_sve_ld3q_sret: {
5307 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5310 case Intrinsic::aarch64_sve_ld4q_sret: {
5311 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5314 case Intrinsic::aarch64_sve_ld2_sret: {
5315 if (VT == MVT::nxv16i8) {
5316 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5319 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5320 VT == MVT::nxv8bf16) {
5321 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5324 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5325 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5328 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5329 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5335 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5336 if (VT == MVT::nxv16i8) {
5337 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5338 SelectContiguousMultiVectorLoad(
5339 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5340 else if (Subtarget->hasSVE2p1())
5341 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5346 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5347 VT == MVT::nxv8bf16) {
5348 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5349 SelectContiguousMultiVectorLoad(
5350 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5351 else if (Subtarget->hasSVE2p1())
5352 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5357 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5358 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5359 SelectContiguousMultiVectorLoad(
5360 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5361 else if (Subtarget->hasSVE2p1())
5362 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5367 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5368 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5369 SelectContiguousMultiVectorLoad(
5370 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5371 else if (Subtarget->hasSVE2p1())
5372 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5380 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5381 if (VT == MVT::nxv16i8) {
5382 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5383 SelectContiguousMultiVectorLoad(
5384 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5385 else if (Subtarget->hasSVE2p1())
5386 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5391 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5392 VT == MVT::nxv8bf16) {
5393 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5394 SelectContiguousMultiVectorLoad(
5395 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5396 else if (Subtarget->hasSVE2p1())
5397 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5402 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5403 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5404 SelectContiguousMultiVectorLoad(
5405 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5406 else if (Subtarget->hasSVE2p1())
5407 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5412 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5413 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5414 SelectContiguousMultiVectorLoad(
5415 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5416 else if (Subtarget->hasSVE2p1())
5417 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5425 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5426 if (VT == MVT::nxv16i8) {
5427 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5428 SelectContiguousMultiVectorLoad(Node, 2, 0,
5429 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5430 AArch64::LDNT1B_2Z_PSEUDO);
5431 else if (Subtarget->hasSVE2p1())
5432 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5433 AArch64::LDNT1B_2Z);
5437 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5438 VT == MVT::nxv8bf16) {
5439 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5440 SelectContiguousMultiVectorLoad(Node, 2, 1,
5441 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5442 AArch64::LDNT1H_2Z_PSEUDO);
5443 else if (Subtarget->hasSVE2p1())
5444 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5445 AArch64::LDNT1H_2Z);
5449 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5450 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5451 SelectContiguousMultiVectorLoad(Node, 2, 2,
5452 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5453 AArch64::LDNT1W_2Z_PSEUDO);
5454 else if (Subtarget->hasSVE2p1())
5455 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5456 AArch64::LDNT1W_2Z);
5460 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5461 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5462 SelectContiguousMultiVectorLoad(Node, 2, 3,
5463 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5464 AArch64::LDNT1D_2Z_PSEUDO);
5465 else if (Subtarget->hasSVE2p1())
5466 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5467 AArch64::LDNT1D_2Z);
5474 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5475 if (VT == MVT::nxv16i8) {
5476 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5477 SelectContiguousMultiVectorLoad(Node, 4, 0,
5478 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5479 AArch64::LDNT1B_4Z_PSEUDO);
5480 else if (Subtarget->hasSVE2p1())
5481 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5482 AArch64::LDNT1B_4Z);
5486 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5487 VT == MVT::nxv8bf16) {
5488 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5489 SelectContiguousMultiVectorLoad(Node, 4, 1,
5490 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5491 AArch64::LDNT1H_4Z_PSEUDO);
5492 else if (Subtarget->hasSVE2p1())
5493 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5494 AArch64::LDNT1H_4Z);
5498 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5499 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5500 SelectContiguousMultiVectorLoad(Node, 4, 2,
5501 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5502 AArch64::LDNT1W_4Z_PSEUDO);
5503 else if (Subtarget->hasSVE2p1())
5504 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5505 AArch64::LDNT1W_4Z);
5509 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5510 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5511 SelectContiguousMultiVectorLoad(Node, 4, 3,
5512 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5513 AArch64::LDNT1D_4Z_PSEUDO);
5514 else if (Subtarget->hasSVE2p1())
5515 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5516 AArch64::LDNT1D_4Z);
5523 case Intrinsic::aarch64_sve_ld3_sret: {
5524 if (VT == MVT::nxv16i8) {
5525 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5528 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5529 VT == MVT::nxv8bf16) {
5530 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5533 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5534 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5537 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5538 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5544 case Intrinsic::aarch64_sve_ld4_sret: {
5545 if (VT == MVT::nxv16i8) {
5546 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5549 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5550 VT == MVT::nxv8bf16) {
5551 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5554 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5555 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5558 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5559 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5565 case Intrinsic::aarch64_sme_read_hor_vg2: {
5566 if (VT == MVT::nxv16i8) {
5567 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5568 AArch64::MOVA_2ZMXI_H_B);
5570 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5571 VT == MVT::nxv8bf16) {
5572 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5573 AArch64::MOVA_2ZMXI_H_H);
5575 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5576 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5577 AArch64::MOVA_2ZMXI_H_S);
5579 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5580 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5581 AArch64::MOVA_2ZMXI_H_D);
5586 case Intrinsic::aarch64_sme_read_ver_vg2: {
5587 if (VT == MVT::nxv16i8) {
5588 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5589 AArch64::MOVA_2ZMXI_V_B);
5591 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5592 VT == MVT::nxv8bf16) {
5593 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5594 AArch64::MOVA_2ZMXI_V_H);
5596 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5597 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5598 AArch64::MOVA_2ZMXI_V_S);
5600 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5601 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5602 AArch64::MOVA_2ZMXI_V_D);
5607 case Intrinsic::aarch64_sme_read_hor_vg4: {
5608 if (VT == MVT::nxv16i8) {
5609 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5610 AArch64::MOVA_4ZMXI_H_B);
5612 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5613 VT == MVT::nxv8bf16) {
5614 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5615 AArch64::MOVA_4ZMXI_H_H);
5617 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5618 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5619 AArch64::MOVA_4ZMXI_H_S);
5621 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5622 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5623 AArch64::MOVA_4ZMXI_H_D);
5628 case Intrinsic::aarch64_sme_read_ver_vg4: {
5629 if (VT == MVT::nxv16i8) {
5630 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5631 AArch64::MOVA_4ZMXI_V_B);
5633 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5634 VT == MVT::nxv8bf16) {
5635 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5636 AArch64::MOVA_4ZMXI_V_H);
5638 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5639 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5640 AArch64::MOVA_4ZMXI_V_S);
5642 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5643 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5644 AArch64::MOVA_4ZMXI_V_D);
5649 case Intrinsic::aarch64_sme_read_vg1x2: {
5650 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5651 AArch64::MOVA_VG2_2ZMXI);
5654 case Intrinsic::aarch64_sme_read_vg1x4: {
5655 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5656 AArch64::MOVA_VG4_4ZMXI);
5659 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5660 if (VT == MVT::nxv16i8) {
5661 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5663 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5664 VT == MVT::nxv8bf16) {
5665 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5667 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5668 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5670 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5671 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5676 case Intrinsic::aarch64_sme_readz_vert_x2: {
5677 if (VT == MVT::nxv16i8) {
5678 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5680 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5681 VT == MVT::nxv8bf16) {
5682 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5684 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5685 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5687 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5688 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5693 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5694 if (VT == MVT::nxv16i8) {
5695 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5697 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5698 VT == MVT::nxv8bf16) {
5699 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
5701 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5702 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
5704 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5705 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
5710 case Intrinsic::aarch64_sme_readz_vert_x4: {
5711 if (VT == MVT::nxv16i8) {
5712 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
5714 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5715 VT == MVT::nxv8bf16) {
5716 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
5718 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5719 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
5721 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5722 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
5727 case Intrinsic::aarch64_sme_readz_x2: {
5728 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
5732 case Intrinsic::aarch64_sme_readz_x4: {
5733 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
5737 case Intrinsic::swift_async_context_addr: {
5740 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
5742 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
5743 CurDAG->getTargetConstant(8,
DL, MVT::i32),
5744 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
5746 ReplaceUses(
SDValue(Node, 0), Res);
5748 CurDAG->RemoveDeadNode(Node);
5750 auto &MF = CurDAG->getMachineFunction();
5751 MF.getFrameInfo().setFrameAddressIsTaken(
true);
5752 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
5755 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
5757 Node->getValueType(0),
5758 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
5759 AArch64::LUTI2_4ZTZI_S}))
5761 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
5764 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
5766 Node->getValueType(0),
5767 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
5769 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
5772 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
5774 Node->getValueType(0),
5775 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
5776 AArch64::LUTI2_2ZTZI_S}))
5778 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
5781 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
5783 Node->getValueType(0),
5784 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
5785 AArch64::LUTI4_2ZTZI_S}))
5787 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
5790 case Intrinsic::aarch64_sme_luti4_zt_x4: {
5791 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z);
5794 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
5796 Node->getValueType(0),
5797 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
5798 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5800 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
5802 Node->getValueType(0),
5803 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
5804 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5806 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
5808 Node->getValueType(0),
5809 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
5810 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5812 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
5814 Node->getValueType(0),
5815 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
5816 SelectCVTIntrinsicFP8(Node, 2,
Opc);
5818 case Intrinsic::ptrauth_resign_load_relative:
5819 SelectPtrauthResign(Node);
5824 unsigned IntNo =
Node->getConstantOperandVal(0);
5828 case Intrinsic::aarch64_tagp:
5832 case Intrinsic::ptrauth_auth:
5833 SelectPtrauthAuth(Node);
5836 case Intrinsic::ptrauth_resign:
5837 SelectPtrauthResign(Node);
5840 case Intrinsic::aarch64_neon_tbl2:
5841 SelectTable(Node, 2,
5842 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
5845 case Intrinsic::aarch64_neon_tbl3:
5846 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
5847 : AArch64::TBLv16i8Three,
5850 case Intrinsic::aarch64_neon_tbl4:
5851 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
5852 : AArch64::TBLv16i8Four,
5855 case Intrinsic::aarch64_neon_tbx2:
5856 SelectTable(Node, 2,
5857 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
5860 case Intrinsic::aarch64_neon_tbx3:
5861 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
5862 : AArch64::TBXv16i8Three,
5865 case Intrinsic::aarch64_neon_tbx4:
5866 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
5867 : AArch64::TBXv16i8Four,
5870 case Intrinsic::aarch64_sve_srshl_single_x2:
5872 Node->getValueType(0),
5873 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
5874 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
5875 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5877 case Intrinsic::aarch64_sve_srshl_single_x4:
5879 Node->getValueType(0),
5880 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
5881 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
5882 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5884 case Intrinsic::aarch64_sve_urshl_single_x2:
5886 Node->getValueType(0),
5887 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
5888 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
5889 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5891 case Intrinsic::aarch64_sve_urshl_single_x4:
5893 Node->getValueType(0),
5894 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
5895 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
5896 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5898 case Intrinsic::aarch64_sve_srshl_x2:
5900 Node->getValueType(0),
5901 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
5902 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
5903 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5905 case Intrinsic::aarch64_sve_srshl_x4:
5907 Node->getValueType(0),
5908 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
5909 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
5910 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5912 case Intrinsic::aarch64_sve_urshl_x2:
5914 Node->getValueType(0),
5915 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
5916 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
5917 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5919 case Intrinsic::aarch64_sve_urshl_x4:
5921 Node->getValueType(0),
5922 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
5923 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
5924 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5926 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
5928 Node->getValueType(0),
5929 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
5930 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
5931 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5933 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
5935 Node->getValueType(0),
5936 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
5937 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
5938 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5940 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
5942 Node->getValueType(0),
5943 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
5944 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
5945 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5947 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
5949 Node->getValueType(0),
5950 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
5951 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
5952 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5954 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
5956 Node->getValueType(0),
5957 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
5958 AArch64::FSCALE_2ZZ_D}))
5959 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
5961 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
5963 Node->getValueType(0),
5964 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
5965 AArch64::FSCALE_4ZZ_D}))
5966 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
5968 case Intrinsic::aarch64_sme_fp8_scale_x2:
5970 Node->getValueType(0),
5971 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
5972 AArch64::FSCALE_2Z2Z_D}))
5973 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
5975 case Intrinsic::aarch64_sme_fp8_scale_x4:
5977 Node->getValueType(0),
5978 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
5979 AArch64::FSCALE_4Z4Z_D}))
5980 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
5982 case Intrinsic::aarch64_sve_whilege_x2:
5984 Node->getValueType(0),
5985 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
5986 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
5987 SelectWhilePair(Node,
Op);
5989 case Intrinsic::aarch64_sve_whilegt_x2:
5991 Node->getValueType(0),
5992 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
5993 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
5994 SelectWhilePair(Node,
Op);
5996 case Intrinsic::aarch64_sve_whilehi_x2:
5998 Node->getValueType(0),
5999 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6000 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6001 SelectWhilePair(Node,
Op);
6003 case Intrinsic::aarch64_sve_whilehs_x2:
6005 Node->getValueType(0),
6006 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6007 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6008 SelectWhilePair(Node,
Op);
6010 case Intrinsic::aarch64_sve_whilele_x2:
6012 Node->getValueType(0),
6013 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6014 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6015 SelectWhilePair(Node,
Op);
6017 case Intrinsic::aarch64_sve_whilelo_x2:
6019 Node->getValueType(0),
6020 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6021 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6022 SelectWhilePair(Node,
Op);
6024 case Intrinsic::aarch64_sve_whilels_x2:
6026 Node->getValueType(0),
6027 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6028 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6029 SelectWhilePair(Node,
Op);
6031 case Intrinsic::aarch64_sve_whilelt_x2:
6033 Node->getValueType(0),
6034 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6035 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6036 SelectWhilePair(Node,
Op);
6038 case Intrinsic::aarch64_sve_smax_single_x2:
6040 Node->getValueType(0),
6041 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6042 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6043 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6045 case Intrinsic::aarch64_sve_umax_single_x2:
6047 Node->getValueType(0),
6048 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6049 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6050 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6052 case Intrinsic::aarch64_sve_fmax_single_x2:
6054 Node->getValueType(0),
6055 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6056 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6057 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6059 case Intrinsic::aarch64_sve_smax_single_x4:
6061 Node->getValueType(0),
6062 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6063 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6064 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6066 case Intrinsic::aarch64_sve_umax_single_x4:
6068 Node->getValueType(0),
6069 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6070 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6071 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6073 case Intrinsic::aarch64_sve_fmax_single_x4:
6075 Node->getValueType(0),
6076 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6077 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6078 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6080 case Intrinsic::aarch64_sve_smin_single_x2:
6082 Node->getValueType(0),
6083 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6084 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6085 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6087 case Intrinsic::aarch64_sve_umin_single_x2:
6089 Node->getValueType(0),
6090 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6091 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6092 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6094 case Intrinsic::aarch64_sve_fmin_single_x2:
6096 Node->getValueType(0),
6097 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6098 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6099 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6101 case Intrinsic::aarch64_sve_smin_single_x4:
6103 Node->getValueType(0),
6104 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6105 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6106 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6108 case Intrinsic::aarch64_sve_umin_single_x4:
6110 Node->getValueType(0),
6111 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6112 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6113 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6115 case Intrinsic::aarch64_sve_fmin_single_x4:
6117 Node->getValueType(0),
6118 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6119 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6120 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6122 case Intrinsic::aarch64_sve_smax_x2:
6124 Node->getValueType(0),
6125 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6126 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6127 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6129 case Intrinsic::aarch64_sve_umax_x2:
6131 Node->getValueType(0),
6132 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6133 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6134 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6136 case Intrinsic::aarch64_sve_fmax_x2:
6138 Node->getValueType(0),
6139 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6140 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6141 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6143 case Intrinsic::aarch64_sve_smax_x4:
6145 Node->getValueType(0),
6146 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6147 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6148 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6150 case Intrinsic::aarch64_sve_umax_x4:
6152 Node->getValueType(0),
6153 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6154 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6155 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6157 case Intrinsic::aarch64_sve_fmax_x4:
6159 Node->getValueType(0),
6160 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6161 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6162 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6164 case Intrinsic::aarch64_sme_famax_x2:
6166 Node->getValueType(0),
6167 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6168 AArch64::FAMAX_2Z2Z_D}))
6169 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6171 case Intrinsic::aarch64_sme_famax_x4:
6173 Node->getValueType(0),
6174 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6175 AArch64::FAMAX_4Z4Z_D}))
6176 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6178 case Intrinsic::aarch64_sme_famin_x2:
6180 Node->getValueType(0),
6181 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6182 AArch64::FAMIN_2Z2Z_D}))
6183 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6185 case Intrinsic::aarch64_sme_famin_x4:
6187 Node->getValueType(0),
6188 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6189 AArch64::FAMIN_4Z4Z_D}))
6190 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6192 case Intrinsic::aarch64_sve_smin_x2:
6194 Node->getValueType(0),
6195 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6196 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6197 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6199 case Intrinsic::aarch64_sve_umin_x2:
6201 Node->getValueType(0),
6202 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6203 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6204 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6206 case Intrinsic::aarch64_sve_fmin_x2:
6208 Node->getValueType(0),
6209 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6210 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6211 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6213 case Intrinsic::aarch64_sve_smin_x4:
6215 Node->getValueType(0),
6216 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6217 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6218 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6220 case Intrinsic::aarch64_sve_umin_x4:
6222 Node->getValueType(0),
6223 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6224 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6225 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6227 case Intrinsic::aarch64_sve_fmin_x4:
6229 Node->getValueType(0),
6230 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6231 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6232 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6234 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6236 Node->getValueType(0),
6237 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6238 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6239 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6241 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6243 Node->getValueType(0),
6244 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6245 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6246 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6248 case Intrinsic::aarch64_sve_fminnm_single_x2:
6250 Node->getValueType(0),
6251 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6252 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6253 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6255 case Intrinsic::aarch64_sve_fminnm_single_x4:
6257 Node->getValueType(0),
6258 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6259 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6260 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6262 case Intrinsic::aarch64_sve_fscale_single_x4:
6263 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6265 case Intrinsic::aarch64_sve_fscale_single_x2:
6266 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6268 case Intrinsic::aarch64_sve_fmul_single_x4:
6270 Node->getValueType(0),
6271 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6272 AArch64::FMUL_4ZZ_D}))
6273 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6275 case Intrinsic::aarch64_sve_fmul_single_x2:
6277 Node->getValueType(0),
6278 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6279 AArch64::FMUL_2ZZ_D}))
6280 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6282 case Intrinsic::aarch64_sve_fmaxnm_x2:
6284 Node->getValueType(0),
6285 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6286 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6287 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6289 case Intrinsic::aarch64_sve_fmaxnm_x4:
6291 Node->getValueType(0),
6292 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6293 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6294 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6296 case Intrinsic::aarch64_sve_fminnm_x2:
6298 Node->getValueType(0),
6299 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6300 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6301 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6303 case Intrinsic::aarch64_sve_fminnm_x4:
6305 Node->getValueType(0),
6306 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6307 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6308 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6310 case Intrinsic::aarch64_sve_aese_lane_x2:
6311 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6313 case Intrinsic::aarch64_sve_aesd_lane_x2:
6314 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6316 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6317 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6319 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6320 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6322 case Intrinsic::aarch64_sve_aese_lane_x4:
6323 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6325 case Intrinsic::aarch64_sve_aesd_lane_x4:
6326 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6328 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6329 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6331 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6332 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6334 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6335 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6337 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6341 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6343 for (
unsigned I = 0;
I < 2;
I++)
6345 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6347 CurDAG->RemoveDeadNode(Node);
6350 case Intrinsic::aarch64_sve_fscale_x4:
6351 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6353 case Intrinsic::aarch64_sve_fscale_x2:
6354 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6356 case Intrinsic::aarch64_sve_fmul_x4:
6358 Node->getValueType(0),
6359 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6360 AArch64::FMUL_4Z4Z_D}))
6361 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6363 case Intrinsic::aarch64_sve_fmul_x2:
6365 Node->getValueType(0),
6366 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6367 AArch64::FMUL_2Z2Z_D}))
6368 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6370 case Intrinsic::aarch64_sve_fcvtzs_x2:
6371 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6373 case Intrinsic::aarch64_sve_scvtf_x2:
6374 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6376 case Intrinsic::aarch64_sve_fcvtzu_x2:
6377 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6379 case Intrinsic::aarch64_sve_ucvtf_x2:
6380 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6382 case Intrinsic::aarch64_sve_fcvtzs_x4:
6383 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6385 case Intrinsic::aarch64_sve_scvtf_x4:
6386 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6388 case Intrinsic::aarch64_sve_fcvtzu_x4:
6389 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6391 case Intrinsic::aarch64_sve_ucvtf_x4:
6392 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6394 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6395 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6397 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6398 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6400 case Intrinsic::aarch64_sve_sclamp_single_x2:
6402 Node->getValueType(0),
6403 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6404 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6405 SelectClamp(Node, 2,
Op);
6407 case Intrinsic::aarch64_sve_uclamp_single_x2:
6409 Node->getValueType(0),
6410 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6411 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6412 SelectClamp(Node, 2,
Op);
6414 case Intrinsic::aarch64_sve_fclamp_single_x2:
6416 Node->getValueType(0),
6417 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6418 AArch64::FCLAMP_VG2_2Z2Z_D}))
6419 SelectClamp(Node, 2,
Op);
6421 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6422 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6424 case Intrinsic::aarch64_sve_sclamp_single_x4:
6426 Node->getValueType(0),
6427 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6428 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6429 SelectClamp(Node, 4,
Op);
6431 case Intrinsic::aarch64_sve_uclamp_single_x4:
6433 Node->getValueType(0),
6434 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6435 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6436 SelectClamp(Node, 4,
Op);
6438 case Intrinsic::aarch64_sve_fclamp_single_x4:
6440 Node->getValueType(0),
6441 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6442 AArch64::FCLAMP_VG4_4Z4Z_D}))
6443 SelectClamp(Node, 4,
Op);
6445 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6446 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6448 case Intrinsic::aarch64_sve_add_single_x2:
6450 Node->getValueType(0),
6451 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6452 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6453 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6455 case Intrinsic::aarch64_sve_add_single_x4:
6457 Node->getValueType(0),
6458 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6459 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6460 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6462 case Intrinsic::aarch64_sve_zip_x2:
6464 Node->getValueType(0),
6465 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6466 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6467 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6469 case Intrinsic::aarch64_sve_zipq_x2:
6470 SelectUnaryMultiIntrinsic(Node, 2,
false,
6471 AArch64::ZIP_VG2_2ZZZ_Q);
6473 case Intrinsic::aarch64_sve_zip_x4:
6475 Node->getValueType(0),
6476 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6477 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6478 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6480 case Intrinsic::aarch64_sve_zipq_x4:
6481 SelectUnaryMultiIntrinsic(Node, 4,
true,
6482 AArch64::ZIP_VG4_4Z4Z_Q);
6484 case Intrinsic::aarch64_sve_uzp_x2:
6486 Node->getValueType(0),
6487 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6488 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6489 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6491 case Intrinsic::aarch64_sve_uzpq_x2:
6492 SelectUnaryMultiIntrinsic(Node, 2,
false,
6493 AArch64::UZP_VG2_2ZZZ_Q);
6495 case Intrinsic::aarch64_sve_uzp_x4:
6497 Node->getValueType(0),
6498 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6499 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6500 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6502 case Intrinsic::aarch64_sve_uzpq_x4:
6503 SelectUnaryMultiIntrinsic(Node, 4,
true,
6504 AArch64::UZP_VG4_4Z4Z_Q);
6506 case Intrinsic::aarch64_sve_sel_x2:
6508 Node->getValueType(0),
6509 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6510 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6511 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6513 case Intrinsic::aarch64_sve_sel_x4:
6515 Node->getValueType(0),
6516 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6517 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6518 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6520 case Intrinsic::aarch64_sve_frinta_x2:
6521 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6523 case Intrinsic::aarch64_sve_frinta_x4:
6524 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6526 case Intrinsic::aarch64_sve_frintm_x2:
6527 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6529 case Intrinsic::aarch64_sve_frintm_x4:
6530 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6532 case Intrinsic::aarch64_sve_frintn_x2:
6533 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6535 case Intrinsic::aarch64_sve_frintn_x4:
6536 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6538 case Intrinsic::aarch64_sve_frintp_x2:
6539 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6541 case Intrinsic::aarch64_sve_frintp_x4:
6542 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6544 case Intrinsic::aarch64_sve_sunpk_x2:
6546 Node->getValueType(0),
6547 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6548 AArch64::SUNPK_VG2_2ZZ_D}))
6549 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6551 case Intrinsic::aarch64_sve_uunpk_x2:
6553 Node->getValueType(0),
6554 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6555 AArch64::UUNPK_VG2_2ZZ_D}))
6556 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6558 case Intrinsic::aarch64_sve_sunpk_x4:
6560 Node->getValueType(0),
6561 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6562 AArch64::SUNPK_VG4_4Z2Z_D}))
6563 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6565 case Intrinsic::aarch64_sve_uunpk_x4:
6567 Node->getValueType(0),
6568 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6569 AArch64::UUNPK_VG4_4Z2Z_D}))
6570 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6572 case Intrinsic::aarch64_sve_pext_x2: {
6574 Node->getValueType(0),
6575 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6576 AArch64::PEXT_2PCI_D}))
6577 SelectPExtPair(Node,
Op);
6584 unsigned IntNo =
Node->getConstantOperandVal(1);
6585 if (
Node->getNumOperands() >= 3)
6586 VT =
Node->getOperand(2)->getValueType(0);
6590 case Intrinsic::aarch64_neon_st1x2: {
6591 if (VT == MVT::v8i8) {
6592 SelectStore(Node, 2, AArch64::ST1Twov8b);
6594 }
else if (VT == MVT::v16i8) {
6595 SelectStore(Node, 2, AArch64::ST1Twov16b);
6597 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6598 VT == MVT::v4bf16) {
6599 SelectStore(Node, 2, AArch64::ST1Twov4h);
6601 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6602 VT == MVT::v8bf16) {
6603 SelectStore(Node, 2, AArch64::ST1Twov8h);
6605 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6606 SelectStore(Node, 2, AArch64::ST1Twov2s);
6608 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6609 SelectStore(Node, 2, AArch64::ST1Twov4s);
6611 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6612 SelectStore(Node, 2, AArch64::ST1Twov2d);
6614 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6615 SelectStore(Node, 2, AArch64::ST1Twov1d);
6620 case Intrinsic::aarch64_neon_st1x3: {
6621 if (VT == MVT::v8i8) {
6622 SelectStore(Node, 3, AArch64::ST1Threev8b);
6624 }
else if (VT == MVT::v16i8) {
6625 SelectStore(Node, 3, AArch64::ST1Threev16b);
6627 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6628 VT == MVT::v4bf16) {
6629 SelectStore(Node, 3, AArch64::ST1Threev4h);
6631 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6632 VT == MVT::v8bf16) {
6633 SelectStore(Node, 3, AArch64::ST1Threev8h);
6635 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6636 SelectStore(Node, 3, AArch64::ST1Threev2s);
6638 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6639 SelectStore(Node, 3, AArch64::ST1Threev4s);
6641 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6642 SelectStore(Node, 3, AArch64::ST1Threev2d);
6644 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6645 SelectStore(Node, 3, AArch64::ST1Threev1d);
6650 case Intrinsic::aarch64_neon_st1x4: {
6651 if (VT == MVT::v8i8) {
6652 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6654 }
else if (VT == MVT::v16i8) {
6655 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6657 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6658 VT == MVT::v4bf16) {
6659 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6661 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6662 VT == MVT::v8bf16) {
6663 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6665 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6666 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6668 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6669 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6671 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6672 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6674 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6675 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6680 case Intrinsic::aarch64_neon_st2: {
6681 if (VT == MVT::v8i8) {
6682 SelectStore(Node, 2, AArch64::ST2Twov8b);
6684 }
else if (VT == MVT::v16i8) {
6685 SelectStore(Node, 2, AArch64::ST2Twov16b);
6687 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6688 VT == MVT::v4bf16) {
6689 SelectStore(Node, 2, AArch64::ST2Twov4h);
6691 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6692 VT == MVT::v8bf16) {
6693 SelectStore(Node, 2, AArch64::ST2Twov8h);
6695 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6696 SelectStore(Node, 2, AArch64::ST2Twov2s);
6698 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6699 SelectStore(Node, 2, AArch64::ST2Twov4s);
6701 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6702 SelectStore(Node, 2, AArch64::ST2Twov2d);
6704 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6705 SelectStore(Node, 2, AArch64::ST1Twov1d);
6710 case Intrinsic::aarch64_neon_st3: {
6711 if (VT == MVT::v8i8) {
6712 SelectStore(Node, 3, AArch64::ST3Threev8b);
6714 }
else if (VT == MVT::v16i8) {
6715 SelectStore(Node, 3, AArch64::ST3Threev16b);
6717 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6718 VT == MVT::v4bf16) {
6719 SelectStore(Node, 3, AArch64::ST3Threev4h);
6721 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6722 VT == MVT::v8bf16) {
6723 SelectStore(Node, 3, AArch64::ST3Threev8h);
6725 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6726 SelectStore(Node, 3, AArch64::ST3Threev2s);
6728 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6729 SelectStore(Node, 3, AArch64::ST3Threev4s);
6731 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6732 SelectStore(Node, 3, AArch64::ST3Threev2d);
6734 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6735 SelectStore(Node, 3, AArch64::ST1Threev1d);
6740 case Intrinsic::aarch64_neon_st4: {
6741 if (VT == MVT::v8i8) {
6742 SelectStore(Node, 4, AArch64::ST4Fourv8b);
6744 }
else if (VT == MVT::v16i8) {
6745 SelectStore(Node, 4, AArch64::ST4Fourv16b);
6747 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6748 VT == MVT::v4bf16) {
6749 SelectStore(Node, 4, AArch64::ST4Fourv4h);
6751 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6752 VT == MVT::v8bf16) {
6753 SelectStore(Node, 4, AArch64::ST4Fourv8h);
6755 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6756 SelectStore(Node, 4, AArch64::ST4Fourv2s);
6758 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6759 SelectStore(Node, 4, AArch64::ST4Fourv4s);
6761 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6762 SelectStore(Node, 4, AArch64::ST4Fourv2d);
6764 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6765 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6770 case Intrinsic::aarch64_neon_st2lane: {
6771 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6772 SelectStoreLane(Node, 2, AArch64::ST2i8);
6774 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6775 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6776 SelectStoreLane(Node, 2, AArch64::ST2i16);
6778 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6780 SelectStoreLane(Node, 2, AArch64::ST2i32);
6782 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6784 SelectStoreLane(Node, 2, AArch64::ST2i64);
6789 case Intrinsic::aarch64_neon_st3lane: {
6790 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6791 SelectStoreLane(Node, 3, AArch64::ST3i8);
6793 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6794 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6795 SelectStoreLane(Node, 3, AArch64::ST3i16);
6797 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6799 SelectStoreLane(Node, 3, AArch64::ST3i32);
6801 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6803 SelectStoreLane(Node, 3, AArch64::ST3i64);
6808 case Intrinsic::aarch64_neon_st4lane: {
6809 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
6810 SelectStoreLane(Node, 4, AArch64::ST4i8);
6812 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
6813 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
6814 SelectStoreLane(Node, 4, AArch64::ST4i16);
6816 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
6818 SelectStoreLane(Node, 4, AArch64::ST4i32);
6820 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
6822 SelectStoreLane(Node, 4, AArch64::ST4i64);
6827 case Intrinsic::aarch64_sve_st2q: {
6828 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
6831 case Intrinsic::aarch64_sve_st3q: {
6832 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
6835 case Intrinsic::aarch64_sve_st4q: {
6836 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
6839 case Intrinsic::aarch64_sve_st2: {
6840 if (VT == MVT::nxv16i8) {
6841 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
6843 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6844 VT == MVT::nxv8bf16) {
6845 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
6847 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6848 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
6850 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6851 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
6856 case Intrinsic::aarch64_sve_st3: {
6857 if (VT == MVT::nxv16i8) {
6858 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
6860 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6861 VT == MVT::nxv8bf16) {
6862 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
6864 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6865 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
6867 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6868 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
6873 case Intrinsic::aarch64_sve_st4: {
6874 if (VT == MVT::nxv16i8) {
6875 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
6877 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6878 VT == MVT::nxv8bf16) {
6879 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
6881 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6882 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
6884 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6885 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
6893 case AArch64ISD::LD2post: {
6894 if (VT == MVT::v8i8) {
6895 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
6897 }
else if (VT == MVT::v16i8) {
6898 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
6900 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6901 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
6903 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6904 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
6906 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6907 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
6909 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6910 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
6912 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6913 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6915 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6916 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
6921 case AArch64ISD::LD3post: {
6922 if (VT == MVT::v8i8) {
6923 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
6925 }
else if (VT == MVT::v16i8) {
6926 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
6928 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6929 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
6931 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6932 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
6934 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6935 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
6937 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6938 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
6940 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6941 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
6943 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6944 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
6949 case AArch64ISD::LD4post: {
6950 if (VT == MVT::v8i8) {
6951 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
6953 }
else if (VT == MVT::v16i8) {
6954 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
6956 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6957 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
6959 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6960 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
6962 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6963 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
6965 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6966 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
6968 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6969 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
6971 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6972 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
6977 case AArch64ISD::LD1x2post: {
6978 if (VT == MVT::v8i8) {
6979 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
6981 }
else if (VT == MVT::v16i8) {
6982 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
6984 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
6985 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
6987 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
6988 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
6990 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6991 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
6993 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6994 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
6996 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6997 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
6999 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7000 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7005 case AArch64ISD::LD1x3post: {
7006 if (VT == MVT::v8i8) {
7007 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7009 }
else if (VT == MVT::v16i8) {
7010 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7012 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7013 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7015 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7016 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7018 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7019 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7021 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7022 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7024 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7025 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7027 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7028 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7033 case AArch64ISD::LD1x4post: {
7034 if (VT == MVT::v8i8) {
7035 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7037 }
else if (VT == MVT::v16i8) {
7038 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7040 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7041 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7043 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7044 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7046 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7047 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7049 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7050 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7052 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7053 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7055 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7056 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7061 case AArch64ISD::LD1DUPpost: {
7062 if (VT == MVT::v8i8) {
7063 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7065 }
else if (VT == MVT::v16i8) {
7066 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7068 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7069 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7071 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7072 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7074 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7075 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7077 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7078 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7080 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7081 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7083 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7084 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7089 case AArch64ISD::LD2DUPpost: {
7090 if (VT == MVT::v8i8) {
7091 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7093 }
else if (VT == MVT::v16i8) {
7094 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7096 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7097 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7099 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7100 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7102 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7103 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7105 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7106 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7108 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7109 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7111 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7112 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7117 case AArch64ISD::LD3DUPpost: {
7118 if (VT == MVT::v8i8) {
7119 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7121 }
else if (VT == MVT::v16i8) {
7122 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7124 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7125 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7127 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7128 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7130 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7131 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7133 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7134 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7136 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7137 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7139 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7140 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7145 case AArch64ISD::LD4DUPpost: {
7146 if (VT == MVT::v8i8) {
7147 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7149 }
else if (VT == MVT::v16i8) {
7150 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7152 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7153 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7155 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7156 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7158 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7159 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7161 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7162 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7164 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7165 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7167 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7168 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7173 case AArch64ISD::LD1LANEpost: {
7174 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7175 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7177 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7178 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7179 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7181 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7183 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7185 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7187 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7192 case AArch64ISD::LD2LANEpost: {
7193 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7194 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7196 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7197 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7198 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7200 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7202 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7204 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7206 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7211 case AArch64ISD::LD3LANEpost: {
7212 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7213 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7215 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7216 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7217 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7219 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7221 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7223 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7225 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7230 case AArch64ISD::LD4LANEpost: {
7231 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7232 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7234 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7235 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7236 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7238 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7240 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7242 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7244 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7249 case AArch64ISD::ST2post: {
7250 VT =
Node->getOperand(1).getValueType();
7251 if (VT == MVT::v8i8) {
7252 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7254 }
else if (VT == MVT::v16i8) {
7255 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7257 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7258 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7260 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7261 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7263 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7264 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7266 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7267 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7269 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7270 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7272 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7273 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7278 case AArch64ISD::ST3post: {
7279 VT =
Node->getOperand(1).getValueType();
7280 if (VT == MVT::v8i8) {
7281 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7283 }
else if (VT == MVT::v16i8) {
7284 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7286 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7287 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7289 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7290 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7292 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7293 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7295 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7296 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7298 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7299 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7301 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7302 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7307 case AArch64ISD::ST4post: {
7308 VT =
Node->getOperand(1).getValueType();
7309 if (VT == MVT::v8i8) {
7310 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7312 }
else if (VT == MVT::v16i8) {
7313 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7315 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7316 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7318 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7319 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7321 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7322 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7324 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7325 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7327 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7328 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7330 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7331 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7336 case AArch64ISD::ST1x2post: {
7337 VT =
Node->getOperand(1).getValueType();
7338 if (VT == MVT::v8i8) {
7339 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7341 }
else if (VT == MVT::v16i8) {
7342 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7344 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7345 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7347 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7348 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7350 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7351 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7353 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7354 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7356 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7357 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7359 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7360 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7365 case AArch64ISD::ST1x3post: {
7366 VT =
Node->getOperand(1).getValueType();
7367 if (VT == MVT::v8i8) {
7368 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7370 }
else if (VT == MVT::v16i8) {
7371 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7373 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7374 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7376 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7377 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7379 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7380 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7382 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7383 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7385 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7386 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7388 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7389 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7394 case AArch64ISD::ST1x4post: {
7395 VT =
Node->getOperand(1).getValueType();
7396 if (VT == MVT::v8i8) {
7397 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7399 }
else if (VT == MVT::v16i8) {
7400 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7402 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7403 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7405 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7406 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7408 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7409 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7411 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7412 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7414 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7415 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7417 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7418 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7423 case AArch64ISD::ST2LANEpost: {
7424 VT =
Node->getOperand(1).getValueType();
7425 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7426 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7428 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7429 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7430 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7432 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7434 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7436 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7438 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7443 case AArch64ISD::ST3LANEpost: {
7444 VT =
Node->getOperand(1).getValueType();
7445 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7446 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7448 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7449 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7450 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7452 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7454 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7456 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7458 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7463 case AArch64ISD::ST4LANEpost: {
7464 VT =
Node->getOperand(1).getValueType();
7465 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7466 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7468 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7469 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7470 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7472 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7474 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7476 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7478 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7493 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7505 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7509 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7510 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7525 return MemIntr->getMemoryVT();
7532 DataVT = Load->getValueType(0);
7534 DataVT = Load->getValueType(0);
7536 DataVT = Store->getValue().getValueType();
7538 DataVT = Store->getValue().getValueType();
7545 const unsigned Opcode = Root->
getOpcode();
7549 case AArch64ISD::LD1_MERGE_ZERO:
7550 case AArch64ISD::LD1S_MERGE_ZERO:
7551 case AArch64ISD::LDNF1_MERGE_ZERO:
7552 case AArch64ISD::LDNF1S_MERGE_ZERO:
7554 case AArch64ISD::ST1_PRED:
7566 case Intrinsic::aarch64_sme_ldr:
7567 case Intrinsic::aarch64_sme_str:
7568 return MVT::nxv16i8;
7569 case Intrinsic::aarch64_sve_prf:
7574 case Intrinsic::aarch64_sve_ld2_sret:
7575 case Intrinsic::aarch64_sve_ld2q_sret:
7578 case Intrinsic::aarch64_sve_st2q:
7581 case Intrinsic::aarch64_sve_ld3_sret:
7582 case Intrinsic::aarch64_sve_ld3q_sret:
7585 case Intrinsic::aarch64_sve_st3q:
7588 case Intrinsic::aarch64_sve_ld4_sret:
7589 case Intrinsic::aarch64_sve_ld4q_sret:
7592 case Intrinsic::aarch64_sve_st4q:
7595 case Intrinsic::aarch64_sve_ld1udq:
7596 case Intrinsic::aarch64_sve_st1dq:
7597 return EVT(MVT::nxv1i64);
7598 case Intrinsic::aarch64_sve_ld1uwq:
7599 case Intrinsic::aarch64_sve_st1wq:
7600 return EVT(MVT::nxv1i32);
7607template <
int64_t Min,
int64_t Max>
7608bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root,
SDValue N,
7612 const DataLayout &
DL = CurDAG->getDataLayout();
7613 const MachineFrameInfo &MFI = MF->getFrameInfo();
7621 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7635 int64_t MulImm = std::numeric_limits<int64_t>::max();
7639 int64_t ByteOffset =
C->getSExtValue();
7640 const auto KnownVScale =
7643 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7646 MulImm = ByteOffset / KnownVScale;
7653 if ((MulImm % MemWidthBytes) != 0)
7656 int64_t
Offset = MulImm / MemWidthBytes;
7660 Base =
N.getOperand(0);
7669 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
7675bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(
SDValue N,
unsigned Scale,
7694 int64_t ImmOff =
C->getSExtValue();
7695 unsigned Size = 1 << Scale;
7704 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
7706 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
7717 if (
C->getZExtValue() == Scale) {
7726bool AArch64DAGToDAGISel::SelectAllActivePredicate(
SDValue N) {
7727 const AArch64TargetLowering *TLI =
7728 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
7733bool AArch64DAGToDAGISel::SelectAnyPredicate(
SDValue N) {
7734 EVT VT =
N.getValueType();
7738bool AArch64DAGToDAGISel::SelectSMETileSlice(
SDValue N,
unsigned MaxSize,
7743 int64_t ImmOff =
C->getSExtValue();
7744 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
7745 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
7750 if (
SDValue C = MatchConstantOffset(
N)) {
7751 Base = CurDAG->getConstant(0, SDLoc(
N), MVT::i32);
7757 if (CurDAG->isBaseWithConstantOffset(
N)) {
7758 if (
SDValue C = MatchConstantOffset(
N.getOperand(1))) {
7759 Base =
N.getOperand(0);
7767 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7771bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P,
SDValue N,
7791 uint64_t LowerBound = 0, UpperBound = 64;
7809 if (CN->getAPIntValue().uge(LowerBound) &&
7810 CN->getAPIntValue().ult(UpperBound)) {
7812 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
7820template <
bool MatchCBB>
7827 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
7829 Reg =
N.getOperand(0);
7831 SDLoc(
N), MVT::i32);
7839 Reg =
N.getOperand(0);
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
static int getIntOperandFromRegisterString(StringRef RegString)
static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG)
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 regi...
static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
Does DstMask form a complementary pair with the mask provided by BitsToBeInserted,...
static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N)
Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32,...
static bool isSeveralBitsPositioningOpFromShl(const uint64_t ShlImm, SDValue Op, SDValue &Src, int &DstLSB, int &Width)
static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &DstLSB, int &Width)
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL,...
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static bool isPreferredADD(int64_t ImmOff)
static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
Create a machine node performing a notional SHL of Op by ShlAmount.
static bool isWorthFoldingSHL(SDValue V)
Determine whether it is worth it to fold SHL into the addressing mode.
static bool isBitfieldPositioningOpFromAnd(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
static bool tryOrrWithShift(SDNode *N, SDValue OrOpd0, SDValue OrOpd1, SDValue Src, SDValue Dst, SelectionDAG *CurDAG, const bool BiggerPattern)
static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
static bool isMemOpOrPrefetch(SDNode *N)
static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static AArch64_AM::ShiftExtendType getExtendTypeForNode(SDValue N, bool IsLoadStore=false)
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
static bool isIntImmediate(const SDNode *N, uint64_t &Imm)
isIntImmediate - This method tests to see if the node is a constant operand.
static bool isWorthFoldingIntoOrrWithShift(SDValue Dst, SelectionDAG *CurDAG, SDValue &ShiftedOperand, uint64_t &EncodedShiftImm)
static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range, unsigned Size)
Check if the immediate offset is valid as a scaled immediate.
static bool isBitfieldPositioningOpFromShl(SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, const uint64_t NonZeroBits, SDValue &Src, int &DstLSB, int &Width)
static 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
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 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.
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 constexpr unsigned SVEBitsPerBlock
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
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.
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.
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.