25#include "llvm/IR/IntrinsicsAArch64.h"
36#define DEBUG_TYPE "aarch64-isel"
37#define PASS_NAME "AArch64 Instruction Selection"
40#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
41#pragma inline_depth(0)
57 AArch64DAGToDAGISel() =
delete;
69 void PreprocessISelDAG()
override;
73 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
75 std::vector<SDValue> &OutOps)
override;
77 template <
signed Low,
signed High,
signed Scale>
80 template <
signed Low,
signed High>
88 return SelectShiftedRegister(
N,
false,
Reg, Shift);
91 return SelectShiftedRegister(
N,
true,
Reg, Shift);
93 template <
unsigned ShiftW
idth>
97 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
100 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
103 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
106 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
109 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
112 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
115 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
118 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
121 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
124 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
127 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
130 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
133 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
136 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
139 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
142 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
145 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
147 template <
unsigned Size,
unsigned Max>
151 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
154 int64_t
C = CI->getSExtValue();
162 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
169 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
175 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
180 N =
N->getOperand(0);
184 EVT VT =
N->getValueType(0);
185 EVT LVT =
N->getOperand(0).getValueType();
186 unsigned Index =
N->getConstantOperandVal(1);
190 Res =
N->getOperand(0);
195 if (
N.getOpcode() != AArch64ISD::VLSHR)
198 EVT VT =
Op.getValueType();
199 unsigned ShtAmt =
N->getConstantOperandVal(1);
204 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
206 Op.getOperand(1).getConstantOperandVal(0)
207 <<
Op.getOperand(1).getConstantOperandVal(1));
208 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
211 Op.getOperand(1).getConstantOperandVal(0));
215 if (
Imm != 1ULL << (ShtAmt - 1))
218 Res1 =
Op.getOperand(0);
219 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
223 bool SelectDupZeroOrUndef(
SDValue N) {
224 switch(
N->getOpcode()) {
228 case AArch64ISD::DUP:
230 auto Opnd0 =
N->getOperand(0);
244 bool SelectAny(
SDValue) {
return true; }
247 switch(
N->getOpcode()) {
248 case AArch64ISD::DUP:
250 auto Opnd0 =
N->getOperand(0);
262 template <MVT::SimpleValueType VT,
bool Negate>
264 return SelectSVEAddSubImm(
N, VT,
Imm, Shift, Negate);
267 template <MVT::SimpleValueType VT,
bool Negate>
269 return SelectSVEAddSubSSatImm(
N, VT,
Imm, Shift, Negate);
272 template <MVT::SimpleValueType VT>
274 return SelectSVECpyDupImm(
N, VT,
Imm, Shift);
277 template <MVT::SimpleValueType VT,
bool Invert = false>
279 return SelectSVELogicalImm(
N, VT,
Imm, Invert);
282 template <MVT::SimpleValueType VT>
284 return SelectSVEArithImm(
N, VT,
Imm);
287 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
289 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation,
Imm);
296 EVT EltVT =
N->getValueType(0).getVectorElementType();
297 return SelectSVEShiftImm(
N->getOperand(0), 1,
303 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
310 MulImm = 1LL << MulImm;
312 if ((MulImm % std::abs(Scale)) != 0)
316 if ((MulImm >= Min) && (MulImm <= Max)) {
317 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
324 template <
signed Max,
signed Scale>
331 if (MulImm >= 0 && MulImm <= Max) {
333 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
340 template <
unsigned BaseReg,
unsigned Max>
348 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
371 const unsigned SubRegs[]);
373 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
375 bool tryIndexedLoad(
SDNode *
N);
377 void SelectPtrauthAuth(
SDNode *
N);
378 void SelectPtrauthResign(
SDNode *
N);
379 void SelectPtrauthResignWithPC(
SDNode *
N);
381 bool trySelectStackSlotTagP(
SDNode *
N);
384 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
386 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
388 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
389 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
390 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
391 unsigned Opc_rr,
unsigned Opc_ri,
392 bool IsIntr =
false);
393 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
394 unsigned Scale,
unsigned Opc_ri,
396 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
397 bool IsZmMulti,
unsigned Opcode,
398 bool HasPred =
false);
400 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
401 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
402 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
403 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
404 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
405 bool IsTupleInput,
unsigned Opc);
406 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
408 template <
unsigned MaxIdx,
unsigned Scale>
409 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
411 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
412 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
413 unsigned BaseReg = 0);
415 template <
int64_t Min,
int64_t Max>
419 template <
unsigned Scale>
421 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
424 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
426 void SelectMultiVectorLuti6LaneX4(
SDNode *
Node,
unsigned NumIndexVecs);
428 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc,
431 template <
unsigned MaxIdx,
unsigned Scale>
436 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
437 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
438 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
439 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
440 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
441 unsigned Opc_rr,
unsigned Opc_ri);
442 std::tuple<unsigned, SDValue, SDValue>
443 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
447 bool tryBitfieldExtractOp(
SDNode *
N);
448 bool tryBitfieldInsertOp(
SDNode *
N);
449 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
451 bool tryReadRegister(
SDNode *
N);
452 bool tryWriteRegister(
SDNode *
N);
454 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
455 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
459 bool tryFoldCselToFMaxMin(
SDNode *
N);
462#include "AArch64GenDAGISel.inc"
470 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
472 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
485 bool isWorthNegatingImm(
SDValue V)
const;
486 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
487 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
488 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
491 template<
unsigned RegW
idth>
493 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
495 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
497 template <
unsigned RegW
idth>
499 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
501 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
503 template<
unsigned RegW
idth>
505 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
511 template <
unsigned FloatW
idth>
513 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
519 bool SelectCMP_SWAP(
SDNode *
N);
551 bool SelectAllActivePredicate(
SDValue N);
556 template <
bool MatchCBB>
566 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
570char AArch64DAGToDAGISelLegacy::ID = 0;
576 std::make_unique<AArch64DAGToDAGISel>(TM, TM.getOptLevel())) {}
582 auto getFloatVT = [&](
EVT VT) {
584 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
585 return VT.changeElementType(*(DAG.
getContext()),
586 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
591 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
592 auto bitcasted = DAG.
getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
596 EVT OrigVT =
N.getValueType(0);
605 Imm =
C->getZExtValue();
622 return N->getOpcode() ==
Opc &&
633 return Imm == ImmExpected;
638 assert(RegWidth == 32 || RegWidth == 64);
640 return APInt(RegWidth,
648 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
649 if (
N->getOpcode() == AArch64ISD::NVCAST ||
651 N =
N->getOperand(0);
652 unsigned SplatWidth =
N.getScalarValueSizeInBits();
653 if (
N.getOpcode() == AArch64ISD::FMOV)
655 if (
N->getOpcode() == AArch64ISD::MOVI)
656 return APInt(SplatWidth,
N.getConstantOperandVal(0));
657 if (
N->getOpcode() == AArch64ISD::MOVIshift)
658 return APInt(SplatWidth,
N.getConstantOperandVal(0)
659 <<
N.getConstantOperandVal(1));
660 if (
N->getOpcode() == AArch64ISD::MVNIshift)
661 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
662 <<
N.getConstantOperandVal(1));
663 if (
N->getOpcode() == AArch64ISD::MOVIedit)
665 N.getConstantOperandVal(0)));
666 if (
N->getOpcode() == AArch64ISD::DUP)
668 return Const->getAPIntValue().trunc(SplatWidth);
671 return SplatVal.
trunc(SplatWidth);
679static std::optional<APInt>
681 unsigned SplatWidth =
N.getScalarValueSizeInBits();
683 if (SplatVal->getBitWidth() <= SplatWidth)
685 if (SplatVal->isSplat(SplatWidth))
686 return SplatVal->trunc(SplatWidth);
691bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
698 ImmVal->getZExtValue(), Encoding))
701 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
705bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(SDValue
N, SDValue &
Imm,
708 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
709 N.getValueType().getScalarType().getSimpleVT(),
715bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(SDValue
N,
718 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal,
Imm);
722bool AArch64DAGToDAGISel::SelectNEONSplatOfSImm8(SDValue
N, SDValue &
Imm) {
727 int64_t ImmVal = ImmAPIntVal->getSExtValue();
728 if (ImmVal < -128 || ImmVal > 127)
731 Imm = CurDAG->getSignedTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
735bool AArch64DAGToDAGISel::SelectNEONSplatOfUImm8(SDValue
N, SDValue &
Imm) {
740 uint64_t ImmVal = ImmAPIntVal->getZExtValue();
744 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
748bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
750 std::vector<SDValue> &OutOps) {
751 switch(ConstraintID) {
754 case InlineAsm::ConstraintCode::m:
755 case InlineAsm::ConstraintCode::o:
756 case InlineAsm::ConstraintCode::Q:
763 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
765 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
766 dl,
Op.getValueType(),
768 OutOps.push_back(NewOp);
780 switch (User->getOpcode()) {
785 return User->getOperand(1).getNode() == N.getNode();
786 case ISD::ANY_EXTEND:
787 case ISD::ZERO_EXTEND:
788 case ISD::SIGN_EXTEND:
791 return allUsesAreShiftAmounts(SDValue(User, 0));
798template <
unsigned ShiftW
idth>
799bool AArch64DAGToDAGISel::SelectShiftMask(SDValue
N, SDValue &ShAmt) {
808 (
N.getValueType() == MVT::i32 ||
N.getValueType() == MVT::i64)) {
820 (
N.getValueType() == MVT::i32 ||
N.getValueType() == MVT::i64)) {
823 (
Imm % ShiftWidth == 0)) {
832 (
N.getValueType() == MVT::i32 ||
N.getValueType() == MVT::i64)) {
835 (
Imm % ShiftWidth == 0)) {
837 EVT VT =
N.getValueType();
838 bool Is32 = VT == MVT::i32;
839 unsigned NegOpc = Is32 ? AArch64::SUBWrr : AArch64::SUBXrr;
840 unsigned ZeroReg = Is32 ? AArch64::WZR : AArch64::XZR;
842 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, VT);
844 CurDAG->getMachineNode(NegOpc,
DL, VT, Zero,
N.getOperand(1));
845 ShAmt = SDValue(Neg, 0);
853 (
N.getValueType() == MVT::i32 ||
N.getValueType() == MVT::i64)) {
856 (
Imm % ShiftWidth == ShiftWidth - 1)) {
858 EVT VT =
N.getValueType();
859 bool Is32 = VT == MVT::i32;
860 unsigned NotOpc = Is32 ? AArch64::ORNWrr : AArch64::ORNXrr;
861 unsigned ZeroReg = Is32 ? AArch64::WZR : AArch64::XZR;
863 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, VT);
865 CurDAG->getMachineNode(NotOpc,
DL, VT, Zero,
N.getOperand(1));
866 ShAmt = SDValue(
Not, 0);
877bool AArch64DAGToDAGISel::SelectArithImmed(SDValue
N, SDValue &Val,
887 uint64_t Immed =
N.getNode()->getAsZExtVal();
897 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
898 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
904bool AArch64DAGToDAGISel::SelectNegArithImmed(SDValue
N, SDValue &Val,
915 uint64_t Immed =
N.getNode()->getAsZExtVal();
923 if (
N.getValueType() == MVT::i32)
924 Immed = ~((uint32_t)Immed) + 1;
926 Immed = ~Immed + 1ULL;
927 if (Immed & 0xFFFFFFFFFF000000ULL)
930 Immed &= 0xFFFFFFULL;
931 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
938 switch (
N.getOpcode()) {
964 unsigned ShiftVal = CSD->getZExtValue();
982bool AArch64DAGToDAGISel::isWorthFoldingAddr(SDValue V,
unsigned Size)
const {
985 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
990 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
998 const SDValue
LHS =
V.getOperand(0);
999 const SDValue
RHS =
V.getOperand(1);
1012bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(SDValue
N, SDValue &
Reg,
1014 EVT VT =
N.getValueType();
1015 if (VT != MVT::i32 && VT != MVT::i64)
1018 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
1020 SDValue
LHS =
N.getOperand(0);
1024 unsigned LHSOpcode =
LHS->getOpcode();
1038 unsigned LowZBits, MaskLen;
1042 unsigned BitWidth =
N.getValueSizeInBits();
1045 unsigned NewShiftOp;
1048 if (LowZBits <= ShiftAmtC)
1051 NewShiftC = LowZBits - ShiftAmtC;
1052 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
1058 NewShiftC = LowZBits + ShiftAmtC;
1067 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
1069 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
1073 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
1077 MSB = std::min<uint64_t>(NewShiftC + MaskLen,
BitWidth) - 1;
1078 SDValue MSBC = CurDAG->getTargetConstant(MSB,
DL, VT);
1079 Reg = SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
1083 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
1097 SrcVT =
N.getOperand(0).getValueType();
1099 if (!IsLoadStore && SrcVT == MVT::i8)
1101 else if (!IsLoadStore && SrcVT == MVT::i16)
1103 else if (SrcVT == MVT::i32)
1105 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
1110 EVT SrcVT =
N.getOperand(0).getValueType();
1111 if (!IsLoadStore && SrcVT == MVT::i8)
1113 else if (!IsLoadStore && SrcVT == MVT::i16)
1115 else if (SrcVT == MVT::i32)
1117 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
1142bool AArch64DAGToDAGISel::isWorthNegatingImm(SDValue V)
const {
1145 EVT VT =
V.getValueType();
1146 assert((VT == MVT::i32 || VT == MVT::i64) &&
"invalid type");
1157 return NewCost.
size() < OrigCost.
size();
1164bool AArch64DAGToDAGISel::isWorthFoldingALU(SDValue V,
bool LSL)
const {
1167 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1172 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1173 V.getConstantOperandVal(1) <= 4 &&
1186bool AArch64DAGToDAGISel::SelectShiftedRegister(SDValue
N,
bool AllowROR,
1187 SDValue &
Reg, SDValue &Shift) {
1188 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1198 unsigned BitSize =
N.getValueSizeInBits();
1199 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1202 Reg =
N.getOperand(0);
1203 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1204 return isWorthFoldingALU(
N,
true);
1215 if (
N.getValueType() == MVT::i32)
1223template<
signed Low,
signed High,
signed Scale>
1224bool AArch64DAGToDAGISel::SelectRDVLImm(SDValue
N, SDValue &
Imm) {
1229 if ((MulImm % std::abs(Scale)) == 0) {
1230 int64_t RDVLImm = MulImm / Scale;
1231 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1232 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1241template <
signed Low,
signed High>
1242bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(SDValue
N, SDValue &
Imm) {
1247 if (MulImm >=
Low && MulImm <=
High) {
1248 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1257bool AArch64DAGToDAGISel::SelectArithExtendedRegister(SDValue
N, SDValue &
Reg,
1259 unsigned ShiftVal = 0;
1274 Reg =
N.getOperand(0).getOperand(0);
1284 SDValue
Op =
N.getOperand(0);
1286 Op =
Op->getOperand(0);
1288 Op.getOperand(0).getValueType().isFixedLengthVector())
1292 Reg =
N.getOperand(0);
1296 auto isDef32 = [](SDValue
N) {
1297 unsigned Opc =
N.getOpcode();
1310 Reg.getValueType() == MVT::i32 &&
1321 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1323 return isWorthFoldingALU(
N);
1328bool AArch64DAGToDAGISel::SelectArithUXTXRegister(SDValue
N, SDValue &
Reg,
1330 unsigned ShiftVal = 0;
1344 Reg =
N.getOperand(0);
1345 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1347 return isWorthFoldingALU(
N);
1356 for (
auto *
User :
N->users()) {
1383bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(SDValue
N,
bool IsSignedImm,
1384 unsigned BW,
unsigned Size,
1388 const DataLayout &
DL = CurDAG->getDataLayout();
1389 const TargetLowering *TLI = getTargetLowering();
1393 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1399 if (CurDAG->isBaseWithConstantOffset(
N)) {
1402 int64_t RHSC =
RHS->getSExtValue();
1404 int64_t
Range = 0x1LL << (BW - 1);
1406 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1407 RHSC < (
Range << Scale)) {
1408 Base =
N.getOperand(0);
1413 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1422 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1423 Base =
N.getOperand(0);
1428 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1439 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1446bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue
N,
unsigned Size,
1447 SDValue &
Base, SDValue &OffImm) {
1449 const DataLayout &
DL = CurDAG->getDataLayout();
1450 const TargetLowering *TLI = getTargetLowering();
1454 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1459 GlobalAddressSDNode *GAN =
1461 Base =
N.getOperand(0);
1471 if (CurDAG->isBaseWithConstantOffset(
N)) {
1473 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1476 Base =
N.getOperand(0);
1481 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1489 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1497 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1506bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(SDValue
N,
unsigned Size,
1509 if (!CurDAG->isBaseWithConstantOffset(
N))
1512 int64_t RHSC =
RHS->getSExtValue();
1513 if (RHSC >= -256 && RHSC < 256) {
1514 Base =
N.getOperand(0);
1517 const TargetLowering *TLI = getTargetLowering();
1518 Base = CurDAG->getTargetFrameIndex(
1521 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1531 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1538bool AArch64DAGToDAGISel::SelectExtendedSHL(SDValue
N,
unsigned Size,
1539 bool WantExtend, SDValue &
Offset,
1540 SDValue &SignExtend) {
1558 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1564 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1567 return isWorthFoldingAddr(
N,
Size);
1570bool AArch64DAGToDAGISel::SelectAddrModeWRO(SDValue
N,
unsigned Size,
1572 SDValue &SignExtend,
1576 SDValue
LHS =
N.getOperand(0);
1577 SDValue
RHS =
N.getOperand(1);
1588 const SDNode *
Node =
N.getNode();
1589 for (SDNode *UI :
Node->users()) {
1595 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1598 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1601 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1606 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1609 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1614 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1618 if (IsExtendedRegisterWorthFolding &&
1625 if (isWorthFoldingAddr(
LHS,
Size))
1630 if (IsExtendedRegisterWorthFolding &&
1637 if (isWorthFoldingAddr(
RHS,
Size))
1649 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1652 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1654 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1655 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1659bool AArch64DAGToDAGISel::SelectAddrModeXRO(SDValue
N,
unsigned Size,
1661 SDValue &SignExtend,
1665 SDValue
LHS =
N.getOperand(0);
1666 SDValue
RHS =
N.getOperand(1);
1672 const SDNode *
Node =
N.getNode();
1673 for (SDNode *UI :
Node->users()) {
1690 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1700 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1701 SDValue MOVIV = SDValue(MOVI, 0);
1707 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1710 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1713 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1718 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1721 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1728 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1729 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1735 static const unsigned RegClassIDs[] = {
1736 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1737 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1738 AArch64::dsub2, AArch64::dsub3};
1744 static const unsigned RegClassIDs[] = {
1745 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1746 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1747 AArch64::qsub2, AArch64::qsub3};
1753 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1754 AArch64::ZPR3RegClassID,
1755 AArch64::ZPR4RegClassID};
1756 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1757 AArch64::zsub2, AArch64::zsub3};
1767 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1768 AArch64::ZPR4Mul4RegClassID};
1769 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1770 AArch64::zsub2, AArch64::zsub3};
1775 const unsigned RegClassIDs[],
1776 const unsigned SubRegs[]) {
1779 if (Regs.
size() == 1)
1790 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1793 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1794 Ops.push_back(Regs[i]);
1795 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1799 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1800 return SDValue(
N, 0);
1803void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1806 EVT VT =
N->getValueType(0);
1808 unsigned ExtOff = isExt;
1811 unsigned Vec0Off = ExtOff + 1;
1817 Ops.push_back(
N->getOperand(1));
1818 Ops.push_back(RegSeq);
1819 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1820 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1823static std::tuple<SDValue, SDValue>
1844 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1849 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1851 return std::make_tuple(
1856void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1859 SDValue Val =
N->getOperand(1);
1860 SDValue AUTKey =
N->getOperand(2);
1861 SDValue AUTDisc =
N->getOperand(3);
1864 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1866 SDValue AUTAddrDisc, AUTConstDisc;
1867 std::tie(AUTConstDisc, AUTAddrDisc) =
1871 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1873 if (
N->getNumOperands() > 4)
1874 Ops.push_back(
N->getOperand(4));
1877 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1878 ReplaceNode(
N, AUT);
1880 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1881 AArch64::X16, Val, SDValue());
1882 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1884 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1885 ReplaceNode(
N, AUT);
1889void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1899 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1904 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1905 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1907 SDValue AUTAddrDisc, AUTConstDisc;
1908 std::tie(AUTConstDisc, AUTAddrDisc) =
1911 SDValue PACAddrDisc, PACConstDisc;
1912 std::tie(PACConstDisc, PACAddrDisc) =
1915 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1916 AArch64::X16, Val, SDValue());
1919 SDValue Addend =
N->getOperand(OffsetBase + 6);
1920 SDValue IncomingChain =
N->getOperand(0);
1921 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1922 PACKey, PACConstDisc, PACAddrDisc,
1923 Addend, IncomingChain, X16Copy.
getValue(1)};
1925 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1926 MVT::i64, MVT::Other,
Ops);
1927 ReplaceNode(
N, AUTRELLOADPAC);
1929 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1930 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1932 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1933 ReplaceNode(
N, AUTPAC);
1937void AArch64DAGToDAGISel::SelectPtrauthResignWithPC(SDNode *
N) {
1949 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1950 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1952 SDValue PACAddrDisc, PACConstDisc;
1953 std::tie(PACConstDisc, PACAddrDisc) =
1956 SDValue X17Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1957 AArch64::X17, Val, SDValue());
1958 SDValue X16Copy = CurDAG->getCopyToReg(
1959 CurDAG->getEntryNode(),
DL, AArch64::X16, AUTDisc, X17Copy.
getValue(1));
1960 SDValue X15Copy = CurDAG->getCopyToReg(
1961 CurDAG->getEntryNode(),
DL, AArch64::X15, AUTPC, X16Copy.
getValue(1));
1963 SDValue
Ops[] = {AUTKey, PACKey, PACConstDisc, PACAddrDisc,
1966 CurDAG->getMachineNode(AArch64::AUTPCPAC,
DL, MVT::i64,
Ops);
1967 ReplaceNode(
N, AUTPCPAC);
1970bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1972 if (
LD->isUnindexed())
1974 EVT VT =
LD->getMemoryVT();
1975 EVT DstVT =
N->getValueType(0);
1979 int OffsetVal = (int)
OffsetOp->getZExtValue();
1984 unsigned Opcode = 0;
1987 bool InsertTo64 =
false;
1990 (!Subtarget->
isLittleEndian() || (Subtarget->requiresStrictAlign() &&
1993 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1994 else if (VT == MVT::i32) {
1996 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1998 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
2000 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
2006 }
else if (VT == MVT::i16) {
2008 if (DstVT == MVT::i64)
2009 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
2011 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
2013 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
2014 InsertTo64 = DstVT == MVT::i64;
2019 }
else if (VT == MVT::i8) {
2021 if (DstVT == MVT::i64)
2022 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
2024 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
2026 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
2027 InsertTo64 = DstVT == MVT::i64;
2032 }
else if (VT == MVT::f16) {
2033 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
2034 }
else if (VT == MVT::bf16) {
2035 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
2036 }
else if (VT == MVT::f32) {
2037 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
2038 }
else if (VT == MVT::f64 || (VT.
is64BitVector() && !UseLd1)) {
2039 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
2041 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
2043 if (IsPre || OffsetVal != 8)
2047 Opcode = AArch64::LD1Onev8b_POST;
2050 Opcode = AArch64::LD1Onev4h_POST;
2053 Opcode = AArch64::LD1Onev2s_POST;
2056 Opcode = AArch64::LD1Onev1d_POST;
2062 if (IsPre || OffsetVal != 16)
2066 Opcode = AArch64::LD1Onev16b_POST;
2069 Opcode = AArch64::LD1Onev8h_POST;
2072 Opcode = AArch64::LD1Onev4s_POST;
2075 Opcode = AArch64::LD1Onev2d_POST;
2082 SDValue Chain =
LD->getChain();
2083 SDValue
Base =
LD->getBasePtr();
2086 SDValue
Offset = UseLd1 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
2087 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
2089 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
2097 SDValue LoadedVal = SDValue(Res, 1);
2099 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
2100 LoadedVal = SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
2101 MVT::i64, LoadedVal, SubReg),
2105 ReplaceUses(SDValue(
N, 0), LoadedVal);
2106 ReplaceUses(SDValue(
N, 1), SDValue(Res, 0));
2107 ReplaceUses(SDValue(
N, 2), SDValue(Res, 2));
2108 CurDAG->RemoveDeadNode(
N);
2112void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
2113 unsigned SubRegIdx) {
2115 EVT VT =
N->getValueType(0);
2118 SDValue
Ops[] = {
N->getOperand(2),
2121 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2123 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2124 SDValue SuperReg = SDValue(Ld, 0);
2125 for (
unsigned i = 0; i < NumVecs; ++i)
2126 ReplaceUses(SDValue(
N, i),
2127 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
2129 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 1));
2134 MachineMemOperand *MemOp = MemIntr->getMemOperand();
2138 CurDAG->RemoveDeadNode(
N);
2141void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
2142 unsigned Opc,
unsigned SubRegIdx) {
2144 EVT VT =
N->getValueType(0);
2147 SDValue
Ops[] = {
N->getOperand(1),
2151 const EVT ResTys[] = {MVT::i64,
2152 MVT::Untyped, MVT::Other};
2154 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2157 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 0));
2160 SDValue SuperReg = SDValue(Ld, 1);
2162 ReplaceUses(SDValue(
N, 0), SuperReg);
2164 for (
unsigned i = 0; i < NumVecs; ++i)
2165 ReplaceUses(SDValue(
N, i),
2166 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
2173 ReplaceUses(SDValue(
N, NumVecs + 1), SDValue(Ld, 2));
2174 CurDAG->RemoveDeadNode(
N);
2180std::tuple<unsigned, SDValue, SDValue>
2181AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
2183 const SDValue &OldBase,
2184 const SDValue &OldOffset,
2186 SDValue NewBase = OldBase;
2187 SDValue NewOffset = OldOffset;
2189 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
2190 N, OldBase, NewBase, NewOffset);
2194 const bool IsRegReg =
2195 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
2198 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
2211template <SelectTypeKind Kind>
2223 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2228 if (EltVT != MVT::i1)
2232 if (EltVT == MVT::bf16)
2234 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2264void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2267 if (
Imm->getZExtValue() > 1)
2271 EVT VT =
N->getValueType(0);
2272 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2)};
2273 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2274 SDValue SuperReg = SDValue(WhilePair, 0);
2276 for (
unsigned I = 0;
I < 2; ++
I)
2277 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2278 AArch64::psub0 +
I,
DL, VT, SuperReg));
2280 CurDAG->RemoveDeadNode(
N);
2283void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2285 EVT VT =
N->getValueType(0);
2287 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2)};
2289 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2290 SDValue SuperReg = SDValue(WhilePair, 0);
2292 for (
unsigned I = 0;
I < 2; ++
I)
2293 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2294 AArch64::psub0 +
I,
DL, VT, SuperReg));
2296 CurDAG->RemoveDeadNode(
N);
2299void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2301 EVT VT =
N->getValueType(0);
2303 SDValue
Ops = createZTuple(Regs);
2305 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2306 SDValue SuperReg = SDValue(Intrinsic, 0);
2307 for (
unsigned i = 0; i < NumVecs; ++i)
2308 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2309 AArch64::zsub0 + i,
DL, VT, SuperReg));
2311 CurDAG->RemoveDeadNode(
N);
2314void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2317 EVT VT =
N->getValueType(0);
2319 Ops.push_back(
N->getOperand(0));
2322 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2323 SDValue SuperReg = SDValue(Instruction, 0);
2325 for (
unsigned i = 0; i < NumVecs; ++i)
2326 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2327 AArch64::zsub0 + i,
DL, VT, SuperReg));
2330 unsigned ChainIdx = NumVecs;
2331 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Instruction, 1));
2332 CurDAG->RemoveDeadNode(
N);
2335void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2340 assert(Opcode != 0 &&
"Unexpected opcode");
2343 EVT VT =
N->getValueType(0);
2344 SDUse *OpsIter =
N->op_begin() + 1;
2347 auto GetMultiVecOperand = [&]() {
2350 return createZMulTuple(Regs);
2354 Ops.push_back(*OpsIter++);
2356 Ops.push_back(GetMultiVecOperand());
2358 Ops.push_back(GetMultiVecOperand());
2360 Ops.push_back(*OpsIter++);
2363 Ops.append(OpsIter,
N->op_end());
2365 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2366 SDValue SuperReg = SDValue(Intrinsic, 0);
2367 for (
unsigned i = 0; i < NumVecs; ++i)
2368 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2369 AArch64::zsub0 + i,
DL, VT, SuperReg));
2371 CurDAG->RemoveDeadNode(
N);
2374void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2375 unsigned Scale,
unsigned Opc_ri,
2376 unsigned Opc_rr,
bool IsIntr) {
2377 assert(Scale < 5 &&
"Invalid scaling value.");
2379 EVT VT =
N->getValueType(0);
2386 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2387 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2389 SDValue
Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
2393 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2395 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2396 SDValue SuperReg = SDValue(
Load, 0);
2397 for (
unsigned i = 0; i < NumVecs; ++i)
2398 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2399 AArch64::zsub0 + i,
DL, VT, SuperReg));
2402 unsigned ChainIdx = NumVecs;
2403 ReplaceUses(SDValue(
N, ChainIdx), SDValue(
Load, 1));
2404 CurDAG->RemoveDeadNode(
N);
2407void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2412 assert(Scale < 4 &&
"Invalid scaling value.");
2414 EVT VT =
N->getValueType(0);
2419 SDValue
Offset = CurDAG->getTargetConstant(0,
DL, MVT::i64);
2422 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2424 SDValue
Ops[] = {PNg,
2428 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2430 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2431 SDValue SuperReg = SDValue(
Load, 0);
2432 for (
unsigned i = 0; i < NumVecs; ++i)
2433 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2434 AArch64::zsub0 + i,
DL, VT, SuperReg));
2437 unsigned ChainIdx = NumVecs;
2438 ReplaceUses(SDValue(
N, ChainIdx), SDValue(
Load, 1));
2439 CurDAG->RemoveDeadNode(
N);
2442void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2444 if (
N->getValueType(0) != MVT::nxv4f32)
2446 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2449void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2450 unsigned NumOutVecs,
2454 if (
Imm->getZExtValue() > MaxImm)
2458 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2461 SDValue Chain =
Node->getOperand(0);
2462 SDValue
Ops[] = {ZtValue,
Node->getOperand(3),
Node->getOperand(4), Chain};
2464 EVT VT =
Node->getValueType(0);
2467 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2468 SDValue SuperReg = SDValue(Instruction, 0);
2470 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2471 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2472 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2475 unsigned ChainIdx = NumOutVecs;
2476 ReplaceUses(SDValue(Node, ChainIdx), SDValue(Instruction, 1));
2477 CurDAG->RemoveDeadNode(Node);
2480void AArch64DAGToDAGISel::SelectMultiVectorLuti6LaneX4(SDNode *Node,
2481 unsigned NumIndexVecs) {
2482 assert((NumIndexVecs == 2 || NumIndexVecs == 3) &&
2483 "unexpected number of index vectors");
2485 constexpr unsigned FirstIndexOp = 3;
2486 unsigned ImmOp = FirstIndexOp + NumIndexVecs;
2488 if (!
Imm ||
Imm->getZExtValue() > 1)
2494 unsigned Lane =
Imm->getZExtValue();
2495 unsigned IndexOp = FirstIndexOp;
2496 if (NumIndexVecs == 3)
2499 SDValue TableTuple = createZTuple({
Node->getOperand(1),
Node->getOperand(2)});
2500 SDValue IndexTuple =
2501 createZTuple({
Node->getOperand(IndexOp),
Node->getOperand(IndexOp + 1)});
2502 SDValue
Ops[] = {TableTuple, IndexTuple,
Node->getOperand(ImmOp)};
2505 EVT VT =
Node->getValueType(0);
2507 CurDAG->getMachineNode(AArch64::LUTI6_4Z2Z2ZI,
DL, MVT::Untyped,
Ops);
2508 SDValue SuperReg = SDValue(Instruction, 0);
2510 for (
unsigned I = 0;
I < 4; ++
I)
2511 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2512 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2514 CurDAG->RemoveDeadNode(Node);
2517void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2518 unsigned NumOutVecs,
2520 unsigned NumInVecs) {
2521 assert((NumInVecs == 2 || NumInVecs == 3) &&
2522 "unexpected number of input vectors");
2525 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2529 SDValue ZTuple = NumInVecs == 3 ? createZTuple(Regs) : createZMulTuple(Regs);
2530 SDValue
Ops[] = {ZtValue, ZTuple,
Node->getOperand(0)};
2533 EVT VT =
Node->getValueType(0);
2536 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2537 SDValue SuperReg = SDValue(Instruction, 0);
2539 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2540 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2541 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2543 ReplaceUses(SDValue(Node, NumOutVecs), SDValue(Instruction, 1));
2544 CurDAG->RemoveDeadNode(Node);
2547void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2550 EVT VT =
N->getValueType(0);
2553 SDValue Zd = createZMulTuple(Regs);
2554 SDValue Zn =
N->getOperand(1 + NumVecs);
2555 SDValue Zm =
N->getOperand(2 + NumVecs);
2557 SDValue
Ops[] = {Zd, Zn, Zm};
2560 SDValue SuperReg = SDValue(Intrinsic, 0);
2561 for (
unsigned i = 0; i < NumVecs; ++i)
2562 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2563 AArch64::zsub0 + i,
DL, VT, SuperReg));
2565 CurDAG->RemoveDeadNode(
N);
2595template <
unsigned MaxIdx,
unsigned Scale>
2596void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2597 unsigned BaseReg,
unsigned Op) {
2598 unsigned TileNum = 0;
2599 if (BaseReg != AArch64::ZA)
2600 TileNum =
N->getConstantOperandVal(2);
2606 if (BaseReg == AArch64::ZA)
2611 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2615 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2617 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2619 EVT VT =
N->getValueType(0);
2620 for (
unsigned I = 0;
I < NumVecs; ++
I)
2621 ReplaceUses(SDValue(
N,
I),
2622 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2625 unsigned ChainIdx = NumVecs;
2626 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Mov, 1));
2627 CurDAG->RemoveDeadNode(
N);
2630void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2631 unsigned Op,
unsigned MaxIdx,
2632 unsigned Scale,
unsigned BaseReg) {
2637 if (BaseReg != AArch64::ZA)
2641 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2648 if (BaseReg != AArch64::ZA )
2649 Ops.push_back(
N->getOperand(2));
2652 Ops.push_back(
N->getOperand(0));
2653 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2655 EVT VT =
N->getValueType(0);
2656 for (
unsigned I = 0;
I < NumVecs; ++
I)
2657 ReplaceUses(SDValue(
N,
I),
2658 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2662 unsigned ChainIdx = NumVecs;
2663 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Mov, 1));
2664 CurDAG->RemoveDeadNode(
N);
2667void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2668 unsigned NumOutVecs,
2672 EVT VT =
N->getValueType(0);
2673 unsigned NumInVecs =
N->getNumOperands() - 1;
2677 assert((NumInVecs == 2 || NumInVecs == 4) &&
2678 "Don't know how to handle multi-register input!");
2680 Ops.push_back(createZMulTuple(Regs));
2683 for (
unsigned I = 0;
I < NumInVecs;
I++)
2684 Ops.push_back(
N->getOperand(1 +
I));
2687 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2688 SDValue SuperReg = SDValue(Res, 0);
2690 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2691 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2692 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2693 CurDAG->RemoveDeadNode(
N);
2696void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2699 EVT VT =
N->getOperand(2)->getValueType(0);
2707 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2716void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2717 unsigned Scale,
unsigned Opc_rr,
2723 SDValue RegSeq = createZTuple(Regs);
2729 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2730 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2736 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2745void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2748 EVT VT =
N->getOperand(2)->getValueType(0);
2749 const EVT ResTys[] = {MVT::i64,
2757 SDValue
Ops[] = {RegSeq,
2761 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2779 SDValue operator()(SDValue V64Reg) {
2805void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2808 EVT VT =
N->getValueType(0);
2820 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2822 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2824 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2826 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2827 SDValue SuperReg = SDValue(Ld, 0);
2830 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2831 AArch64::qsub2, AArch64::qsub3 };
2832 for (
unsigned i = 0; i < NumVecs; ++i) {
2833 SDValue
NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2836 ReplaceUses(SDValue(
N, i), NV);
2839 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 1));
2840 CurDAG->RemoveDeadNode(
N);
2843void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2846 EVT VT =
N->getValueType(0);
2858 const EVT ResTys[] = {MVT::i64,
2861 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2863 SDValue
Ops[] = {RegSeq,
2864 CurDAG->getTargetConstant(LaneNo, dl,
2869 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2872 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 0));
2875 SDValue SuperReg = SDValue(Ld, 1);
2877 ReplaceUses(SDValue(
N, 0),
2881 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2882 AArch64::qsub2, AArch64::qsub3 };
2883 for (
unsigned i = 0; i < NumVecs; ++i) {
2884 SDValue
NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2888 ReplaceUses(SDValue(
N, i), NV);
2893 ReplaceUses(SDValue(
N, NumVecs + 1), SDValue(Ld, 2));
2894 CurDAG->RemoveDeadNode(
N);
2897void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2900 EVT VT =
N->getOperand(2)->getValueType(0);
2912 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2914 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2916 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2925void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2928 EVT VT =
N->getOperand(2)->getValueType(0);
2940 const EVT ResTys[] = {MVT::i64,
2943 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2945 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2949 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2960 unsigned &LSB,
unsigned &MSB,
2961 unsigned NumberOfIgnoredLowBits,
2962 bool BiggerPattern) {
2964 "N must be a AND operation to call this function");
2966 EVT VT =
N->getValueType(0);
2971 assert((VT == MVT::i32 || VT == MVT::i64) &&
2972 "Type checking must have been done before calling this function");
2986 const SDNode *Op0 =
N->getOperand(0).getNode();
2993 if (AndImm & (AndImm + 1))
2996 bool ClampMSB =
false;
3016 ClampMSB = (VT == MVT::i32);
3017 }
else if (BiggerPattern) {
3023 Opd0 =
N->getOperand(0);
3029 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
3032 <<
": Found large shift immediate, this should not happen\n"));
3046 MSB = MSB > 31 ? 31 : MSB;
3048 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3053 SDValue &Opd0,
unsigned &Immr,
3057 EVT VT =
N->getValueType(0);
3059 assert((VT == MVT::i32 || VT == MVT::i64) &&
3060 "Type checking must have been done before calling this function");
3064 Op =
Op->getOperand(0);
3065 VT =
Op->getValueType(0);
3074 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
3078 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
3079 Opd0 =
Op.getOperand(0);
3081 Imms = ShiftImm + Width - 1;
3109 Opd0 =
N->getOperand(0).getOperand(0);
3119 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3126 unsigned &Immr,
unsigned &Imms,
3127 bool BiggerPattern) {
3129 "N must be a SHR/SRA operation to call this function");
3131 EVT VT =
N->getValueType(0);
3136 assert((VT == MVT::i32 || VT == MVT::i64) &&
3137 "Type checking must have been done before calling this function");
3147 Opd0 =
N->getOperand(0).getOperand(0);
3148 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
3154 Opd0 =
N->getOperand(0).getOperand(0);
3157 assert(VT == MVT::i64 &&
"the promoted type should be i64");
3158 }
else if (BiggerPattern) {
3162 Opd0 =
N->getOperand(0);
3171 <<
": Found large shift immediate, this should not happen\n"));
3180 "bad amount in shift node!");
3181 int immr = SrlImm - ShlImm;
3186 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
3188 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
3193 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
3194 unsigned NumberOfIgnoredLowBits = 0,
3195 bool BiggerPattern =
false) {
3196 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
3199 switch (
N->getOpcode()) {
3201 if (!
N->isMachineOpcode())
3206 NumberOfIgnoredLowBits, BiggerPattern);
3215 unsigned NOpc =
N->getMachineOpcode();
3219 case AArch64::SBFMWri:
3220 case AArch64::UBFMWri:
3221 case AArch64::SBFMXri:
3222 case AArch64::UBFMXri:
3224 Opd0 =
N->getOperand(0);
3225 Immr =
N->getConstantOperandVal(1);
3226 Imms =
N->getConstantOperandVal(2);
3233bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3234 unsigned Opc, Immr, Imms;
3239 EVT VT =
N->getValueType(0);
3244 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3245 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3246 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3248 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3249 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3250 MVT::i32, SDValue(BFM, 0));
3255 SDValue
Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3256 CurDAG->getTargetConstant(Imms, dl, VT)};
3257 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3266 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3267 assert((VT == MVT::i32 || VT == MVT::i64) &&
3268 "i32 or i64 mask type expected!");
3272 APInt SignificantDstMask =
3276 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3277 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3310 APInt OpUsefulBits(UsefulBits);
3314 OpUsefulBits <<= MSB -
Imm + 1;
3319 OpUsefulBits <<=
Imm;
3321 OpUsefulBits <<= MSB + 1;
3330 UsefulBits &= OpUsefulBits;
3347 APInt Mask(UsefulBits);
3348 Mask.clearAllBits();
3356 Mask.lshrInPlace(ShiftAmt);
3362 Mask.lshrInPlace(ShiftAmt);
3378 APInt OpUsefulBits(UsefulBits);
3392 OpUsefulBits <<= Width;
3395 if (
Op.getOperand(1) == Orig) {
3397 Mask = ResultUsefulBits & OpUsefulBits;
3401 if (
Op.getOperand(0) == Orig)
3403 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3409 OpUsefulBits <<= Width;
3411 OpUsefulBits <<= LSB;
3413 if (
Op.getOperand(1) == Orig) {
3415 Mask = ResultUsefulBits & OpUsefulBits;
3416 Mask.lshrInPlace(LSB);
3419 if (
Op.getOperand(0) == Orig)
3420 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3437 case AArch64::ANDSWri:
3438 case AArch64::ANDSXri:
3439 case AArch64::ANDWri:
3440 case AArch64::ANDXri:
3444 case AArch64::UBFMWri:
3445 case AArch64::UBFMXri:
3448 case AArch64::ORRWrs:
3449 case AArch64::ORRXrs:
3454 case AArch64::BFMWri:
3455 case AArch64::BFMXri:
3458 case AArch64::STRBBui:
3459 case AArch64::STURBBi:
3465 case AArch64::STRHHui:
3466 case AArch64::STURHHi:
3479 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3481 UsefulBits =
APInt(Bitwidth, 0);
3490 UsersUsefulBits |= UsefulBitsForUse;
3495 UsefulBits &= UsersUsefulBits;
3505 EVT VT =
Op.getValueType();
3508 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3511 if (ShlAmount > 0) {
3514 UBFMOpc, dl, VT,
Op,
3519 assert(ShlAmount < 0 &&
"expected right shift");
3520 int ShrAmount = -ShlAmount;
3533 SDValue &Src,
int &DstLSB,
3540 SDValue &Src,
int &DstLSB,
3546 bool BiggerPattern,
SDValue &Src,
3547 int &DstLSB,
int &Width) {
3548 EVT VT =
Op.getValueType();
3561 switch (
Op.getOpcode()) {
3566 NonZeroBits, Src, DstLSB, Width);
3569 NonZeroBits, Src, DstLSB, Width);
3582 EVT VT =
Op.getValueType();
3583 assert((VT == MVT::i32 || VT == MVT::i64) &&
3584 "Caller guarantees VT is one of i32 or i64");
3597 assert((~AndImm & NonZeroBits) == 0 &&
3598 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3627 if (!BiggerPattern && !AndOp0.
hasOneUse())
3646 <<
"Found large Width in bit-field-positioning -- this indicates no "
3647 "proper combining / constant folding was performed\n");
3656 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3671 "Op.getNode() should be a SHL node to call this function");
3673 "Op.getNode() should shift ShlImm to call this function");
3680 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3704 EVT VT =
Op.getValueType();
3705 assert((VT == MVT::i32 || VT == MVT::i64) &&
3706 "Caller guarantees that type is i32 or i64");
3713 if (!BiggerPattern && !
Op.hasOneUse())
3722 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3730 assert(VT == MVT::i32 || VT == MVT::i64);
3741 EVT VT =
N->getValueType(0);
3742 if (VT != MVT::i32 && VT != MVT::i64)
3760 if (!
And.hasOneUse() ||
3777 if ((OrImm & NotKnownZero) != 0) {
3789 unsigned ImmS = Width - 1;
3795 bool IsBFI = LSB != 0;
3800 unsigned OrChunks = 0, BFIChunks = 0;
3801 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3802 if (((OrImm >> Shift) & 0xFFFF) != 0)
3804 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3807 if (BFIChunks > OrChunks)
3813 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3821 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3830 if (!Dst.hasOneUse())
3833 EVT VT = Dst.getValueType();
3834 assert((VT == MVT::i32 || VT == MVT::i64) &&
3835 "Caller should guarantee that VT is one of i32 or i64");
3863 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3864 unsigned MaskWidth =
3867 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3873 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3874 ShiftedOperand =
SDValue(UBFMNode, 0);
3903 const bool BiggerPattern) {
3904 EVT VT =
N->getValueType(0);
3905 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3906 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3907 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3908 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3909 assert((VT == MVT::i32 || VT == MVT::i64) &&
3910 "Expect result type to be i32 or i64 since N is combinable to BFM");
3917 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3920 if (BiggerPattern) {
3943 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
4005 EVT VT =
N->getValueType(0);
4006 if (VT != MVT::i32 && VT != MVT::i64)
4014 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
4015 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
4035 for (
int I = 0;
I < 4; ++
I) {
4038 unsigned ImmR, ImmS;
4039 bool BiggerPattern =
I / 2;
4040 SDValue OrOpd0Val =
N->getOperand(
I % 2);
4042 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
4048 NumberOfIgnoredLowBits, BiggerPattern)) {
4051 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
4052 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
4057 Width = ImmS - ImmR + 1;
4068 Src, DstLSB, Width)) {
4076 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
4086 APInt BitsToBeInserted =
4089 if ((BitsToBeInserted & ~
Known.Zero) != 0)
4113 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
4146 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4148 if (Src->hasOneUse() &&
4151 Src = Src->getOperand(0);
4161 unsigned ImmS = Width - 1;
4167 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
4175bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
4184 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
4197bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
4201 EVT VT =
N->getValueType(0);
4202 if (VT != MVT::i32 && VT != MVT::i64)
4208 Op0, DstLSB, Width))
4214 unsigned ImmS = Width - 1;
4217 SDValue
Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4218 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4219 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4220 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4227 bool isReciprocal) {
4230 FVal = CN->getValueAPF();
4233 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4243 if (
unsigned FBits =
4256 bool isReciprocal) {
4257 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4258 N.getValueType().getScalarSizeInBits() ==
4259 N.getOperand(0).getValueType().getScalarSizeInBits())
4260 N =
N.getOperand(0);
4262 auto ImmToFloat = [RegWidth](
APInt Imm) {
4276 switch (
N->getOpcode()) {
4277 case AArch64ISD::MOVIshift:
4278 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4279 <<
N.getConstantOperandVal(1)));
4281 case AArch64ISD::FMOV:
4282 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4284 case AArch64ISD::DUP:
4286 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4294 if (
unsigned FBits =
4303bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue
N, SDValue &FixedPos,
4304 unsigned RegWidth) {
4309bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(SDValue
N, SDValue &FixedPos,
4310 unsigned RegWidth) {
4312 CurDAG,
N, FixedPos, RegWidth,
false);
4315bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(SDValue
N,
4317 unsigned RegWidth) {
4319 CurDAG,
N, FixedPos, RegWidth,
true);
4322bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(SDValue
N,
4324 unsigned RegWidth) {
4334 RegString.
split(Fields,
':');
4336 if (Fields.
size() == 1)
4340 &&
"Invalid number of fields in read register string");
4343 bool AllIntFields =
true;
4347 AllIntFields &= !
Field.getAsInteger(10, IntField);
4348 Ops.push_back(IntField);
4352 "Unexpected non-integer value in special register string.");
4357 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) | (
Ops[3] << 3) |
4365bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4367 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4370 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4372 unsigned Opcode64Bit = AArch64::MRS;
4377 const auto *TheReg =
4378 AArch64SysReg::lookupSysRegByName(RegString->getString());
4379 if (TheReg && TheReg->Readable &&
4380 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4381 Imm = TheReg->Encoding;
4387 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4388 Opcode64Bit = AArch64::ADR;
4397 RegString->getString());
4398 unsigned PseudoOp = 0;
4399 if (AArch64::GPR64RegClass.
contains(PReg))
4400 PseudoOp = AArch64::READ_REGISTER_GPR64;
4401 else if (AArch64::FPR64RegClass.
contains(PReg))
4402 PseudoOp = AArch64::READ_REGISTER_FPR64;
4403 if (!ReadIs128Bit && PseudoOp &&
N->getValueType(0) == MVT::i64) {
4404 CurDAG->SelectNodeTo(
N, PseudoOp, MVT::i64, MVT::Other,
4405 {CurDAG->getTargetConstant(PReg,
DL, MVT::i32),
4414 SDValue InChain =
N->getOperand(0);
4415 SDValue SysRegImm = CurDAG->getTargetConstant(
Imm,
DL, MVT::i32);
4416 if (!ReadIs128Bit) {
4417 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4418 {SysRegImm, InChain});
4420 SDNode *MRRS = CurDAG->getMachineNode(
4422 {MVT::Untyped , MVT::Other },
4423 {SysRegImm, InChain});
4427 SDValue
Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4429 SDValue
Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4431 SDValue OutChain = SDValue(MRRS, 1);
4433 ReplaceUses(SDValue(
N, 0),
Lo);
4434 ReplaceUses(SDValue(
N, 1),
Hi);
4435 ReplaceUses(SDValue(
N, 2), OutChain);
4444bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4446 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4449 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4451 if (!WriteIs128Bit) {
4457 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4460 "Expected a constant integer expression.");
4461 unsigned Reg = PMapper->Encoding;
4462 uint64_t Immed =
N->getConstantOperandVal(2);
4463 CurDAG->SelectNodeTo(
4464 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4465 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4471 if (trySelectPState(
4472 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4473 AArch64::MSRpstateImm4))
4475 if (trySelectPState(
4476 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4477 AArch64::MSRpstateImm1))
4486 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4487 if (TheReg && TheReg->Writeable &&
4488 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4489 Imm = TheReg->Encoding;
4499 RegString->getString());
4500 bool IsGPR = AArch64::GPR64RegClass.contains(PReg);
4501 bool IsFPR = AArch64::FPR64RegClass.contains(PReg);
4502 if (!WriteIs128Bit && (IsGPR || IsFPR) &&
4503 N->getOperand(2).getValueType() == MVT::i64) {
4505 CurDAG->getCopyToReg(
N->getOperand(0),
DL, PReg,
N->getOperand(2));
4506 SDValue RegOp = CurDAG->getRegister(PReg, MVT::i64);
4507 SDNode *FakeUse = CurDAG->getMachineNode(TargetOpcode::FAKE_USE,
DL,
4508 MVT::Other, {RegOp,
Copy});
4509 ReplaceUses(SDValue(
N, 0), SDValue(FakeUse, 0));
4510 CurDAG->RemoveDeadNode(
N);
4518 if (!WriteIs128Bit) {
4519 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4520 CurDAG->getTargetConstant(
Imm,
DL, MVT::i32),
4521 N->getOperand(2), InChain);
4525 SDNode *Pair = CurDAG->getMachineNode(
4526 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4527 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4530 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4532 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4534 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4535 CurDAG->getTargetConstant(
Imm,
DL, MVT::i32),
4536 SDValue(Pair, 0), InChain);
4543bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4548 if (Subtarget->hasLSE())
return false;
4550 if (MemTy == MVT::i8)
4551 Opcode = AArch64::CMP_SWAP_8;
4552 else if (MemTy == MVT::i16)
4553 Opcode = AArch64::CMP_SWAP_16;
4554 else if (MemTy == MVT::i32)
4555 Opcode = AArch64::CMP_SWAP_32;
4556 else if (MemTy == MVT::i64)
4557 Opcode = AArch64::CMP_SWAP_64;
4561 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4562 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4564 SDNode *CmpSwap = CurDAG->getMachineNode(
4566 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4571 ReplaceUses(SDValue(
N, 0), SDValue(CmpSwap, 0));
4572 ReplaceUses(SDValue(
N, 1), SDValue(CmpSwap, 2));
4573 CurDAG->RemoveDeadNode(
N);
4579AArch64DAGToDAGISel::decodeMemoryHintFlags(MachineMemOperand *MMO)
const {
4580 int MemoryHint = -1;
4583 return AArch64MemoryHint::NONE;
4596bool AArch64DAGToDAGISel::isAtomicMemoryHint(SDNode *
N,
4601bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue
N, MVT VT, SDValue &
Imm,
4602 SDValue &Shift,
bool Negate) {
4609 return SelectSVEAddSubImm(SDLoc(
N), Val, VT,
Imm, Shift, Negate);
4612bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4613 SDValue &
Imm, SDValue &Shift,
4621 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4628 if ((Val & ~0xff) == 0) {
4629 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4634 if ((Val & ~0xff00) == 0) {
4635 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4647bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(SDValue
N, MVT VT,
4648 SDValue &
Imm, SDValue &Shift,
4671 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4672 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4679 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4680 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4684 if (Val <= 65280 && Val % 256 == 0) {
4685 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4686 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4697bool AArch64DAGToDAGISel::SelectSVECpyDupImm(SDValue
N, MVT VT, SDValue &
Imm,
4707 int32_t ImmVal, ShiftVal;
4712 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4713 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4717bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue
N, SDValue &
Imm) {
4719 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(),
Imm);
4723bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4726 if (ImmVal >= -128 && ImmVal < 128) {
4727 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4733bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue
N, MVT VT, SDValue &
Imm) {
4735 uint64_t ImmVal = CNode->getZExtValue();
4745 ImmVal &= 0xFFFFFFFF;
4754 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4761bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue
N, MVT VT, SDValue &
Imm,
4765 ImmVal = CI->getZExtValue();
4767 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4778 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4787bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue
N,
uint64_t Low,
4791 uint64_t ImmVal = CN->getZExtValue();
4798 if (ImmVal >
High) {
4799 if (!AllowSaturation)
4804 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4811bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4819 SDValue IRG_SP =
N->getOperand(2);
4825 const TargetLowering *TLI = getTargetLowering();
4828 SDValue FiOp = CurDAG->getTargetFrameIndex(
4830 int TagOffset =
N->getConstantOperandVal(3);
4832 SDNode *
Out = CurDAG->getMachineNode(
4833 AArch64::TAGPstack,
DL, MVT::i64,
4834 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4835 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4836 ReplaceNode(
N, Out);
4840void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4842 "llvm.aarch64.tagp third argument must be an immediate");
4843 if (trySelectStackSlotTagP(
N))
4850 int TagOffset =
N->getConstantOperandVal(3);
4851 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4852 {
N->getOperand(1),
N->getOperand(2)});
4853 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4854 {SDValue(N1, 0),
N->getOperand(2)});
4855 SDNode *N3 = CurDAG->getMachineNode(
4856 AArch64::ADDG,
DL, MVT::i64,
4857 {SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4858 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4862bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4866 if (
N->getConstantOperandVal(2) != 0)
4868 if (!
N->getOperand(0).isUndef())
4872 EVT VT =
N->getValueType(0);
4873 EVT InVT =
N->getOperand(1).getValueType();
4884 "Expected to insert into a packed scalable vector!");
4887 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4888 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4889 N->getOperand(1), RC));
4893bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4897 if (
N->getConstantOperandVal(1) != 0)
4901 EVT VT =
N->getValueType(0);
4902 EVT InVT =
N->getOperand(0).getValueType();
4913 "Expected to extract from a packed scalable vector!");
4916 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4917 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4918 N->getOperand(0), RC));
4922bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4925 SDValue N0 =
N->getOperand(0);
4928 EVT VT =
N->getValueType(0);
4941 (Subtarget->hasSVE2() ||
4942 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4943 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4946 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4950 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4951 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4952 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4959 bool IsXOROperand =
true;
4961 IsXOROperand =
false;
4967 APInt ShlAmt, ShrAmt;
4975 if (!IsXOROperand) {
4976 SDValue
Zero = CurDAG->getTargetConstant(0,
DL, MVT::i64);
4977 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4978 SDValue MOVIV = SDValue(MOV, 0);
4980 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4981 SDNode *SubRegToReg =
4982 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
4985 R2 = SDValue(SubRegToReg, 0);
4993 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
4994 AArch64::XAR_ZZZI_D})) {
4995 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
5020 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
5030 if (N0->
getOpcode() != AArch64ISD::VSHL ||
5038 bool IsXOROperand =
true;
5040 IsXOROperand =
false;
5043 R1 =
XOR.getOperand(0);
5044 R2 =
XOR.getOperand(1);
5050 SDValue
Imm = CurDAG->getTargetConstant(
5054 if (ShAmt + HsAmt != VTSizeInBits)
5057 if (!IsXOROperand) {
5058 SDValue
Zero = CurDAG->getTargetConstant(0,
DL, MVT::i64);
5060 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
5061 SDValue MOVIV = SDValue(MOV, 0);
5069 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
5074 SDValue UndefQ = SDValue(
5075 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
5076 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5078 R1 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5081 if (
R2.getValueType() == VT)
5082 R2 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5087 SDValue SubReg = CurDAG->getTargetConstant(
5090 R1 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
5095 R2 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
5101 SDNode *XAR =
nullptr;
5105 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
5106 AArch64::XAR_ZZZI_D}))
5107 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
5109 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
5112 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
5118 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
5119 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
5120 SDValue(XAR, 0), ZSub);
5122 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5123 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5124 SDValue(Q, 0), DSub);
5126 SDValue SubReg = CurDAG->getTargetConstant(
5129 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5130 SDValue(XAR, 0), SubReg);
5133 ReplaceNode(
N, XAR);
5140 assert(VT == MVT::i32 || VT == MVT::i64);
5142 VT == MVT::i32 ? AArch64::WZR : AArch64::XZR, VT);
5145void AArch64DAGToDAGISel::Select(SDNode *Node) {
5147 if (
Node->isMachineOpcode()) {
5149 Node->setNodeId(-1);
5154 EVT VT =
Node->getValueType(0);
5156 switch (
Node->getOpcode()) {
5161 if (SelectCMP_SWAP(Node))
5166 case AArch64ISD::MRRS:
5167 if (tryReadRegister(Node))
5172 case AArch64ISD::MSRR:
5173 if (tryWriteRegister(Node))
5180 if (tryIndexedLoad(Node))
5189 if (tryBitfieldExtractOp(Node))
5191 if (tryBitfieldInsertInZeroOp(Node))
5199 if (tryBitfieldInsertOp(Node))
5201 if (trySelectXAR(Node))
5206 if (trySelectCastScalableToFixedLengthVector(Node))
5212 if (trySelectCastFixedLengthToScalableVector(Node))
5217 case AArch64ISD::CSEL:
5218 if (tryFoldCselToFMaxMin(Node))
5226 if (ConstNode->
isZero() && (VT == MVT::i32 || VT == MVT::i64)) {
5237 const TargetLowering *TLI = getTargetLowering();
5238 SDValue TFI = CurDAG->getTargetFrameIndex(
5241 SDValue
Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5242 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5243 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5247 unsigned IntNo =
Node->getConstantOperandVal(1);
5251 case Intrinsic::aarch64_gcsss: {
5253 SDValue Chain =
Node->getOperand(0);
5254 SDValue Val =
Node->getOperand(2);
5255 SDValue
Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5257 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5258 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5259 MVT::Other, Zero, SDValue(SS1, 0));
5260 ReplaceNode(Node, SS2);
5263 case Intrinsic::aarch64_ldaxp:
5264 case Intrinsic::aarch64_ldxp: {
5266 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5267 SDValue MemAddr =
Node->getOperand(2);
5269 SDValue Chain =
Node->getOperand(0);
5271 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5272 MVT::Other, MemAddr, Chain);
5275 MachineMemOperand *MemOp =
5278 ReplaceNode(Node, Ld);
5281 case Intrinsic::aarch64_stlxp:
5282 case Intrinsic::aarch64_stxp: {
5284 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5286 SDValue Chain =
Node->getOperand(0);
5287 SDValue ValLo =
Node->getOperand(2);
5288 SDValue ValHi =
Node->getOperand(3);
5289 SDValue MemAddr =
Node->getOperand(4);
5292 SDValue
Ops[] = {ValLo, ValHi, MemAddr, Chain};
5294 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5296 MachineMemOperand *MemOp =
5300 ReplaceNode(Node, St);
5303 case Intrinsic::aarch64_neon_ld1x2:
5304 if (VT == MVT::v8i8) {
5305 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5307 }
else if (VT == MVT::v16i8) {
5308 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5310 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5311 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5313 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5314 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5316 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5317 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5319 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5320 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5322 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5323 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5325 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5326 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5330 case Intrinsic::aarch64_neon_ld1x3:
5331 if (VT == MVT::v8i8) {
5332 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5334 }
else if (VT == MVT::v16i8) {
5335 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5337 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5338 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5340 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5341 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5343 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5344 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5346 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5347 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5349 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5350 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5352 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5353 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5357 case Intrinsic::aarch64_neon_ld1x4:
5358 if (VT == MVT::v8i8) {
5359 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5361 }
else if (VT == MVT::v16i8) {
5362 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5364 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5365 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5367 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5368 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5370 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5371 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5373 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5374 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5376 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5377 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5379 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5380 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5384 case Intrinsic::aarch64_neon_ld2:
5385 if (VT == MVT::v8i8) {
5386 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5388 }
else if (VT == MVT::v16i8) {
5389 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5391 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5392 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5394 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5395 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5397 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5398 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5400 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5401 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5403 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5404 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5406 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5407 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5411 case Intrinsic::aarch64_neon_ld3:
5412 if (VT == MVT::v8i8) {
5413 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5415 }
else if (VT == MVT::v16i8) {
5416 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5418 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5419 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5421 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5422 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5424 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5425 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5427 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5428 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5430 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5431 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5433 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5434 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5438 case Intrinsic::aarch64_neon_ld4:
5439 if (VT == MVT::v8i8) {
5440 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5442 }
else if (VT == MVT::v16i8) {
5443 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5445 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5446 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5448 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5449 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5451 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5452 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5454 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5455 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5457 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5458 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5460 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5461 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5465 case Intrinsic::aarch64_neon_ld2r:
5466 if (VT == MVT::v8i8) {
5467 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5469 }
else if (VT == MVT::v16i8) {
5470 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5472 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5473 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5475 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5476 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5478 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5479 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5481 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5482 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5484 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5485 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5487 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5488 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5492 case Intrinsic::aarch64_neon_ld3r:
5493 if (VT == MVT::v8i8) {
5494 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5496 }
else if (VT == MVT::v16i8) {
5497 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5499 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5500 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5502 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5503 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5505 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5506 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5508 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5509 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5511 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5512 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5514 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5515 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5519 case Intrinsic::aarch64_neon_ld4r:
5520 if (VT == MVT::v8i8) {
5521 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5523 }
else if (VT == MVT::v16i8) {
5524 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5526 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5527 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5529 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5530 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5532 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5533 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5535 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5536 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5538 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5539 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5541 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5542 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5546 case Intrinsic::aarch64_neon_ld2lane:
5547 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5548 SelectLoadLane(Node, 2, AArch64::LD2i8);
5550 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5551 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5552 SelectLoadLane(Node, 2, AArch64::LD2i16);
5554 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5556 SelectLoadLane(Node, 2, AArch64::LD2i32);
5558 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5560 SelectLoadLane(Node, 2, AArch64::LD2i64);
5564 case Intrinsic::aarch64_neon_ld3lane:
5565 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5566 SelectLoadLane(Node, 3, AArch64::LD3i8);
5568 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5569 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5570 SelectLoadLane(Node, 3, AArch64::LD3i16);
5572 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5574 SelectLoadLane(Node, 3, AArch64::LD3i32);
5576 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5578 SelectLoadLane(Node, 3, AArch64::LD3i64);
5582 case Intrinsic::aarch64_neon_ld4lane:
5583 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5584 SelectLoadLane(Node, 4, AArch64::LD4i8);
5586 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5587 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5588 SelectLoadLane(Node, 4, AArch64::LD4i16);
5590 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5592 SelectLoadLane(Node, 4, AArch64::LD4i32);
5594 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5596 SelectLoadLane(Node, 4, AArch64::LD4i64);
5600 case Intrinsic::aarch64_ld64b:
5601 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5603 case Intrinsic::aarch64_sve_ld2q_sret: {
5604 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5607 case Intrinsic::aarch64_sve_ld3q_sret: {
5608 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5611 case Intrinsic::aarch64_sve_ld4q_sret: {
5612 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5615 case Intrinsic::aarch64_sve_ld2_sret: {
5616 if (VT == MVT::nxv16i8) {
5617 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5620 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5621 VT == MVT::nxv8bf16) {
5622 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5625 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5626 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5629 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5630 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5636 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5637 if (VT == MVT::nxv16i8) {
5638 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5639 SelectContiguousMultiVectorLoad(
5640 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5641 else if (Subtarget->hasSVE2p1())
5642 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5647 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5648 VT == MVT::nxv8bf16) {
5649 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5650 SelectContiguousMultiVectorLoad(
5651 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5652 else if (Subtarget->hasSVE2p1())
5653 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5658 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5659 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5660 SelectContiguousMultiVectorLoad(
5661 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5662 else if (Subtarget->hasSVE2p1())
5663 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5668 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5669 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5670 SelectContiguousMultiVectorLoad(
5671 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5672 else if (Subtarget->hasSVE2p1())
5673 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5681 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5682 if (VT == MVT::nxv16i8) {
5683 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5684 SelectContiguousMultiVectorLoad(
5685 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5686 else if (Subtarget->hasSVE2p1())
5687 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5692 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5693 VT == MVT::nxv8bf16) {
5694 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5695 SelectContiguousMultiVectorLoad(
5696 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5697 else if (Subtarget->hasSVE2p1())
5698 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5703 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5704 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5705 SelectContiguousMultiVectorLoad(
5706 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5707 else if (Subtarget->hasSVE2p1())
5708 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5713 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5714 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5715 SelectContiguousMultiVectorLoad(
5716 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5717 else if (Subtarget->hasSVE2p1())
5718 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5726 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5727 if (VT == MVT::nxv16i8) {
5728 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5729 SelectContiguousMultiVectorLoad(Node, 2, 0,
5730 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5731 AArch64::LDNT1B_2Z_PSEUDO);
5732 else if (Subtarget->hasSVE2p1())
5733 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5734 AArch64::LDNT1B_2Z);
5738 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5739 VT == MVT::nxv8bf16) {
5740 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5741 SelectContiguousMultiVectorLoad(Node, 2, 1,
5742 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5743 AArch64::LDNT1H_2Z_PSEUDO);
5744 else if (Subtarget->hasSVE2p1())
5745 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5746 AArch64::LDNT1H_2Z);
5750 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5751 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5752 SelectContiguousMultiVectorLoad(Node, 2, 2,
5753 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5754 AArch64::LDNT1W_2Z_PSEUDO);
5755 else if (Subtarget->hasSVE2p1())
5756 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5757 AArch64::LDNT1W_2Z);
5761 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5762 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5763 SelectContiguousMultiVectorLoad(Node, 2, 3,
5764 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5765 AArch64::LDNT1D_2Z_PSEUDO);
5766 else if (Subtarget->hasSVE2p1())
5767 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5768 AArch64::LDNT1D_2Z);
5775 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5776 if (VT == MVT::nxv16i8) {
5777 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5778 SelectContiguousMultiVectorLoad(Node, 4, 0,
5779 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5780 AArch64::LDNT1B_4Z_PSEUDO);
5781 else if (Subtarget->hasSVE2p1())
5782 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5783 AArch64::LDNT1B_4Z);
5787 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5788 VT == MVT::nxv8bf16) {
5789 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5790 SelectContiguousMultiVectorLoad(Node, 4, 1,
5791 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5792 AArch64::LDNT1H_4Z_PSEUDO);
5793 else if (Subtarget->hasSVE2p1())
5794 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5795 AArch64::LDNT1H_4Z);
5799 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5800 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5801 SelectContiguousMultiVectorLoad(Node, 4, 2,
5802 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5803 AArch64::LDNT1W_4Z_PSEUDO);
5804 else if (Subtarget->hasSVE2p1())
5805 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5806 AArch64::LDNT1W_4Z);
5810 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5811 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5812 SelectContiguousMultiVectorLoad(Node, 4, 3,
5813 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5814 AArch64::LDNT1D_4Z_PSEUDO);
5815 else if (Subtarget->hasSVE2p1())
5816 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5817 AArch64::LDNT1D_4Z);
5824 case Intrinsic::aarch64_sve_ld3_sret: {
5825 if (VT == MVT::nxv16i8) {
5826 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5829 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5830 VT == MVT::nxv8bf16) {
5831 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5834 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5835 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5838 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5839 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5845 case Intrinsic::aarch64_sve_ld4_sret: {
5846 if (VT == MVT::nxv16i8) {
5847 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5850 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5851 VT == MVT::nxv8bf16) {
5852 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5855 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5856 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5859 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5860 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5866 case Intrinsic::aarch64_sme_read_hor_vg2: {
5867 if (VT == MVT::nxv16i8) {
5868 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5869 AArch64::MOVA_2ZMXI_H_B);
5871 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5872 VT == MVT::nxv8bf16) {
5873 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5874 AArch64::MOVA_2ZMXI_H_H);
5876 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5877 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5878 AArch64::MOVA_2ZMXI_H_S);
5880 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5881 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5882 AArch64::MOVA_2ZMXI_H_D);
5887 case Intrinsic::aarch64_sme_read_ver_vg2: {
5888 if (VT == MVT::nxv16i8) {
5889 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5890 AArch64::MOVA_2ZMXI_V_B);
5892 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5893 VT == MVT::nxv8bf16) {
5894 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5895 AArch64::MOVA_2ZMXI_V_H);
5897 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5898 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5899 AArch64::MOVA_2ZMXI_V_S);
5901 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5902 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5903 AArch64::MOVA_2ZMXI_V_D);
5908 case Intrinsic::aarch64_sme_read_hor_vg4: {
5909 if (VT == MVT::nxv16i8) {
5910 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5911 AArch64::MOVA_4ZMXI_H_B);
5913 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5914 VT == MVT::nxv8bf16) {
5915 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5916 AArch64::MOVA_4ZMXI_H_H);
5918 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5919 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5920 AArch64::MOVA_4ZMXI_H_S);
5922 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5923 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5924 AArch64::MOVA_4ZMXI_H_D);
5929 case Intrinsic::aarch64_sme_read_ver_vg4: {
5930 if (VT == MVT::nxv16i8) {
5931 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5932 AArch64::MOVA_4ZMXI_V_B);
5934 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5935 VT == MVT::nxv8bf16) {
5936 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5937 AArch64::MOVA_4ZMXI_V_H);
5939 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5940 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5941 AArch64::MOVA_4ZMXI_V_S);
5943 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5944 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5945 AArch64::MOVA_4ZMXI_V_D);
5950 case Intrinsic::aarch64_sme_read_vg1x2: {
5951 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5952 AArch64::MOVA_VG2_2ZMXI);
5955 case Intrinsic::aarch64_sme_read_vg1x4: {
5956 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5957 AArch64::MOVA_VG4_4ZMXI);
5960 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5961 if (VT == MVT::nxv16i8) {
5962 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5964 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5965 VT == MVT::nxv8bf16) {
5966 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5968 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5969 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5971 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5972 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
5977 case Intrinsic::aarch64_sme_readz_vert_x2: {
5978 if (VT == MVT::nxv16i8) {
5979 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
5981 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5982 VT == MVT::nxv8bf16) {
5983 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
5985 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5986 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
5988 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5989 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
5994 case Intrinsic::aarch64_sme_readz_horiz_x4: {
5995 if (VT == MVT::nxv16i8) {
5996 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
5998 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5999 VT == MVT::nxv8bf16) {
6000 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
6002 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6003 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
6005 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6006 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
6011 case Intrinsic::aarch64_sme_readz_vert_x4: {
6012 if (VT == MVT::nxv16i8) {
6013 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
6015 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6016 VT == MVT::nxv8bf16) {
6017 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
6019 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6020 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
6022 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6023 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
6028 case Intrinsic::aarch64_sme_readz_x2: {
6029 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
6033 case Intrinsic::aarch64_sme_readz_x4: {
6034 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
6038 case Intrinsic::swift_async_context_addr: {
6040 SDValue Chain =
Node->getOperand(0);
6041 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
6042 SDValue Res = SDValue(
6043 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
6044 CurDAG->getTargetConstant(8,
DL, MVT::i32),
6045 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
6047 ReplaceUses(SDValue(Node, 0), Res);
6048 ReplaceUses(SDValue(Node, 1), CopyFP.
getValue(1));
6049 CurDAG->RemoveDeadNode(Node);
6051 auto &MF = CurDAG->getMachineFunction();
6052 MF.getFrameInfo().setFrameAddressIsTaken(
true);
6053 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
6056 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
6058 Node->getValueType(0),
6059 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
6060 AArch64::LUTI2_4ZTZI_S}))
6062 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
6065 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
6067 Node->getValueType(0),
6068 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
6070 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
6073 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
6075 Node->getValueType(0),
6076 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
6077 AArch64::LUTI2_2ZTZI_S}))
6079 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
6082 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
6084 Node->getValueType(0),
6085 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
6086 AArch64::LUTI4_2ZTZI_S}))
6088 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
6091 case Intrinsic::aarch64_sme_luti4_zt_x4: {
6092 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z, 2);
6095 case Intrinsic::aarch64_sme_luti6_zt_x4: {
6096 SelectMultiVectorLuti(Node, 4, AArch64::LUTI6_4ZT3Z, 3);
6099 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
6101 Node->getValueType(0),
6102 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
6103 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6105 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
6107 Node->getValueType(0),
6108 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
6109 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6111 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
6113 Node->getValueType(0),
6114 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
6115 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6117 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
6119 Node->getValueType(0),
6120 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
6121 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6123 case Intrinsic::ptrauth_resign_load_relative:
6124 SelectPtrauthResign(Node);
6129 unsigned IntNo =
Node->getConstantOperandVal(0);
6133 case Intrinsic::aarch64_tagp:
6137 case Intrinsic::ptrauth_auth:
6138 SelectPtrauthAuth(Node);
6141 case Intrinsic::ptrauth_resign:
6142 SelectPtrauthResign(Node);
6145 case Intrinsic::ptrauth_auth_with_pc_and_resign:
6146 SelectPtrauthResignWithPC(Node);
6149 case Intrinsic::aarch64_neon_tbl2:
6150 SelectTable(Node, 2,
6151 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
6154 case Intrinsic::aarch64_neon_tbl3:
6155 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
6156 : AArch64::TBLv16i8Three,
6159 case Intrinsic::aarch64_neon_tbl4:
6160 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6161 : AArch64::TBLv16i8Four,
6164 case Intrinsic::aarch64_neon_tbx2:
6165 SelectTable(Node, 2,
6166 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6169 case Intrinsic::aarch64_neon_tbx3:
6170 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6171 : AArch64::TBXv16i8Three,
6174 case Intrinsic::aarch64_neon_tbx4:
6175 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6176 : AArch64::TBXv16i8Four,
6179 case Intrinsic::aarch64_sve_srshl_single_x2:
6181 Node->getValueType(0),
6182 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6183 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6184 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6186 case Intrinsic::aarch64_sve_srshl_single_x4:
6188 Node->getValueType(0),
6189 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6190 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6191 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6193 case Intrinsic::aarch64_sme_luti6_lane_x4_x2:
6194 SelectMultiVectorLuti6LaneX4(Node, 2);
6196 case Intrinsic::aarch64_sme_luti6_lane_x4_x3:
6197 SelectMultiVectorLuti6LaneX4(Node, 3);
6199 case Intrinsic::aarch64_sve_urshl_single_x2:
6201 Node->getValueType(0),
6202 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6203 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6204 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6206 case Intrinsic::aarch64_sve_urshl_single_x4:
6208 Node->getValueType(0),
6209 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6210 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6211 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6213 case Intrinsic::aarch64_sve_srshl_x2:
6215 Node->getValueType(0),
6216 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6217 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6218 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6220 case Intrinsic::aarch64_sve_srshl_x4:
6222 Node->getValueType(0),
6223 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6224 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6225 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6227 case Intrinsic::aarch64_sve_urshl_x2:
6229 Node->getValueType(0),
6230 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6231 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6232 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6234 case Intrinsic::aarch64_sve_urshl_x4:
6236 Node->getValueType(0),
6237 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6238 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6239 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6241 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6243 Node->getValueType(0),
6244 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6245 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6246 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6248 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6250 Node->getValueType(0),
6251 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6252 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6253 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6255 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6257 Node->getValueType(0),
6258 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6259 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6260 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6262 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6264 Node->getValueType(0),
6265 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6266 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6267 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6269 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6271 Node->getValueType(0),
6272 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6273 AArch64::FSCALE_2ZZ_D}))
6274 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6276 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6278 Node->getValueType(0),
6279 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6280 AArch64::FSCALE_4ZZ_D}))
6281 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6283 case Intrinsic::aarch64_sme_fp8_scale_x2:
6285 Node->getValueType(0),
6286 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6287 AArch64::FSCALE_2Z2Z_D}))
6288 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6290 case Intrinsic::aarch64_sme_fp8_scale_x4:
6292 Node->getValueType(0),
6293 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6294 AArch64::FSCALE_4Z4Z_D}))
6295 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6297 case Intrinsic::aarch64_sve_whilege_x2:
6299 Node->getValueType(0),
6300 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6301 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6302 SelectWhilePair(Node,
Op);
6304 case Intrinsic::aarch64_sve_whilegt_x2:
6306 Node->getValueType(0),
6307 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6308 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6309 SelectWhilePair(Node,
Op);
6311 case Intrinsic::aarch64_sve_whilehi_x2:
6313 Node->getValueType(0),
6314 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6315 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6316 SelectWhilePair(Node,
Op);
6318 case Intrinsic::aarch64_sve_whilehs_x2:
6320 Node->getValueType(0),
6321 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6322 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6323 SelectWhilePair(Node,
Op);
6325 case Intrinsic::aarch64_sve_whilele_x2:
6327 Node->getValueType(0),
6328 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6329 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6330 SelectWhilePair(Node,
Op);
6332 case Intrinsic::aarch64_sve_whilelo_x2:
6334 Node->getValueType(0),
6335 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6336 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6337 SelectWhilePair(Node,
Op);
6339 case Intrinsic::aarch64_sve_whilels_x2:
6341 Node->getValueType(0),
6342 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6343 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6344 SelectWhilePair(Node,
Op);
6346 case Intrinsic::aarch64_sve_whilelt_x2:
6348 Node->getValueType(0),
6349 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6350 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6351 SelectWhilePair(Node,
Op);
6353 case Intrinsic::aarch64_sve_smax_single_x2:
6355 Node->getValueType(0),
6356 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6357 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6358 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6360 case Intrinsic::aarch64_sve_umax_single_x2:
6362 Node->getValueType(0),
6363 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6364 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6365 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6367 case Intrinsic::aarch64_sve_fmax_single_x2:
6369 Node->getValueType(0),
6370 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6371 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6372 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6374 case Intrinsic::aarch64_sve_smax_single_x4:
6376 Node->getValueType(0),
6377 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6378 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6379 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6381 case Intrinsic::aarch64_sve_umax_single_x4:
6383 Node->getValueType(0),
6384 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6385 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6386 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6388 case Intrinsic::aarch64_sve_fmax_single_x4:
6390 Node->getValueType(0),
6391 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6392 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6393 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6395 case Intrinsic::aarch64_sve_smin_single_x2:
6397 Node->getValueType(0),
6398 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6399 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6400 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6402 case Intrinsic::aarch64_sve_umin_single_x2:
6404 Node->getValueType(0),
6405 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6406 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6407 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6409 case Intrinsic::aarch64_sve_fmin_single_x2:
6411 Node->getValueType(0),
6412 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6413 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6414 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6416 case Intrinsic::aarch64_sve_smin_single_x4:
6418 Node->getValueType(0),
6419 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6420 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6421 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6423 case Intrinsic::aarch64_sve_umin_single_x4:
6425 Node->getValueType(0),
6426 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6427 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6428 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6430 case Intrinsic::aarch64_sve_fmin_single_x4:
6432 Node->getValueType(0),
6433 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6434 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6435 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6437 case Intrinsic::aarch64_sve_smax_x2:
6439 Node->getValueType(0),
6440 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6441 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6442 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6444 case Intrinsic::aarch64_sve_umax_x2:
6446 Node->getValueType(0),
6447 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6448 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6449 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6451 case Intrinsic::aarch64_sve_fmax_x2:
6453 Node->getValueType(0),
6454 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6455 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6456 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6458 case Intrinsic::aarch64_sve_smax_x4:
6460 Node->getValueType(0),
6461 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6462 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6463 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6465 case Intrinsic::aarch64_sve_umax_x4:
6467 Node->getValueType(0),
6468 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6469 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6470 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6472 case Intrinsic::aarch64_sve_fmax_x4:
6474 Node->getValueType(0),
6475 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6476 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6477 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6479 case Intrinsic::aarch64_sme_famax_x2:
6481 Node->getValueType(0),
6482 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6483 AArch64::FAMAX_2Z2Z_D}))
6484 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6486 case Intrinsic::aarch64_sme_famax_x4:
6488 Node->getValueType(0),
6489 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6490 AArch64::FAMAX_4Z4Z_D}))
6491 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6493 case Intrinsic::aarch64_sme_famin_x2:
6495 Node->getValueType(0),
6496 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6497 AArch64::FAMIN_2Z2Z_D}))
6498 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6500 case Intrinsic::aarch64_sme_famin_x4:
6502 Node->getValueType(0),
6503 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6504 AArch64::FAMIN_4Z4Z_D}))
6505 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6507 case Intrinsic::aarch64_sve_smin_x2:
6509 Node->getValueType(0),
6510 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6511 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6512 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6514 case Intrinsic::aarch64_sve_umin_x2:
6516 Node->getValueType(0),
6517 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6518 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6519 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6521 case Intrinsic::aarch64_sve_fmin_x2:
6523 Node->getValueType(0),
6524 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6525 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6526 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6528 case Intrinsic::aarch64_sve_smin_x4:
6530 Node->getValueType(0),
6531 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6532 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6533 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6535 case Intrinsic::aarch64_sve_umin_x4:
6537 Node->getValueType(0),
6538 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6539 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6540 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6542 case Intrinsic::aarch64_sve_fmin_x4:
6544 Node->getValueType(0),
6545 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6546 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6547 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6549 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6551 Node->getValueType(0),
6552 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6553 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6554 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6556 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6558 Node->getValueType(0),
6559 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6560 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6561 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6563 case Intrinsic::aarch64_sve_fminnm_single_x2:
6565 Node->getValueType(0),
6566 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6567 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6568 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6570 case Intrinsic::aarch64_sve_fminnm_single_x4:
6572 Node->getValueType(0),
6573 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6574 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6575 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6577 case Intrinsic::aarch64_sve_fscale_single_x4:
6578 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6580 case Intrinsic::aarch64_sve_fscale_single_x2:
6581 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6583 case Intrinsic::aarch64_sve_fmul_single_x4:
6585 Node->getValueType(0),
6586 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6587 AArch64::FMUL_4ZZ_D}))
6588 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6590 case Intrinsic::aarch64_sve_fmul_single_x2:
6592 Node->getValueType(0),
6593 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6594 AArch64::FMUL_2ZZ_D}))
6595 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6597 case Intrinsic::aarch64_sve_fmaxnm_x2:
6599 Node->getValueType(0),
6600 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6601 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6602 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6604 case Intrinsic::aarch64_sve_fmaxnm_x4:
6606 Node->getValueType(0),
6607 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6608 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6609 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6611 case Intrinsic::aarch64_sve_fminnm_x2:
6613 Node->getValueType(0),
6614 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6615 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6616 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6618 case Intrinsic::aarch64_sve_fminnm_x4:
6620 Node->getValueType(0),
6621 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6622 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6623 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6625 case Intrinsic::aarch64_sve_aese_lane_x2:
6626 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6628 case Intrinsic::aarch64_sve_aesd_lane_x2:
6629 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6631 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6632 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6634 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6635 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6637 case Intrinsic::aarch64_sve_aese_lane_x4:
6638 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6640 case Intrinsic::aarch64_sve_aesd_lane_x4:
6641 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6643 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6644 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6646 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6647 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6649 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6650 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6652 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6656 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6657 SDValue SuperReg = SDValue(Res, 0);
6658 for (
unsigned I = 0;
I < 2;
I++)
6659 ReplaceUses(SDValue(Node,
I),
6660 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6662 CurDAG->RemoveDeadNode(Node);
6665 case Intrinsic::aarch64_sve_fscale_x4:
6666 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6668 case Intrinsic::aarch64_sve_fscale_x2:
6669 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6671 case Intrinsic::aarch64_sve_fmul_x4:
6673 Node->getValueType(0),
6674 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6675 AArch64::FMUL_4Z4Z_D}))
6676 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6678 case Intrinsic::aarch64_sve_fmul_x2:
6680 Node->getValueType(0),
6681 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6682 AArch64::FMUL_2Z2Z_D}))
6683 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6685 case Intrinsic::aarch64_sve_fcvtzs_x2:
6686 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6688 case Intrinsic::aarch64_sve_scvtf_x2:
6689 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6691 case Intrinsic::aarch64_sve_fcvtzu_x2:
6692 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6694 case Intrinsic::aarch64_sve_ucvtf_x2:
6695 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6697 case Intrinsic::aarch64_sve_fcvtzs_x4:
6698 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6700 case Intrinsic::aarch64_sve_scvtf_x4:
6701 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6703 case Intrinsic::aarch64_sve_fcvtzu_x4:
6704 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6706 case Intrinsic::aarch64_sve_ucvtf_x4:
6707 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6709 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6710 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6712 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6713 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6715 case Intrinsic::aarch64_sve_sclamp_single_x2:
6717 Node->getValueType(0),
6718 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6719 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6720 SelectClamp(Node, 2,
Op);
6722 case Intrinsic::aarch64_sve_uclamp_single_x2:
6724 Node->getValueType(0),
6725 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6726 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6727 SelectClamp(Node, 2,
Op);
6729 case Intrinsic::aarch64_sve_fclamp_single_x2:
6731 Node->getValueType(0),
6732 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6733 AArch64::FCLAMP_VG2_2Z2Z_D}))
6734 SelectClamp(Node, 2,
Op);
6736 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6737 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6739 case Intrinsic::aarch64_sve_sclamp_single_x4:
6741 Node->getValueType(0),
6742 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6743 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6744 SelectClamp(Node, 4,
Op);
6746 case Intrinsic::aarch64_sve_uclamp_single_x4:
6748 Node->getValueType(0),
6749 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6750 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6751 SelectClamp(Node, 4,
Op);
6753 case Intrinsic::aarch64_sve_fclamp_single_x4:
6755 Node->getValueType(0),
6756 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6757 AArch64::FCLAMP_VG4_4Z4Z_D}))
6758 SelectClamp(Node, 4,
Op);
6760 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6761 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6763 case Intrinsic::aarch64_sve_add_single_x2:
6765 Node->getValueType(0),
6766 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6767 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6768 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6770 case Intrinsic::aarch64_sve_add_single_x4:
6772 Node->getValueType(0),
6773 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6774 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6775 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6777 case Intrinsic::aarch64_sve_zip_x2:
6779 Node->getValueType(0),
6780 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6781 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6782 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6784 case Intrinsic::aarch64_sve_zipq_x2:
6785 SelectUnaryMultiIntrinsic(Node, 2,
false,
6786 AArch64::ZIP_VG2_2ZZZ_Q);
6788 case Intrinsic::aarch64_sve_zip_x4:
6790 Node->getValueType(0),
6791 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6792 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6793 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6795 case Intrinsic::aarch64_sve_zipq_x4:
6796 SelectUnaryMultiIntrinsic(Node, 4,
true,
6797 AArch64::ZIP_VG4_4Z4Z_Q);
6799 case Intrinsic::aarch64_sve_uzp_x2:
6801 Node->getValueType(0),
6802 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6803 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6804 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6806 case Intrinsic::aarch64_sve_uzpq_x2:
6807 SelectUnaryMultiIntrinsic(Node, 2,
false,
6808 AArch64::UZP_VG2_2ZZZ_Q);
6810 case Intrinsic::aarch64_sve_uzp_x4:
6812 Node->getValueType(0),
6813 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6814 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6815 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6817 case Intrinsic::aarch64_sve_uzpq_x4:
6818 SelectUnaryMultiIntrinsic(Node, 4,
true,
6819 AArch64::UZP_VG4_4Z4Z_Q);
6821 case Intrinsic::aarch64_sve_sel_x2:
6823 Node->getValueType(0),
6824 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6825 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6826 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6828 case Intrinsic::aarch64_sve_sel_x4:
6830 Node->getValueType(0),
6831 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6832 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6833 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6835 case Intrinsic::aarch64_sve_frinta_x2:
6836 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6838 case Intrinsic::aarch64_sve_frinta_x4:
6839 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6841 case Intrinsic::aarch64_sve_frintm_x2:
6842 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6844 case Intrinsic::aarch64_sve_frintm_x4:
6845 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6847 case Intrinsic::aarch64_sve_frintn_x2:
6848 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6850 case Intrinsic::aarch64_sve_frintn_x4:
6851 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6853 case Intrinsic::aarch64_sve_frintp_x2:
6854 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6856 case Intrinsic::aarch64_sve_frintp_x4:
6857 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6859 case Intrinsic::aarch64_sve_sunpk_x2:
6861 Node->getValueType(0),
6862 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6863 AArch64::SUNPK_VG2_2ZZ_D}))
6864 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6866 case Intrinsic::aarch64_sve_uunpk_x2:
6868 Node->getValueType(0),
6869 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6870 AArch64::UUNPK_VG2_2ZZ_D}))
6871 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6873 case Intrinsic::aarch64_sve_sunpk_x4:
6875 Node->getValueType(0),
6876 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6877 AArch64::SUNPK_VG4_4Z2Z_D}))
6878 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6880 case Intrinsic::aarch64_sve_uunpk_x4:
6882 Node->getValueType(0),
6883 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6884 AArch64::UUNPK_VG4_4Z2Z_D}))
6885 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6887 case Intrinsic::aarch64_sve_pext_x2: {
6889 Node->getValueType(0),
6890 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6891 AArch64::PEXT_2PCI_D}))
6892 SelectPExtPair(Node,
Op);
6899 unsigned IntNo =
Node->getConstantOperandVal(1);
6900 if (
Node->getNumOperands() >= 3)
6901 VT =
Node->getOperand(2)->getValueType(0);
6905 case Intrinsic::aarch64_neon_st1x2: {
6906 if (VT == MVT::v8i8) {
6907 SelectStore(Node, 2, AArch64::ST1Twov8b);
6909 }
else if (VT == MVT::v16i8) {
6910 SelectStore(Node, 2, AArch64::ST1Twov16b);
6912 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6913 VT == MVT::v4bf16) {
6914 SelectStore(Node, 2, AArch64::ST1Twov4h);
6916 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6917 VT == MVT::v8bf16) {
6918 SelectStore(Node, 2, AArch64::ST1Twov8h);
6920 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6921 SelectStore(Node, 2, AArch64::ST1Twov2s);
6923 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6924 SelectStore(Node, 2, AArch64::ST1Twov4s);
6926 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6927 SelectStore(Node, 2, AArch64::ST1Twov2d);
6929 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6930 SelectStore(Node, 2, AArch64::ST1Twov1d);
6935 case Intrinsic::aarch64_neon_st1x3: {
6936 if (VT == MVT::v8i8) {
6937 SelectStore(Node, 3, AArch64::ST1Threev8b);
6939 }
else if (VT == MVT::v16i8) {
6940 SelectStore(Node, 3, AArch64::ST1Threev16b);
6942 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6943 VT == MVT::v4bf16) {
6944 SelectStore(Node, 3, AArch64::ST1Threev4h);
6946 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6947 VT == MVT::v8bf16) {
6948 SelectStore(Node, 3, AArch64::ST1Threev8h);
6950 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6951 SelectStore(Node, 3, AArch64::ST1Threev2s);
6953 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6954 SelectStore(Node, 3, AArch64::ST1Threev4s);
6956 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6957 SelectStore(Node, 3, AArch64::ST1Threev2d);
6959 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6960 SelectStore(Node, 3, AArch64::ST1Threev1d);
6965 case Intrinsic::aarch64_neon_st1x4: {
6966 if (VT == MVT::v8i8) {
6967 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6969 }
else if (VT == MVT::v16i8) {
6970 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6972 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6973 VT == MVT::v4bf16) {
6974 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6976 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6977 VT == MVT::v8bf16) {
6978 SelectStore(Node, 4, AArch64::ST1Fourv8h);
6980 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6981 SelectStore(Node, 4, AArch64::ST1Fourv2s);
6983 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6984 SelectStore(Node, 4, AArch64::ST1Fourv4s);
6986 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6987 SelectStore(Node, 4, AArch64::ST1Fourv2d);
6989 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6990 SelectStore(Node, 4, AArch64::ST1Fourv1d);
6995 case Intrinsic::aarch64_neon_st2: {
6996 if (VT == MVT::v8i8) {
6997 SelectStore(Node, 2, AArch64::ST2Twov8b);
6999 }
else if (VT == MVT::v16i8) {
7000 SelectStore(Node, 2, AArch64::ST2Twov16b);
7002 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7003 VT == MVT::v4bf16) {
7004 SelectStore(Node, 2, AArch64::ST2Twov4h);
7006 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7007 VT == MVT::v8bf16) {
7008 SelectStore(Node, 2, AArch64::ST2Twov8h);
7010 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7011 SelectStore(Node, 2, AArch64::ST2Twov2s);
7013 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7014 SelectStore(Node, 2, AArch64::ST2Twov4s);
7016 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7017 SelectStore(Node, 2, AArch64::ST2Twov2d);
7019 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7020 SelectStore(Node, 2, AArch64::ST1Twov1d);
7025 case Intrinsic::aarch64_neon_st3: {
7026 if (VT == MVT::v8i8) {
7027 SelectStore(Node, 3, AArch64::ST3Threev8b);
7029 }
else if (VT == MVT::v16i8) {
7030 SelectStore(Node, 3, AArch64::ST3Threev16b);
7032 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7033 VT == MVT::v4bf16) {
7034 SelectStore(Node, 3, AArch64::ST3Threev4h);
7036 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7037 VT == MVT::v8bf16) {
7038 SelectStore(Node, 3, AArch64::ST3Threev8h);
7040 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7041 SelectStore(Node, 3, AArch64::ST3Threev2s);
7043 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7044 SelectStore(Node, 3, AArch64::ST3Threev4s);
7046 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7047 SelectStore(Node, 3, AArch64::ST3Threev2d);
7049 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7050 SelectStore(Node, 3, AArch64::ST1Threev1d);
7055 case Intrinsic::aarch64_neon_st4: {
7056 if (VT == MVT::v8i8) {
7057 SelectStore(Node, 4, AArch64::ST4Fourv8b);
7059 }
else if (VT == MVT::v16i8) {
7060 SelectStore(Node, 4, AArch64::ST4Fourv16b);
7062 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7063 VT == MVT::v4bf16) {
7064 SelectStore(Node, 4, AArch64::ST4Fourv4h);
7066 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7067 VT == MVT::v8bf16) {
7068 SelectStore(Node, 4, AArch64::ST4Fourv8h);
7070 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7071 SelectStore(Node, 4, AArch64::ST4Fourv2s);
7073 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7074 SelectStore(Node, 4, AArch64::ST4Fourv4s);
7076 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7077 SelectStore(Node, 4, AArch64::ST4Fourv2d);
7079 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7080 SelectStore(Node, 4, AArch64::ST1Fourv1d);
7085 case Intrinsic::aarch64_neon_st2lane: {
7086 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7087 SelectStoreLane(Node, 2, AArch64::ST2i8);
7089 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7090 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7091 SelectStoreLane(Node, 2, AArch64::ST2i16);
7093 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7095 SelectStoreLane(Node, 2, AArch64::ST2i32);
7097 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7099 SelectStoreLane(Node, 2, AArch64::ST2i64);
7104 case Intrinsic::aarch64_neon_st3lane: {
7105 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7106 SelectStoreLane(Node, 3, AArch64::ST3i8);
7108 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7109 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7110 SelectStoreLane(Node, 3, AArch64::ST3i16);
7112 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7114 SelectStoreLane(Node, 3, AArch64::ST3i32);
7116 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7118 SelectStoreLane(Node, 3, AArch64::ST3i64);
7123 case Intrinsic::aarch64_neon_st4lane: {
7124 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7125 SelectStoreLane(Node, 4, AArch64::ST4i8);
7127 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7128 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7129 SelectStoreLane(Node, 4, AArch64::ST4i16);
7131 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7133 SelectStoreLane(Node, 4, AArch64::ST4i32);
7135 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7137 SelectStoreLane(Node, 4, AArch64::ST4i64);
7142 case Intrinsic::aarch64_sve_st2q: {
7143 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
7146 case Intrinsic::aarch64_sve_st3q: {
7147 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
7150 case Intrinsic::aarch64_sve_st4q: {
7151 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
7154 case Intrinsic::aarch64_sve_st2: {
7155 if (VT == MVT::nxv16i8) {
7156 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
7158 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7159 VT == MVT::nxv8bf16) {
7160 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
7162 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7163 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7165 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7166 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7171 case Intrinsic::aarch64_sve_st3: {
7172 if (VT == MVT::nxv16i8) {
7173 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7175 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7176 VT == MVT::nxv8bf16) {
7177 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7179 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7180 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7182 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7183 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7188 case Intrinsic::aarch64_sve_st4: {
7189 if (VT == MVT::nxv16i8) {
7190 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7192 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7193 VT == MVT::nxv8bf16) {
7194 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7196 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7197 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7199 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7200 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7208 case AArch64ISD::LD2post: {
7209 if (VT == MVT::v8i8) {
7210 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7212 }
else if (VT == MVT::v16i8) {
7213 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7215 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7216 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7218 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7219 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7221 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7222 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7224 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7225 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7227 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7228 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7230 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7231 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7236 case AArch64ISD::LD3post: {
7237 if (VT == MVT::v8i8) {
7238 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7240 }
else if (VT == MVT::v16i8) {
7241 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7243 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7244 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7246 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7247 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7249 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7250 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7252 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7253 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7255 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7256 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7258 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7259 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7264 case AArch64ISD::LD4post: {
7265 if (VT == MVT::v8i8) {
7266 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7268 }
else if (VT == MVT::v16i8) {
7269 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7271 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7272 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7274 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7275 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7277 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7278 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7280 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7281 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7283 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7284 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7286 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7287 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7292 case AArch64ISD::LD1x2post: {
7293 if (VT == MVT::v8i8) {
7294 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7296 }
else if (VT == MVT::v16i8) {
7297 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7299 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7300 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7302 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7303 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7305 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7306 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7308 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7309 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7311 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7312 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7314 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7315 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7320 case AArch64ISD::LD1x3post: {
7321 if (VT == MVT::v8i8) {
7322 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7324 }
else if (VT == MVT::v16i8) {
7325 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7327 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7328 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7330 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7331 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7333 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7334 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7336 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7337 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7339 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7340 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7342 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7343 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7348 case AArch64ISD::LD1x4post: {
7349 if (VT == MVT::v8i8) {
7350 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7352 }
else if (VT == MVT::v16i8) {
7353 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7355 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7356 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7358 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7359 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7361 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7362 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7364 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7365 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7367 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7368 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7370 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7371 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7376 case AArch64ISD::LD1DUPpost: {
7377 if (VT == MVT::v8i8) {
7378 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7380 }
else if (VT == MVT::v16i8) {
7381 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7383 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7384 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7386 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7387 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7389 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7390 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7392 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7393 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7395 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7396 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7398 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7399 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7404 case AArch64ISD::LD2DUPpost: {
7405 if (VT == MVT::v8i8) {
7406 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7408 }
else if (VT == MVT::v16i8) {
7409 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7411 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7412 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7414 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7415 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7417 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7418 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7420 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7421 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7423 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7424 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7426 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7427 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7432 case AArch64ISD::LD3DUPpost: {
7433 if (VT == MVT::v8i8) {
7434 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7436 }
else if (VT == MVT::v16i8) {
7437 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7439 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7440 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7442 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7443 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7445 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7446 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7448 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7449 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7451 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7452 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7454 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7455 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7460 case AArch64ISD::LD4DUPpost: {
7461 if (VT == MVT::v8i8) {
7462 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7464 }
else if (VT == MVT::v16i8) {
7465 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7467 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7468 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7470 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7471 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7473 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7474 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7476 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7477 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7479 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7480 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7482 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7483 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7488 case AArch64ISD::LD1LANEpost: {
7489 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7490 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7492 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7493 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7494 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7496 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7498 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7500 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7502 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7507 case AArch64ISD::LD2LANEpost: {
7508 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7509 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7511 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7512 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7513 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7515 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7517 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7519 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7521 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7526 case AArch64ISD::LD3LANEpost: {
7527 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7528 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7530 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7531 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7532 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7534 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7536 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7538 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7540 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7545 case AArch64ISD::LD4LANEpost: {
7546 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7547 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7549 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7550 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7551 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7553 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7555 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7557 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7559 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7564 case AArch64ISD::ST2post: {
7565 VT =
Node->getOperand(1).getValueType();
7566 if (VT == MVT::v8i8) {
7567 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7569 }
else if (VT == MVT::v16i8) {
7570 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7572 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7573 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7575 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7576 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7578 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7579 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7581 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7582 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7584 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7585 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7587 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7588 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7593 case AArch64ISD::ST3post: {
7594 VT =
Node->getOperand(1).getValueType();
7595 if (VT == MVT::v8i8) {
7596 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7598 }
else if (VT == MVT::v16i8) {
7599 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7601 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7602 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7604 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7605 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7607 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7608 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7610 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7611 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7613 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7614 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7616 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7617 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7622 case AArch64ISD::ST4post: {
7623 VT =
Node->getOperand(1).getValueType();
7624 if (VT == MVT::v8i8) {
7625 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7627 }
else if (VT == MVT::v16i8) {
7628 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7630 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7631 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7633 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7634 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7636 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7637 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7639 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7640 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7642 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7643 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7645 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7646 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7651 case AArch64ISD::ST1x2post: {
7652 VT =
Node->getOperand(1).getValueType();
7653 if (VT == MVT::v8i8) {
7654 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7656 }
else if (VT == MVT::v16i8) {
7657 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7659 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7660 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7662 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7663 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7665 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7666 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7668 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7669 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7671 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7672 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7674 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7675 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7680 case AArch64ISD::ST1x3post: {
7681 VT =
Node->getOperand(1).getValueType();
7682 if (VT == MVT::v8i8) {
7683 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7685 }
else if (VT == MVT::v16i8) {
7686 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7688 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7689 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7691 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7692 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7694 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7695 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7697 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7698 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7700 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7701 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7703 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7704 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7709 case AArch64ISD::ST1x4post: {
7710 VT =
Node->getOperand(1).getValueType();
7711 if (VT == MVT::v8i8) {
7712 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7714 }
else if (VT == MVT::v16i8) {
7715 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7717 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7718 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7720 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7721 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7723 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7724 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7726 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7727 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7729 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7730 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7732 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7733 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7738 case AArch64ISD::ST2LANEpost: {
7739 VT =
Node->getOperand(1).getValueType();
7740 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7741 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7743 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7744 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7745 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7747 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7749 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7751 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7753 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7758 case AArch64ISD::ST3LANEpost: {
7759 VT =
Node->getOperand(1).getValueType();
7760 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7761 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7763 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7764 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7765 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7767 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7769 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7771 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7773 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7778 case AArch64ISD::ST4LANEpost: {
7779 VT =
Node->getOperand(1).getValueType();
7780 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7781 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7783 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7784 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7785 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7787 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7789 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7791 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7793 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7808 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7820 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7824 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7825 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7847 return MemIntr->getMemoryVT();
7854 DataVT =
Load->getValueType(0);
7856 DataVT =
Load->getValueType(0);
7858 DataVT =
Store->getValue().getValueType();
7860 DataVT =
Store->getValue().getValueType();
7867 const unsigned Opcode = Root->
getOpcode();
7871 case AArch64ISD::LD1_MERGE_ZERO:
7872 case AArch64ISD::LD1S_MERGE_ZERO:
7873 case AArch64ISD::LDNF1_MERGE_ZERO:
7874 case AArch64ISD::LDNF1S_MERGE_ZERO:
7876 case AArch64ISD::ST1_PRED:
7888 case Intrinsic::aarch64_sme_ldr:
7889 case Intrinsic::aarch64_sme_str:
7890 return MVT::nxv16i8;
7891 case Intrinsic::aarch64_sve_prf:
7896 case Intrinsic::aarch64_sve_ld2_sret:
7897 case Intrinsic::aarch64_sve_ld2q_sret:
7900 case Intrinsic::aarch64_sve_st2q:
7903 case Intrinsic::aarch64_sve_ld3_sret:
7904 case Intrinsic::aarch64_sve_ld3q_sret:
7907 case Intrinsic::aarch64_sve_st3q:
7910 case Intrinsic::aarch64_sve_ld4_sret:
7911 case Intrinsic::aarch64_sve_ld4q_sret:
7914 case Intrinsic::aarch64_sve_st4q:
7917 case Intrinsic::aarch64_sve_ld1_pn_x2:
7918 case Intrinsic::aarch64_sve_ldnt1_pn_x2:
7921 case Intrinsic::aarch64_sve_ld1_pn_x4:
7922 case Intrinsic::aarch64_sve_ldnt1_pn_x4:
7925 case Intrinsic::aarch64_sve_st1_pn_x2:
7926 case Intrinsic::aarch64_sve_stnt1_pn_x2:
7929 case Intrinsic::aarch64_sve_st1_pn_x4:
7930 case Intrinsic::aarch64_sve_stnt1_pn_x4:
7933 case Intrinsic::aarch64_sve_ld1udq:
7934 case Intrinsic::aarch64_sve_st1dq:
7935 return EVT(MVT::nxv1i64);
7936 case Intrinsic::aarch64_sve_ld1uwq:
7937 case Intrinsic::aarch64_sve_st1wq:
7938 return EVT(MVT::nxv1i32);
7945template <
int64_t Min,
int64_t Max>
7946bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue
N,
7950 const DataLayout &
DL = CurDAG->getDataLayout();
7951 const MachineFrameInfo &MFI = MF->getFrameInfo();
7959 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7972 SDValue VScale =
N.getOperand(1);
7973 int64_t MulImm = std::numeric_limits<int64_t>::max();
7977 int64_t ByteOffset =
C->getSExtValue();
7978 const auto KnownVScale =
7981 if (!KnownVScale || ByteOffset % KnownVScale != 0)
7984 MulImm = ByteOffset / KnownVScale;
7991 if ((MulImm % MemWidthBytes) != 0)
7994 int64_t
Offset = MulImm / MemWidthBytes;
7998 Base =
N.getOperand(0);
8007 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
8013bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(SDValue
N,
unsigned Scale,
8020 const SDValue
LHS =
N.getOperand(0);
8021 const SDValue
RHS =
N.getOperand(1);
8032 int64_t ImmOff =
C->getSExtValue();
8033 unsigned Size = 1 << Scale;
8042 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
8044 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
8053 const SDValue ShiftRHS =
RHS.getOperand(1);
8055 if (
C->getZExtValue() == Scale) {
8064bool AArch64DAGToDAGISel::SelectAllActivePredicate(SDValue
N) {
8065 const AArch64TargetLowering *TLI =
8066 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
8071bool AArch64DAGToDAGISel::SelectAnyPredicate(SDValue
N) {
8072 return N.getValueType().isScalableVectorOf(MVT::i1);
8075bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue
N,
unsigned MaxSize,
8078 auto MatchConstantOffset = [&](SDValue CN) -> SDValue {
8080 int64_t ImmOff =
C->getSExtValue();
8081 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
8082 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
8087 if (SDValue
C = MatchConstantOffset(
N)) {
8094 if (CurDAG->isBaseWithConstantOffset(
N)) {
8095 if (SDValue
C = MatchConstantOffset(
N.getOperand(1))) {
8096 Base =
N.getOperand(0);
8104 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
8108bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P, SDValue
N,
8146 if (CN->getAPIntValue().uge(LowerBound) &&
8147 CN->getAPIntValue().ult(UpperBound)) {
8149 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
8157template <
bool MatchCBB>
8158bool AArch64DAGToDAGISel::SelectCmpBranchExtOperand(SDValue
N, SDValue &
Reg,
8164 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
8166 Reg =
N.getOperand(0);
8168 SDLoc(
N), MVT::i32);
8176 Reg =
N.getOperand(0);
8196bool AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode *
N) {
8197 EVT VT =
N->getValueType(0);
8203 SDValue TVal =
N->getOperand(0);
8204 SDValue FVal =
N->getOperand(1);
8205 SDValue CCVal =
N->getOperand(2);
8206 SDValue
Cmp =
N->getOperand(3);
8208 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8215 SDValue CmpLHS =
Cmp.getOperand(0);
8216 SDValue CmpRHS =
Cmp.getOperand(1);
8220 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8222 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8223 else if (VT == MVT::f32)
8224 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8225 else if (VT == MVT::f64)
8226 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8234 if (TVal == CmpLHS && FVal == CmpRHS)
8239 if (TVal == CmpLHS && FVal == CmpRHS)
8248 unsigned Opc = getOpc(VT, isMax);
8254 if (!CFP || CFP->getValueAPF().isNaN())
8259 if (CFP->isZero() && !
N->getFlags().hasNoSignedZeros())
8265 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8268 CurDAG->SelectNodeTo(
N,
Opc, VT, CmpLHS, CmpRHS);
8272void AArch64DAGToDAGISel::PreprocessISelDAG() {
8273 bool MadeChange =
false;
8279 switch (
N.getOpcode()) {
8281 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8282 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8283 ScalarTy ==
N.getOperand(0).getValueType())
8288 case AArch64ISD::VSHL: {
8291 EVT VT =
N.getValueType(0);
8292 SDValue
A,
B,
C =
N.getOperand(1);
8298 if (
B.getOpcode() ==
A.getOpcode())
8301 SDValue
SHL = CurDAG->getNode(AArch64ISD::VSHL,
DL, VT,
A,
C);
8311 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8317 CurDAG->ReplaceAllUsesOfValueWith(SDValue(&
N, 0), Result);
8323 CurDAG->RemoveDeadNodes();
static std::optional< APInt > GetNEONSplatValue(SDValue N, const AArch64Subtarget *Subtarget)
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 allUsesAreShiftAmounts(SDValue N)
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG)
static std::tuple< SDValue, SDValue > extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG)
static SDValue addBitcastHints(SelectionDAG &DAG, SDNode &N)
addBitcastHints - This method adds bitcast hints to the operands of a node to help instruction select...
static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, unsigned Depth)
static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
static bool isShiftedMask(uint64_t Mask, EVT VT)
bool SelectSMETile(unsigned &BaseReg, unsigned TileNum)
static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root)
Return the EVT of the data associated to a memory operation in Root.
static bool checkCVTFixedPointOperandWithFBits(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static bool isWorthFoldingADDlow(SDValue N)
If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD i...
static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N)
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
static unsigned SelectOpcodeFromVT(EVT VT, ArrayRef< unsigned > Opcodes)
This function selects an opcode from a list of opcodes, which is expected to be the opcode for { 8-bi...
static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, unsigned NumVec)
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent sca...
static bool checkCVTFixedPointOperandWithFBitsForVectors(SelectionDAG *CurDAG, SDValue N, SDValue &FixedPos, unsigned RegWidth, bool isReciprocal)
static SDValue getZeroRegister(SelectionDAG &DAG, SDLoc DL, EVT VT)
Returns a copy from WZR or XZR.
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 APInt DecodeFMOVImm(uint64_t Imm, unsigned RegWidth)
static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, unsigned Depth)
static std::optional< APInt > DecodeNEONSplat(SDValue N, const AArch64Subtarget *Subtarget)
static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth=0)
static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected)
static EVT getMultipleVectorType(LLVMContext &Ctx, EVT VecVT, unsigned NumVec)
Builds an integer vector type large enough to hold NumVec instances of VecVT.
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!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Contains matchers for matching SelectionDAG nodes and values.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
AArch64DAGToDAGISelPass(AArch64TargetMachine &TM)
const AArch64InstrInfo * getInstrInfo() const override
const AArch64TargetLowering * getTargetLowering() 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(const SelectionDAG &DAG, SDValue N) const
Register matchRegisterName(StringRef RegName) const
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static const fltSemantics & IEEEhalf()
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.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
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
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
unsigned getID() const
getID() - Return the register class ID number.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
bool equalsStr(StringRef Str) const
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.
A description of a memory reference used in the backend.
const MDNode * getMemCacheHint() const
Return the cache hint metadata for the memory reference.
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, in exactly one operand.
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
SelectionDAGISelPass(std::unique_ptr< SelectionDAGISel > Selector)
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
static constexpr unsigned MaxRecursionDepth
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
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.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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...
LLVM Value Representation.
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)
constexpr bool isLegalArithImmed(const uint64_t C)
isLegalArithImmed -
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 uint64_t decodeAdvSIMDModImmType10(uint8_t Imm)
static bool isSVELogicalImm(unsigned SizeInBits, uint64_t ImmVal, uint64_t &Encoding)
constexpr unsigned getArithImmedShift(const uint64_t C)
getArithImmedShift - assumes C is a legal immediate for arithmetic instructions and
static bool isSVECpyDupImm(int SizeInBits, int64_t Val, int32_t &Imm, int32_t &Shift)
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
static bool isSignExtendShiftType(AArch64_AM::ShiftExtendType Type)
isSignExtendShiftType - Returns true if Type is sign extending.
void expandMOVImm(uint64_t Imm, unsigned BitSize, SmallVectorImpl< ImmInsnModel > &Insn)
Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more real move-immediate instructions to...
static constexpr unsigned SVEBitsPerBlock
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ POISON
POISON - A poison node.
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SHL
Shift and rotation operations.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ READ_REGISTER
READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on the DAG, which implements the n...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ VSCALE
VSCALE(IMM) - Returns the runtime scaling factor used to calculate the number of elements within a sc...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
BinaryOpc_match< LHS, RHS, true > m_Mul(const LHS &L, const RHS &R)
Or< Preds... > m_AnyOf(const Preds &...preds)
auto m_SExt(const Opnd &Op)
bool sd_match(SDValue N, Pattern &&P)
UnaryOpc_match< Opnd > m_ZExt(const Opnd &Op)
Value_match m_Value()
Match any valid SDValue.
NUses_match< 1, Value_match > m_OneUse()
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
unsigned CheckFixedPointOperandConstant(APFloat &FVal, unsigned RegWidth, bool isReciprocal)
@ Known
Known to have no common set bits.
@ 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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOptLevel OptLevel)
createAArch64ISelDag - This pass converts a legalized DAG into a AArch64-specific DAG,...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
AArch64MemoryHint toAArch64MemoryHint(Int I)
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isScalableVectorOf(EVT EltVT) const
Return true if this is a scalable vector with matching element type.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
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.
EVT changeTypeToInteger() const
Return the type converted to an equivalently sized integer or vector with integer element type.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
ElementCount getVectorElementCount() const
EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
unsigned getVectorMinNumElements() const
Given a vector type, return the minimum number of elements it contains.
uint64_t getScalarSizeInBits() const
EVT changeVectorElementType(LLVMContext &Context, EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool is64BitVector() const
Return true if this is a 64-bit vector type.