25#include "llvm/IR/IntrinsicsAArch64.h"
35#define DEBUG_TYPE "aarch64-isel"
36#define PASS_NAME "AArch64 Instruction Selection"
39#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
40#pragma inline_depth(0)
56 AArch64DAGToDAGISel() =
delete;
68 void PreprocessISelDAG()
override;
72 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
74 std::vector<SDValue> &OutOps)
override;
76 template <
signed Low,
signed High,
signed Scale>
79 template <
signed Low,
signed High>
87 return SelectShiftedRegister(
N,
false,
Reg, Shift);
90 return SelectShiftedRegister(
N,
true,
Reg, Shift);
93 return SelectAddrModeIndexed7S(
N, 1,
Base, OffImm);
96 return SelectAddrModeIndexed7S(
N, 2,
Base, OffImm);
99 return SelectAddrModeIndexed7S(
N, 4,
Base, OffImm);
102 return SelectAddrModeIndexed7S(
N, 8,
Base, OffImm);
105 return SelectAddrModeIndexed7S(
N, 16,
Base, OffImm);
108 return SelectAddrModeIndexedBitWidth(
N,
true, 9, 16,
Base, OffImm);
111 return SelectAddrModeIndexedBitWidth(
N,
false, 6, 16,
Base, OffImm);
114 return SelectAddrModeIndexed(
N, 1,
Base, OffImm);
117 return SelectAddrModeIndexed(
N, 2,
Base, OffImm);
120 return SelectAddrModeIndexed(
N, 4,
Base, OffImm);
123 return SelectAddrModeIndexed(
N, 8,
Base, OffImm);
126 return SelectAddrModeIndexed(
N, 16,
Base, OffImm);
129 return SelectAddrModeUnscaled(
N, 1,
Base, OffImm);
132 return SelectAddrModeUnscaled(
N, 2,
Base, OffImm);
135 return SelectAddrModeUnscaled(
N, 4,
Base, OffImm);
138 return SelectAddrModeUnscaled(
N, 8,
Base, OffImm);
141 return SelectAddrModeUnscaled(
N, 16,
Base, OffImm);
143 template <
unsigned Size,
unsigned Max>
147 bool Found = SelectAddrModeIndexed(
N,
Size,
Base, OffImm);
150 int64_t
C = CI->getSExtValue();
158 OffImm = CurDAG->getTargetConstant(0,
SDLoc(
N), MVT::i64);
165 return SelectAddrModeWRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
171 return SelectAddrModeXRO(
N, Width / 8,
Base,
Offset, SignExtend, DoShift);
176 N =
N->getOperand(0);
180 EVT VT =
N->getValueType(0);
181 EVT LVT =
N->getOperand(0).getValueType();
182 unsigned Index =
N->getConstantOperandVal(1);
186 Res =
N->getOperand(0);
191 if (
N.getOpcode() != AArch64ISD::VLSHR)
194 EVT VT =
Op.getValueType();
195 unsigned ShtAmt =
N->getConstantOperandVal(1);
200 if (
Op.getOperand(1).getOpcode() == AArch64ISD::MOVIshift)
202 Op.getOperand(1).getConstantOperandVal(0)
203 <<
Op.getOperand(1).getConstantOperandVal(1));
204 else if (
Op.getOperand(1).getOpcode() == AArch64ISD::DUP &&
207 Op.getOperand(1).getConstantOperandVal(0));
211 if (
Imm != 1ULL << (ShtAmt - 1))
214 Res1 =
Op.getOperand(0);
215 Res2 = CurDAG->getTargetConstant(ShtAmt,
SDLoc(
N), MVT::i32);
219 bool SelectDupZeroOrUndef(
SDValue N) {
220 switch(
N->getOpcode()) {
224 case AArch64ISD::DUP:
226 auto Opnd0 =
N->getOperand(0);
240 bool SelectAny(
SDValue) {
return true; }
243 switch(
N->getOpcode()) {
244 case AArch64ISD::DUP:
246 auto Opnd0 =
N->getOperand(0);
258 template <MVT::SimpleValueType VT,
bool Negate>
260 return SelectSVEAddSubImm(
N, VT,
Imm, Shift, Negate);
263 template <MVT::SimpleValueType VT,
bool Negate>
265 return SelectSVEAddSubSSatImm(
N, VT,
Imm, Shift, Negate);
268 template <MVT::SimpleValueType VT>
270 return SelectSVECpyDupImm(
N, VT,
Imm, Shift);
273 template <MVT::SimpleValueType VT,
bool Invert = false>
275 return SelectSVELogicalImm(
N, VT,
Imm, Invert);
278 template <MVT::SimpleValueType VT>
280 return SelectSVEArithImm(
N, VT,
Imm);
283 template <
unsigned Low,
unsigned High,
bool AllowSaturation = false>
285 return SelectSVEShiftImm(
N,
Low,
High, AllowSaturation,
Imm);
292 EVT EltVT =
N->getValueType(0).getVectorElementType();
293 return SelectSVEShiftImm(
N->getOperand(0), 1,
299 template<
signed Min,
signed Max,
signed Scale,
bool Shift>
306 MulImm = 1LL << MulImm;
308 if ((MulImm % std::abs(Scale)) != 0)
312 if ((MulImm >= Min) && (MulImm <= Max)) {
313 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
320 template <
signed Max,
signed Scale>
327 if (MulImm >= 0 && MulImm <= Max) {
329 Imm = CurDAG->getTargetConstant(MulImm,
SDLoc(
N), MVT::i32);
336 template <
unsigned BaseReg,
unsigned Max>
344 Imm = CurDAG->getRegister(BaseReg +
C, MVT::Other);
367 const unsigned SubRegs[]);
369 void SelectTable(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
bool isExt);
371 bool tryIndexedLoad(
SDNode *
N);
373 void SelectPtrauthAuth(
SDNode *
N);
374 void SelectPtrauthResign(
SDNode *
N);
375 void SelectPtrauthResignWithPC(
SDNode *
N);
377 bool trySelectStackSlotTagP(
SDNode *
N);
380 void SelectLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
382 void SelectPostLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Opc,
384 void SelectLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
385 void SelectPostLoadLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
386 void SelectPredicatedLoad(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
387 unsigned Opc_rr,
unsigned Opc_ri,
388 bool IsIntr =
false);
389 void SelectContiguousMultiVectorLoad(
SDNode *
N,
unsigned NumVecs,
390 unsigned Scale,
unsigned Opc_ri,
392 void SelectDestructiveMultiIntrinsic(
SDNode *
N,
unsigned NumVecs,
393 bool IsZmMulti,
unsigned Opcode,
394 bool HasPred =
false);
396 void SelectWhilePair(
SDNode *
N,
unsigned Opc);
397 void SelectCVTIntrinsic(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
398 void SelectCVTIntrinsicFP8(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
399 void SelectClamp(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
400 void SelectUnaryMultiIntrinsic(
SDNode *
N,
unsigned NumOutVecs,
401 bool IsTupleInput,
unsigned Opc);
402 void SelectFrintFromVT(
SDNode *
N,
unsigned NumVecs,
unsigned Opcode);
404 template <
unsigned MaxIdx,
unsigned Scale>
405 void SelectMultiVectorMove(
SDNode *
N,
unsigned NumVecs,
unsigned BaseReg,
407 void SelectMultiVectorMoveZ(
SDNode *
N,
unsigned NumVecs,
408 unsigned Op,
unsigned MaxIdx,
unsigned Scale,
409 unsigned BaseReg = 0);
411 template <
int64_t Min,
int64_t Max>
415 template <
unsigned Scale>
417 return SelectSVERegRegAddrMode(
N, Scale,
Base,
Offset);
420 void SelectMultiVectorLutiLane(
SDNode *
Node,
unsigned NumOutVecs,
422 void SelectMultiVectorLuti6LaneX4(
SDNode *
Node,
unsigned NumIndexVecs);
424 void SelectMultiVectorLuti(
SDNode *
Node,
unsigned NumOutVecs,
unsigned Opc,
427 template <
unsigned MaxIdx,
unsigned Scale>
432 void SelectStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
433 void SelectPostStore(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
434 void SelectStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
435 void SelectPostStoreLane(
SDNode *
N,
unsigned NumVecs,
unsigned Opc);
436 void SelectPredicatedStore(
SDNode *
N,
unsigned NumVecs,
unsigned Scale,
437 unsigned Opc_rr,
unsigned Opc_ri);
438 std::tuple<unsigned, SDValue, SDValue>
439 findAddrModeSVELoadStore(
SDNode *
N,
unsigned Opc_rr,
unsigned Opc_ri,
443 bool tryBitfieldExtractOp(
SDNode *
N);
444 bool tryBitfieldExtractOpFromSExt(
SDNode *
N);
445 bool tryBitfieldInsertOp(
SDNode *
N);
446 bool tryBitfieldInsertInZeroOp(
SDNode *
N);
447 bool tryShiftAmountMod(
SDNode *
N);
449 bool tryReadRegister(
SDNode *
N);
450 bool tryWriteRegister(
SDNode *
N);
452 bool trySelectCastFixedLengthToScalableVector(
SDNode *
N);
453 bool trySelectCastScalableToFixedLengthVector(
SDNode *
N);
457 bool tryFoldCselToFMaxMin(
SDNode *
N);
460#include "AArch64GenDAGISel.inc"
468 return SelectAddrModeIndexedBitWidth(
N,
true, 7,
Size,
Base, OffImm);
470 bool SelectAddrModeIndexedBitWidth(
SDValue N,
bool IsSignedImm,
unsigned BW,
483 bool isWorthNegatingImm(
SDValue V)
const;
484 bool isWorthFoldingALU(
SDValue V,
bool LSL =
false)
const;
485 bool isWorthFoldingAddr(
SDValue V,
unsigned Size)
const;
486 bool SelectExtendedSHL(
SDValue N,
unsigned Size,
bool WantExtend,
489 template<
unsigned RegW
idth>
491 return SelectCVTFixedPosOperand(
N, FixedPos, RegWidth);
493 bool SelectCVTFixedPosOperand(
SDValue N,
SDValue &FixedPos,
unsigned Width);
495 template <
unsigned RegW
idth>
497 return SelectCVTFixedPointVec(
N, FixedPos, RegWidth);
499 bool SelectCVTFixedPointVec(
SDValue N,
SDValue &FixedPos,
unsigned Width);
501 template<
unsigned RegW
idth>
503 return SelectCVTFixedPosRecipOperand(
N, FixedPos, RegWidth);
509 template <
unsigned FloatW
idth>
511 return SelectCVTFixedPosRecipOperandVec(
N, FixedPos, FloatWidth);
517 bool SelectCMP_SWAP(
SDNode *
N);
546 bool SelectAllActivePredicate(
SDValue N);
551 template <
bool MatchCBB>
561 ID, std::make_unique<AArch64DAGToDAGISel>(tm, OptLevel)) {}
565char AArch64DAGToDAGISelLegacy::ID = 0;
571 std::make_unique<AArch64DAGToDAGISel>(TM, TM.getOptLevel())) {}
577 auto getFloatVT = [&](
EVT VT) {
579 assert((ScalarVT == MVT::i32 || ScalarVT == MVT::i64) &&
"Unexpected VT");
580 return VT.changeElementType(*(DAG.
getContext()),
581 ScalarVT == MVT::i32 ? MVT::f32 : MVT::f64);
586 for (
unsigned I = 0,
E =
N.getNumOperands();
I <
E; ++
I) {
587 auto bitcasted = DAG.
getBitcast(getFloatVT(
N.getOperand(
I).getValueType()),
591 EVT OrigVT =
N.getValueType(0);
600 Imm =
C->getZExtValue();
617 return N->getOpcode() ==
Opc &&
628 return Imm == ImmExpected;
633 assert(RegWidth == 32 || RegWidth == 64);
635 return APInt(RegWidth,
643 assert(
N.getValueType().isInteger() &&
"Only integers are supported");
644 if (
N->getOpcode() == AArch64ISD::NVCAST ||
646 N =
N->getOperand(0);
647 unsigned SplatWidth =
N.getScalarValueSizeInBits();
648 if (
N.getOpcode() == AArch64ISD::FMOV)
650 if (
N->getOpcode() == AArch64ISD::MOVI)
651 return APInt(SplatWidth,
N.getConstantOperandVal(0));
652 if (
N->getOpcode() == AArch64ISD::MOVIshift)
653 return APInt(SplatWidth,
N.getConstantOperandVal(0)
654 <<
N.getConstantOperandVal(1));
655 if (
N->getOpcode() == AArch64ISD::MVNIshift)
656 return ~APInt(SplatWidth,
N.getConstantOperandVal(0)
657 <<
N.getConstantOperandVal(1));
658 if (
N->getOpcode() == AArch64ISD::MOVIedit)
660 N.getConstantOperandVal(0)));
661 if (
N->getOpcode() == AArch64ISD::DUP)
663 return Const->getAPIntValue().trunc(SplatWidth);
666 return SplatVal.
trunc(SplatWidth);
674static std::optional<APInt>
676 unsigned SplatWidth =
N.getScalarValueSizeInBits();
678 if (SplatVal->getBitWidth() <= SplatWidth)
680 if (SplatVal->isSplat(SplatWidth))
681 return SplatVal->trunc(SplatWidth);
686bool AArch64DAGToDAGISel::SelectNEONSplatOfSVELogicalImm(
SDValue N,
693 ImmVal->getZExtValue(), Encoding))
696 Imm = CurDAG->getTargetConstant(Encoding, SDLoc(
N), MVT::i64);
700bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEAddSubImm(SDValue
N, SDValue &
Imm,
703 return SelectSVEAddSubImm(SDLoc(
N), *ImmVal,
704 N.getValueType().getScalarType().getSimpleVT(),
710bool AArch64DAGToDAGISel::SelectNEONSplatOfSVEArithSImm(SDValue
N,
713 return SelectSVESignedArithImm(SDLoc(
N), *ImmVal,
Imm);
717bool AArch64DAGToDAGISel::SelectNEONSplatOfSImm8(SDValue
N, SDValue &
Imm) {
722 int64_t ImmVal = ImmAPIntVal->getSExtValue();
723 if (ImmVal < -128 || ImmVal > 127)
726 Imm = CurDAG->getSignedTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
730bool AArch64DAGToDAGISel::SelectNEONSplatOfUImm8(SDValue
N, SDValue &
Imm) {
735 uint64_t ImmVal = ImmAPIntVal->getZExtValue();
739 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
743bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
745 std::vector<SDValue> &OutOps) {
746 switch(ConstraintID) {
749 case InlineAsm::ConstraintCode::m:
750 case InlineAsm::ConstraintCode::o:
751 case InlineAsm::ConstraintCode::Q:
758 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i64);
760 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
761 dl,
Op.getValueType(),
763 OutOps.push_back(NewOp);
772bool AArch64DAGToDAGISel::SelectArithImmed(SDValue
N, SDValue &Val,
782 uint64_t Immed =
N.getNode()->getAsZExtVal();
792 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32);
793 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32);
799bool AArch64DAGToDAGISel::SelectNegArithImmed(SDValue
N, SDValue &Val,
810 uint64_t Immed =
N.getNode()->getAsZExtVal();
818 if (
N.getValueType() == MVT::i32)
819 Immed = ~((uint32_t)Immed) + 1;
821 Immed = ~Immed + 1ULL;
822 if (Immed & 0xFFFFFFFFFF000000ULL)
825 Immed &= 0xFFFFFFULL;
826 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(
N), MVT::i32), Val,
833 switch (
N.getOpcode()) {
859 unsigned ShiftVal = CSD->getZExtValue();
877bool AArch64DAGToDAGISel::isWorthFoldingAddr(SDValue V,
unsigned Size)
const {
880 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
885 if (Subtarget->hasAddrLSLSlow14() && (
Size == 2 ||
Size == 16))
893 const SDValue
LHS =
V.getOperand(0);
894 const SDValue
RHS =
V.getOperand(1);
907bool AArch64DAGToDAGISel::SelectShiftedRegisterFromAnd(SDValue
N, SDValue &
Reg,
909 EVT VT =
N.getValueType();
910 if (VT != MVT::i32 && VT != MVT::i64)
913 if (
N->getOpcode() !=
ISD::AND || !
N->hasOneUse())
915 SDValue
LHS =
N.getOperand(0);
919 unsigned LHSOpcode =
LHS->getOpcode();
933 unsigned LowZBits, MaskLen;
937 unsigned BitWidth =
N.getValueSizeInBits();
944 if (LowZBits <= ShiftAmtC || (
BitWidth != LowZBits + MaskLen))
947 NewShiftC = LowZBits - ShiftAmtC;
948 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
954 NewShiftC = LowZBits + ShiftAmtC;
967 NewShiftOp = VT == MVT::i64 ? AArch64::UBFMXri : AArch64::UBFMWri;
969 NewShiftOp = VT == MVT::i64 ? AArch64::SBFMXri : AArch64::SBFMWri;
973 SDValue NewShiftAmt = CurDAG->getTargetConstant(NewShiftC,
DL, VT);
974 SDValue BitWidthMinus1 = CurDAG->getTargetConstant(
BitWidth - 1,
DL, VT);
975 Reg = SDValue(CurDAG->getMachineNode(NewShiftOp,
DL, VT,
LHS->getOperand(0),
976 NewShiftAmt, BitWidthMinus1),
979 Shift = CurDAG->getTargetConstant(ShVal,
DL, MVT::i32);
993 SrcVT =
N.getOperand(0).getValueType();
995 if (!IsLoadStore && SrcVT == MVT::i8)
997 else if (!IsLoadStore && SrcVT == MVT::i16)
999 else if (SrcVT == MVT::i32)
1001 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
1006 EVT SrcVT =
N.getOperand(0).getValueType();
1007 if (!IsLoadStore && SrcVT == MVT::i8)
1009 else if (!IsLoadStore && SrcVT == MVT::i16)
1011 else if (SrcVT == MVT::i32)
1013 assert(SrcVT != MVT::i64 &&
"extend from 64-bits?");
1038bool AArch64DAGToDAGISel::isWorthNegatingImm(SDValue V)
const {
1041 EVT VT =
V.getValueType();
1042 assert((VT == MVT::i32 || VT == MVT::i64) &&
"invalid type");
1053 return NewCost.
size() < OrigCost.
size();
1060bool AArch64DAGToDAGISel::isWorthFoldingALU(SDValue V,
bool LSL)
const {
1063 if (CurDAG->shouldOptForSize() ||
V.hasOneUse())
1068 if (LSL && Subtarget->hasALULSLFast() &&
V.getOpcode() ==
ISD::SHL &&
1069 V.getConstantOperandVal(1) <= 4 &&
1082bool AArch64DAGToDAGISel::SelectShiftedRegister(SDValue
N,
bool AllowROR,
1083 SDValue &
Reg, SDValue &Shift) {
1084 if (SelectShiftedRegisterFromAnd(
N,
Reg, Shift))
1094 unsigned BitSize =
N.getValueSizeInBits();
1095 unsigned Val =
RHS->getZExtValue() & (BitSize - 1);
1098 Reg =
N.getOperand(0);
1099 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(
N), MVT::i32);
1100 return isWorthFoldingALU(
N,
true);
1111 if (
N.getValueType() == MVT::i32)
1119template<
signed Low,
signed High,
signed Scale>
1120bool AArch64DAGToDAGISel::SelectRDVLImm(SDValue
N, SDValue &
Imm) {
1125 if ((MulImm % std::abs(Scale)) == 0) {
1126 int64_t RDVLImm = MulImm / Scale;
1127 if ((RDVLImm >=
Low) && (RDVLImm <=
High)) {
1128 Imm = CurDAG->getSignedTargetConstant(RDVLImm, SDLoc(
N), MVT::i32);
1137template <
signed Low,
signed High>
1138bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(SDValue
N, SDValue &
Imm) {
1143 if (MulImm >=
Low && MulImm <=
High) {
1144 Imm = CurDAG->getSignedTargetConstant(MulImm, SDLoc(
N), MVT::i32);
1153bool AArch64DAGToDAGISel::SelectArithExtendedRegister(SDValue
N, SDValue &
Reg,
1155 unsigned ShiftVal = 0;
1170 Reg =
N.getOperand(0).getOperand(0);
1180 SDValue
Op =
N.getOperand(0);
1182 Op =
Op->getOperand(0);
1184 Op.getOperand(0).getValueType().isFixedLengthVector())
1188 Reg =
N.getOperand(0);
1192 auto isDef32 = [](SDValue
N) {
1193 unsigned Opc =
N.getOpcode();
1211 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1213 return isWorthFoldingALU(
N);
1218bool AArch64DAGToDAGISel::SelectArithUXTXRegister(SDValue
N, SDValue &
Reg,
1220 unsigned ShiftVal = 0;
1234 Reg =
N.getOperand(0);
1235 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(
N),
1237 return isWorthFoldingALU(
N);
1246 for (
auto *
User :
N->users()) {
1273bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(SDValue
N,
bool IsSignedImm,
1274 unsigned BW,
unsigned Size,
1278 const DataLayout &
DL = CurDAG->getDataLayout();
1279 const TargetLowering *TLI = getTargetLowering();
1283 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1289 if (CurDAG->isBaseWithConstantOffset(
N)) {
1292 int64_t RHSC =
RHS->getSExtValue();
1294 int64_t
Range = 0x1LL << (BW - 1);
1296 if ((RHSC & (
Size - 1)) == 0 && RHSC >= -(
Range << Scale) &&
1297 RHSC < (
Range << Scale)) {
1298 Base =
N.getOperand(0);
1303 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1312 if ((RHSC & (
Size - 1)) == 0 && RHSC < (
Range << Scale)) {
1313 Base =
N.getOperand(0);
1318 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1329 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1336bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue
N,
unsigned Size,
1337 SDValue &
Base, SDValue &OffImm) {
1339 const DataLayout &
DL = CurDAG->getDataLayout();
1340 const TargetLowering *TLI = getTargetLowering();
1344 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1349 GlobalAddressSDNode *GAN =
1351 Base =
N.getOperand(0);
1361 if (CurDAG->isBaseWithConstantOffset(
N)) {
1363 int64_t RHSC = (int64_t)
RHS->getZExtValue();
1366 Base =
N.getOperand(0);
1371 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64);
1379 if (SelectAddrModeUnscaled(
N,
Size,
Base, OffImm))
1387 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
1396bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(SDValue
N,
unsigned Size,
1399 if (!CurDAG->isBaseWithConstantOffset(
N))
1402 int64_t RHSC =
RHS->getSExtValue();
1403 if (RHSC >= -256 && RHSC < 256) {
1404 Base =
N.getOperand(0);
1407 const TargetLowering *TLI = getTargetLowering();
1408 Base = CurDAG->getTargetFrameIndex(
1411 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(
N), MVT::i64);
1421 CurDAG->
getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0);
1428bool AArch64DAGToDAGISel::SelectExtendedSHL(SDValue
N,
unsigned Size,
1429 bool WantExtend, SDValue &
Offset,
1430 SDValue &SignExtend) {
1448 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32);
1454 if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
1457 return isWorthFoldingAddr(
N,
Size);
1460bool AArch64DAGToDAGISel::SelectAddrModeWRO(SDValue
N,
unsigned Size,
1462 SDValue &SignExtend,
1466 SDValue
LHS =
N.getOperand(0);
1467 SDValue
RHS =
N.getOperand(1);
1478 const SDNode *
Node =
N.getNode();
1479 for (SDNode *UI :
Node->users()) {
1485 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1488 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1491 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1496 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1499 DoShift = CurDAG->getTargetConstant(
true, dl, MVT::i32);
1504 DoShift = CurDAG->getTargetConstant(
false, dl, MVT::i32);
1508 if (IsExtendedRegisterWorthFolding &&
1515 if (isWorthFoldingAddr(
LHS,
Size))
1520 if (IsExtendedRegisterWorthFolding &&
1527 if (isWorthFoldingAddr(
RHS,
Size))
1539 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL)
1542 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL)
1544 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL &&
1545 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL;
1549bool AArch64DAGToDAGISel::SelectAddrModeXRO(SDValue
N,
unsigned Size,
1551 SDValue &SignExtend,
1555 SDValue
LHS =
N.getOperand(0);
1556 SDValue
RHS =
N.getOperand(1);
1562 const SDNode *
Node =
N.getNode();
1563 for (SDNode *UI :
Node->users()) {
1580 int64_t ImmOff = (int64_t)
RHS->getAsZExtVal();
1590 CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
1591 SDValue MOVIV = SDValue(MOVI, 0);
1597 bool IsExtendedRegisterWorthFolding = isWorthFoldingAddr(
N,
Size);
1600 if (IsExtendedRegisterWorthFolding &&
RHS.getOpcode() ==
ISD::SHL &&
1603 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1608 if (IsExtendedRegisterWorthFolding &&
LHS.getOpcode() ==
ISD::SHL &&
1611 DoShift = CurDAG->getTargetConstant(
true,
DL, MVT::i32);
1618 SignExtend = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1619 DoShift = CurDAG->getTargetConstant(
false,
DL, MVT::i32);
1625 static const unsigned RegClassIDs[] = {
1626 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID};
1627 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1,
1628 AArch64::dsub2, AArch64::dsub3};
1634 static const unsigned RegClassIDs[] = {
1635 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID};
1636 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1,
1637 AArch64::qsub2, AArch64::qsub3};
1643 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID,
1644 AArch64::ZPR3RegClassID,
1645 AArch64::ZPR4RegClassID};
1646 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1647 AArch64::zsub2, AArch64::zsub3};
1657 static const unsigned RegClassIDs[] = {AArch64::ZPR2Mul2RegClassID, 0,
1658 AArch64::ZPR4Mul4RegClassID};
1659 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1,
1660 AArch64::zsub2, AArch64::zsub3};
1665 const unsigned RegClassIDs[],
1666 const unsigned SubRegs[]) {
1669 if (Regs.
size() == 1)
1680 CurDAG->getTargetConstant(RegClassIDs[Regs.
size() - 2],
DL, MVT::i32));
1683 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1684 Ops.push_back(Regs[i]);
1685 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i],
DL, MVT::i32));
1689 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped,
Ops);
1690 return SDValue(
N, 0);
1693void AArch64DAGToDAGISel::SelectTable(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
1696 EVT VT =
N->getValueType(0);
1698 unsigned ExtOff = isExt;
1701 unsigned Vec0Off = ExtOff + 1;
1707 Ops.push_back(
N->getOperand(1));
1708 Ops.push_back(RegSeq);
1709 Ops.push_back(
N->getOperand(NumVecs + ExtOff + 1));
1710 ReplaceNode(
N, CurDAG->getMachineNode(
Opc, dl, VT,
Ops));
1713static std::tuple<SDValue, SDValue>
1734 if (!ConstDiscN || !
isUInt<16>(ConstDiscN->getZExtValue()))
1739 AddrDisc = DAG->
getRegister(AArch64::XZR, MVT::i64);
1741 return std::make_tuple(
1746void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *
N) {
1749 SDValue Val =
N->getOperand(1);
1750 SDValue AUTKey =
N->getOperand(2);
1751 SDValue AUTDisc =
N->getOperand(3);
1754 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1756 SDValue AUTAddrDisc, AUTConstDisc;
1757 std::tie(AUTConstDisc, AUTAddrDisc) =
1761 std::vector<SDValue>
Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc};
1763 if (
N->getNumOperands() > 4)
1764 Ops.push_back(
N->getOperand(4));
1767 CurDAG->getMachineNode(AArch64::AUTxMxN,
DL, MVT::i64, MVT::i64,
Ops);
1768 ReplaceNode(
N, AUT);
1770 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1771 AArch64::X16, Val, SDValue());
1772 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.
getValue(1)};
1774 SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTx16x17,
DL, MVT::i64,
Ops);
1775 ReplaceNode(
N, AUT);
1779void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *
N) {
1789 bool HasLoad = IntNum == Intrinsic::ptrauth_resign_load_relative;
1794 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1795 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1797 SDValue AUTAddrDisc, AUTConstDisc;
1798 std::tie(AUTConstDisc, AUTAddrDisc) =
1801 SDValue PACAddrDisc, PACConstDisc;
1802 std::tie(PACConstDisc, PACAddrDisc) =
1805 SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1806 AArch64::X16, Val, SDValue());
1809 SDValue Addend =
N->getOperand(OffsetBase + 6);
1810 SDValue IncomingChain =
N->getOperand(0);
1811 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc,
1812 PACKey, PACConstDisc, PACAddrDisc,
1813 Addend, IncomingChain, X16Copy.
getValue(1)};
1815 SDNode *AUTRELLOADPAC = CurDAG->getMachineNode(AArch64::AUTRELLOADPAC,
DL,
1816 MVT::i64, MVT::Other,
Ops);
1817 ReplaceNode(
N, AUTRELLOADPAC);
1819 SDValue
Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey,
1820 PACConstDisc, PACAddrDisc, X16Copy.
getValue(1)};
1822 SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC,
DL, MVT::i64,
Ops);
1823 ReplaceNode(
N, AUTPAC);
1827void AArch64DAGToDAGISel::SelectPtrauthResignWithPC(SDNode *
N) {
1839 AUTKey = CurDAG->getTargetConstant(AUTKeyC,
DL, MVT::i64);
1840 PACKey = CurDAG->getTargetConstant(PACKeyC,
DL, MVT::i64);
1842 SDValue PACAddrDisc, PACConstDisc;
1843 std::tie(PACConstDisc, PACAddrDisc) =
1846 SDValue X17Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(),
DL,
1847 AArch64::X17, Val, SDValue());
1848 SDValue X16Copy = CurDAG->getCopyToReg(
1849 CurDAG->getEntryNode(),
DL, AArch64::X16, AUTDisc, X17Copy.
getValue(1));
1850 SDValue X15Copy = CurDAG->getCopyToReg(
1851 CurDAG->getEntryNode(),
DL, AArch64::X15, AUTPC, X16Copy.
getValue(1));
1853 SDValue
Ops[] = {AUTKey, PACKey, PACConstDisc, PACAddrDisc,
1856 CurDAG->getMachineNode(AArch64::AUTPCPAC,
DL, MVT::i64,
Ops);
1857 ReplaceNode(
N, AUTPCPAC);
1860bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *
N) {
1862 if (
LD->isUnindexed())
1864 EVT VT =
LD->getMemoryVT();
1865 EVT DstVT =
N->getValueType(0);
1869 int OffsetVal = (int)
OffsetOp->getZExtValue();
1874 unsigned Opcode = 0;
1877 bool InsertTo64 =
false;
1880 (!Subtarget->
isLittleEndian() || (Subtarget->requiresStrictAlign() &&
1883 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost;
1884 else if (VT == MVT::i32) {
1886 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1888 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
1890 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
1896 }
else if (VT == MVT::i16) {
1898 if (DstVT == MVT::i64)
1899 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
1901 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
1903 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
1904 InsertTo64 = DstVT == MVT::i64;
1909 }
else if (VT == MVT::i8) {
1911 if (DstVT == MVT::i64)
1912 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
1914 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
1916 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
1917 InsertTo64 = DstVT == MVT::i64;
1922 }
else if (VT == MVT::f16) {
1923 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1924 }
else if (VT == MVT::bf16) {
1925 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost;
1926 }
else if (VT == MVT::f32) {
1927 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost;
1928 }
else if (VT == MVT::f64 || (VT.
is64BitVector() && !UseLd1)) {
1929 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost;
1931 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost;
1933 if (IsPre || OffsetVal != 8)
1937 Opcode = AArch64::LD1Onev8b_POST;
1940 Opcode = AArch64::LD1Onev4h_POST;
1943 Opcode = AArch64::LD1Onev2s_POST;
1946 Opcode = AArch64::LD1Onev1d_POST;
1952 if (IsPre || OffsetVal != 16)
1956 Opcode = AArch64::LD1Onev16b_POST;
1959 Opcode = AArch64::LD1Onev8h_POST;
1962 Opcode = AArch64::LD1Onev4s_POST;
1965 Opcode = AArch64::LD1Onev2d_POST;
1972 SDValue Chain =
LD->getChain();
1973 SDValue
Base =
LD->getBasePtr();
1976 SDValue
Offset = UseLd1 ? CurDAG->getRegister(AArch64::XZR, MVT::i64)
1977 : CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64);
1979 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT,
1987 SDValue LoadedVal = SDValue(Res, 1);
1989 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32);
1990 LoadedVal = SDValue(CurDAG->getMachineNode(AArch64::SUBREG_TO_REG, dl,
1991 MVT::i64, LoadedVal, SubReg),
1995 ReplaceUses(SDValue(
N, 0), LoadedVal);
1996 ReplaceUses(SDValue(
N, 1), SDValue(Res, 0));
1997 ReplaceUses(SDValue(
N, 2), SDValue(Res, 2));
1998 CurDAG->RemoveDeadNode(
N);
2002void AArch64DAGToDAGISel::SelectLoad(SDNode *
N,
unsigned NumVecs,
unsigned Opc,
2003 unsigned SubRegIdx) {
2005 EVT VT =
N->getValueType(0);
2008 SDValue
Ops[] = {
N->getOperand(2),
2011 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2013 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2014 SDValue SuperReg = SDValue(Ld, 0);
2015 for (
unsigned i = 0; i < NumVecs; ++i)
2016 ReplaceUses(SDValue(
N, i),
2017 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
2019 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 1));
2024 MachineMemOperand *MemOp = MemIntr->getMemOperand();
2028 CurDAG->RemoveDeadNode(
N);
2031void AArch64DAGToDAGISel::SelectPostLoad(SDNode *
N,
unsigned NumVecs,
2032 unsigned Opc,
unsigned SubRegIdx) {
2034 EVT VT =
N->getValueType(0);
2037 SDValue
Ops[] = {
N->getOperand(1),
2041 const EVT ResTys[] = {MVT::i64,
2042 MVT::Untyped, MVT::Other};
2044 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2047 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 0));
2050 SDValue SuperReg = SDValue(Ld, 1);
2052 ReplaceUses(SDValue(
N, 0), SuperReg);
2054 for (
unsigned i = 0; i < NumVecs; ++i)
2055 ReplaceUses(SDValue(
N, i),
2056 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
2063 ReplaceUses(SDValue(
N, NumVecs + 1), SDValue(Ld, 2));
2064 CurDAG->RemoveDeadNode(
N);
2070std::tuple<unsigned, SDValue, SDValue>
2071AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *
N,
unsigned Opc_rr,
2073 const SDValue &OldBase,
2074 const SDValue &OldOffset,
2076 SDValue NewBase = OldBase;
2077 SDValue NewOffset = OldOffset;
2079 const bool IsRegImm = SelectAddrModeIndexedSVE<-8, 7>(
2080 N, OldBase, NewBase, NewOffset);
2084 const bool IsRegReg =
2085 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset);
2088 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset);
2101template <SelectTypeKind Kind>
2113 if (EltVT != MVT::i8 && EltVT != MVT::i16 && EltVT != MVT::i32 &&
2118 if (EltVT != MVT::i1)
2122 if (EltVT == MVT::bf16)
2124 else if (EltVT != MVT::bf16 && EltVT != MVT::f16 && EltVT != MVT::f32 &&
2154void AArch64DAGToDAGISel::SelectPExtPair(SDNode *
N,
unsigned Opc) {
2157 if (
Imm->getZExtValue() > 1)
2161 EVT VT =
N->getValueType(0);
2162 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2)};
2163 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2164 SDValue SuperReg = SDValue(WhilePair, 0);
2166 for (
unsigned I = 0;
I < 2; ++
I)
2167 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2168 AArch64::psub0 +
I,
DL, VT, SuperReg));
2170 CurDAG->RemoveDeadNode(
N);
2173void AArch64DAGToDAGISel::SelectWhilePair(SDNode *
N,
unsigned Opc) {
2175 EVT VT =
N->getValueType(0);
2177 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2)};
2179 SDNode *WhilePair = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2180 SDValue SuperReg = SDValue(WhilePair, 0);
2182 for (
unsigned I = 0;
I < 2; ++
I)
2183 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2184 AArch64::psub0 +
I,
DL, VT, SuperReg));
2186 CurDAG->RemoveDeadNode(
N);
2189void AArch64DAGToDAGISel::SelectCVTIntrinsic(SDNode *
N,
unsigned NumVecs,
2191 EVT VT =
N->getValueType(0);
2193 SDValue
Ops = createZTuple(Regs);
2195 SDNode *
Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2196 SDValue SuperReg = SDValue(Intrinsic, 0);
2197 for (
unsigned i = 0; i < NumVecs; ++i)
2198 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2199 AArch64::zsub0 + i,
DL, VT, SuperReg));
2201 CurDAG->RemoveDeadNode(
N);
2204void AArch64DAGToDAGISel::SelectCVTIntrinsicFP8(SDNode *
N,
unsigned NumVecs,
2207 EVT VT =
N->getValueType(0);
2209 Ops.push_back(
N->getOperand(0));
2212 CurDAG->getMachineNode(Opcode,
DL, {MVT::Untyped, MVT::Other},
Ops);
2213 SDValue SuperReg = SDValue(Instruction, 0);
2215 for (
unsigned i = 0; i < NumVecs; ++i)
2216 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2217 AArch64::zsub0 + i,
DL, VT, SuperReg));
2220 unsigned ChainIdx = NumVecs;
2221 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Instruction, 1));
2222 CurDAG->RemoveDeadNode(
N);
2225void AArch64DAGToDAGISel::SelectDestructiveMultiIntrinsic(SDNode *
N,
2230 assert(Opcode != 0 &&
"Unexpected opcode");
2233 EVT VT =
N->getValueType(0);
2234 SDUse *OpsIter =
N->op_begin() + 1;
2237 auto GetMultiVecOperand = [&]() {
2240 return createZMulTuple(Regs);
2244 Ops.push_back(*OpsIter++);
2246 Ops.push_back(GetMultiVecOperand());
2248 Ops.push_back(GetMultiVecOperand());
2250 Ops.push_back(*OpsIter++);
2253 Ops.append(OpsIter,
N->op_end());
2255 Intrinsic = CurDAG->getMachineNode(Opcode,
DL, MVT::Untyped,
Ops);
2256 SDValue SuperReg = SDValue(Intrinsic, 0);
2257 for (
unsigned i = 0; i < NumVecs; ++i)
2258 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2259 AArch64::zsub0 + i,
DL, VT, SuperReg));
2261 CurDAG->RemoveDeadNode(
N);
2264void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *
N,
unsigned NumVecs,
2265 unsigned Scale,
unsigned Opc_ri,
2266 unsigned Opc_rr,
bool IsIntr) {
2267 assert(Scale < 5 &&
"Invalid scaling value.");
2269 EVT VT =
N->getValueType(0);
2276 N, Opc_rr, Opc_ri,
N->getOperand(IsIntr ? 3 : 2),
2277 CurDAG->getTargetConstant(0,
DL, MVT::i64), Scale);
2279 SDValue
Ops[] = {
N->getOperand(IsIntr ? 2 : 1),
2283 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2285 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2286 SDValue SuperReg = SDValue(
Load, 0);
2287 for (
unsigned i = 0; i < NumVecs; ++i)
2288 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2289 AArch64::zsub0 + i,
DL, VT, SuperReg));
2292 unsigned ChainIdx = NumVecs;
2293 ReplaceUses(SDValue(
N, ChainIdx), SDValue(
Load, 1));
2294 CurDAG->RemoveDeadNode(
N);
2297void AArch64DAGToDAGISel::SelectContiguousMultiVectorLoad(SDNode *
N,
2302 assert(Scale < 4 &&
"Invalid scaling value.");
2304 EVT VT =
N->getValueType(0);
2309 SDValue
Offset = CurDAG->getTargetConstant(0,
DL, MVT::i64);
2312 findAddrModeSVELoadStore(
N, Opc_rr, Opc_ri,
Base,
Offset, Scale);
2314 SDValue
Ops[] = {PNg,
2318 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2320 SDNode *
Load = CurDAG->getMachineNode(
Opc,
DL, ResTys,
Ops);
2321 SDValue SuperReg = SDValue(
Load, 0);
2322 for (
unsigned i = 0; i < NumVecs; ++i)
2323 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2324 AArch64::zsub0 + i,
DL, VT, SuperReg));
2327 unsigned ChainIdx = NumVecs;
2328 ReplaceUses(SDValue(
N, ChainIdx), SDValue(
Load, 1));
2329 CurDAG->RemoveDeadNode(
N);
2332void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *
N,
unsigned NumVecs,
2334 if (
N->getValueType(0) != MVT::nxv4f32)
2336 SelectUnaryMultiIntrinsic(
N, NumVecs,
true, Opcode);
2339void AArch64DAGToDAGISel::SelectMultiVectorLutiLane(SDNode *Node,
2340 unsigned NumOutVecs,
2344 if (
Imm->getZExtValue() > MaxImm)
2348 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2351 SDValue Chain =
Node->getOperand(0);
2352 SDValue
Ops[] = {ZtValue,
Node->getOperand(3),
Node->getOperand(4), Chain};
2354 EVT VT =
Node->getValueType(0);
2357 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2358 SDValue SuperReg = SDValue(Instruction, 0);
2360 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2361 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2362 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2365 unsigned ChainIdx = NumOutVecs;
2366 ReplaceUses(SDValue(Node, ChainIdx), SDValue(Instruction, 1));
2367 CurDAG->RemoveDeadNode(Node);
2370void AArch64DAGToDAGISel::SelectMultiVectorLuti6LaneX4(SDNode *Node,
2371 unsigned NumIndexVecs) {
2372 assert((NumIndexVecs == 2 || NumIndexVecs == 3) &&
2373 "unexpected number of index vectors");
2375 constexpr unsigned FirstIndexOp = 3;
2376 unsigned ImmOp = FirstIndexOp + NumIndexVecs;
2378 if (!
Imm ||
Imm->getZExtValue() > 1)
2384 unsigned Lane =
Imm->getZExtValue();
2385 unsigned IndexOp = FirstIndexOp;
2386 if (NumIndexVecs == 3)
2389 SDValue TableTuple = createZTuple({
Node->getOperand(1),
Node->getOperand(2)});
2390 SDValue IndexTuple =
2391 createZTuple({
Node->getOperand(IndexOp),
Node->getOperand(IndexOp + 1)});
2392 SDValue
Ops[] = {TableTuple, IndexTuple,
Node->getOperand(ImmOp)};
2395 EVT VT =
Node->getValueType(0);
2397 CurDAG->getMachineNode(AArch64::LUTI6_4Z2Z2ZI,
DL, MVT::Untyped,
Ops);
2398 SDValue SuperReg = SDValue(Instruction, 0);
2400 for (
unsigned I = 0;
I < 4; ++
I)
2401 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2402 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2404 CurDAG->RemoveDeadNode(Node);
2407void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
2408 unsigned NumOutVecs,
2410 unsigned NumInVecs) {
2411 assert((NumInVecs == 2 || NumInVecs == 3) &&
2412 "unexpected number of input vectors");
2415 if (!ImmToReg<AArch64::ZT0, 0>(
Node->getOperand(2), ZtValue))
2419 SDValue ZTuple = NumInVecs == 3 ? createZTuple(Regs) : createZMulTuple(Regs);
2420 SDValue
Ops[] = {ZtValue, ZTuple,
Node->getOperand(0)};
2423 EVT VT =
Node->getValueType(0);
2426 CurDAG->getMachineNode(
Opc,
DL, {MVT::Untyped, MVT::Other},
Ops);
2427 SDValue SuperReg = SDValue(Instruction, 0);
2429 for (
unsigned I = 0;
I < NumOutVecs; ++
I)
2430 ReplaceUses(SDValue(Node,
I), CurDAG->getTargetExtractSubreg(
2431 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2433 ReplaceUses(SDValue(Node, NumOutVecs), SDValue(Instruction, 1));
2434 CurDAG->RemoveDeadNode(Node);
2437void AArch64DAGToDAGISel::SelectClamp(SDNode *
N,
unsigned NumVecs,
2440 EVT VT =
N->getValueType(0);
2443 SDValue Zd = createZMulTuple(Regs);
2444 SDValue Zn =
N->getOperand(1 + NumVecs);
2445 SDValue Zm =
N->getOperand(2 + NumVecs);
2447 SDValue
Ops[] = {Zd, Zn, Zm};
2450 SDValue SuperReg = SDValue(Intrinsic, 0);
2451 for (
unsigned i = 0; i < NumVecs; ++i)
2452 ReplaceUses(SDValue(
N, i), CurDAG->getTargetExtractSubreg(
2453 AArch64::zsub0 + i,
DL, VT, SuperReg));
2455 CurDAG->RemoveDeadNode(
N);
2485template <
unsigned MaxIdx,
unsigned Scale>
2486void AArch64DAGToDAGISel::SelectMultiVectorMove(SDNode *
N,
unsigned NumVecs,
2487 unsigned BaseReg,
unsigned Op) {
2488 unsigned TileNum = 0;
2489 if (BaseReg != AArch64::ZA)
2490 TileNum =
N->getConstantOperandVal(2);
2496 if (BaseReg == AArch64::ZA)
2501 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2505 SDValue SubReg = CurDAG->getRegister(BaseReg, MVT::Other);
2507 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2509 EVT VT =
N->getValueType(0);
2510 for (
unsigned I = 0;
I < NumVecs; ++
I)
2511 ReplaceUses(SDValue(
N,
I),
2512 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2515 unsigned ChainIdx = NumVecs;
2516 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Mov, 1));
2517 CurDAG->RemoveDeadNode(
N);
2520void AArch64DAGToDAGISel::SelectMultiVectorMoveZ(SDNode *
N,
unsigned NumVecs,
2521 unsigned Op,
unsigned MaxIdx,
2522 unsigned Scale,
unsigned BaseReg) {
2527 if (BaseReg != AArch64::ZA)
2531 if (!SelectSMETileSlice(SliceBase, MaxIdx,
Base,
Offset, Scale))
2538 if (BaseReg != AArch64::ZA )
2539 Ops.push_back(
N->getOperand(2));
2542 Ops.push_back(
N->getOperand(0));
2543 SDNode *Mov = CurDAG->getMachineNode(
Op,
DL, {MVT::Untyped, MVT::Other},
Ops);
2545 EVT VT =
N->getValueType(0);
2546 for (
unsigned I = 0;
I < NumVecs; ++
I)
2547 ReplaceUses(SDValue(
N,
I),
2548 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
2552 unsigned ChainIdx = NumVecs;
2553 ReplaceUses(SDValue(
N, ChainIdx), SDValue(Mov, 1));
2554 CurDAG->RemoveDeadNode(
N);
2557void AArch64DAGToDAGISel::SelectUnaryMultiIntrinsic(SDNode *
N,
2558 unsigned NumOutVecs,
2562 EVT VT =
N->getValueType(0);
2563 unsigned NumInVecs =
N->getNumOperands() - 1;
2567 assert((NumInVecs == 2 || NumInVecs == 4) &&
2568 "Don't know how to handle multi-register input!");
2570 Ops.push_back(createZMulTuple(Regs));
2573 for (
unsigned I = 0;
I < NumInVecs;
I++)
2574 Ops.push_back(
N->getOperand(1 +
I));
2577 SDNode *Res = CurDAG->getMachineNode(
Opc,
DL, MVT::Untyped,
Ops);
2578 SDValue SuperReg = SDValue(Res, 0);
2580 for (
unsigned I = 0;
I < NumOutVecs;
I++)
2581 ReplaceUses(SDValue(
N,
I), CurDAG->getTargetExtractSubreg(
2582 AArch64::zsub0 +
I,
DL, VT, SuperReg));
2583 CurDAG->RemoveDeadNode(
N);
2586void AArch64DAGToDAGISel::SelectStore(SDNode *
N,
unsigned NumVecs,
2589 EVT VT =
N->getOperand(2)->getValueType(0);
2597 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2606void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *
N,
unsigned NumVecs,
2607 unsigned Scale,
unsigned Opc_rr,
2613 SDValue RegSeq = createZTuple(Regs);
2619 N, Opc_rr, Opc_ri,
N->getOperand(NumVecs + 3),
2620 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale);
2626 SDNode *St = CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0),
Ops);
2635void AArch64DAGToDAGISel::SelectPostStore(SDNode *
N,
unsigned NumVecs,
2638 EVT VT =
N->getOperand(2)->getValueType(0);
2639 const EVT ResTys[] = {MVT::i64,
2647 SDValue
Ops[] = {RegSeq,
2651 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2669 SDValue operator()(SDValue V64Reg) {
2695void AArch64DAGToDAGISel::SelectLoadLane(SDNode *
N,
unsigned NumVecs,
2698 EVT VT =
N->getValueType(0);
2710 const EVT ResTys[] = {MVT::Untyped, MVT::Other};
2712 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2714 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2716 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2717 SDValue SuperReg = SDValue(Ld, 0);
2720 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2721 AArch64::qsub2, AArch64::qsub3 };
2722 for (
unsigned i = 0; i < NumVecs; ++i) {
2723 SDValue
NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
2726 ReplaceUses(SDValue(
N, i), NV);
2729 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 1));
2730 CurDAG->RemoveDeadNode(
N);
2733void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *
N,
unsigned NumVecs,
2736 EVT VT =
N->getValueType(0);
2748 const EVT ResTys[] = {MVT::i64,
2751 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2753 SDValue
Ops[] = {RegSeq,
2754 CurDAG->getTargetConstant(LaneNo, dl,
2759 SDNode *Ld = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2762 ReplaceUses(SDValue(
N, NumVecs), SDValue(Ld, 0));
2765 SDValue SuperReg = SDValue(Ld, 1);
2767 ReplaceUses(SDValue(
N, 0),
2771 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1,
2772 AArch64::qsub2, AArch64::qsub3 };
2773 for (
unsigned i = 0; i < NumVecs; ++i) {
2774 SDValue
NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
2778 ReplaceUses(SDValue(
N, i), NV);
2783 ReplaceUses(SDValue(
N, NumVecs + 1), SDValue(Ld, 2));
2784 CurDAG->RemoveDeadNode(
N);
2787void AArch64DAGToDAGISel::SelectStoreLane(SDNode *
N,
unsigned NumVecs,
2790 EVT VT =
N->getOperand(2)->getValueType(0);
2802 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 2);
2804 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2806 SDNode *St = CurDAG->getMachineNode(
Opc, dl, MVT::Other,
Ops);
2815void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *
N,
unsigned NumVecs,
2818 EVT VT =
N->getOperand(2)->getValueType(0);
2830 const EVT ResTys[] = {MVT::i64,
2833 unsigned LaneNo =
N->getConstantOperandVal(NumVecs + 1);
2835 SDValue
Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64),
2839 SDNode *St = CurDAG->getMachineNode(
Opc, dl, ResTys,
Ops);
2850 unsigned &LSB,
unsigned &MSB,
2851 unsigned NumberOfIgnoredLowBits,
2852 bool BiggerPattern) {
2854 "N must be a AND operation to call this function");
2856 EVT VT =
N->getValueType(0);
2861 assert((VT == MVT::i32 || VT == MVT::i64) &&
2862 "Type checking must have been done before calling this function");
2876 const SDNode *Op0 =
N->getOperand(0).getNode();
2883 if (AndImm & (AndImm + 1))
2886 bool ClampMSB =
false;
2906 ClampMSB = (VT == MVT::i32);
2907 }
else if (BiggerPattern) {
2913 Opd0 =
N->getOperand(0);
2919 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.
getSizeInBits())) {
2922 <<
": Found large shift immediate, this should not happen\n"));
2936 MSB = MSB > 31 ? 31 : MSB;
2938 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
2943 SDValue &Opd0,
unsigned &Immr,
2947 EVT VT =
N->getValueType(0);
2949 assert((VT == MVT::i32 || VT == MVT::i64) &&
2950 "Type checking must have been done before calling this function");
2954 Op =
Op->getOperand(0);
2955 VT =
Op->getValueType(0);
2964 unsigned Width =
cast<VTSDNode>(
N->getOperand(1))->getVT().getSizeInBits();
2968 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri;
2969 Opd0 =
Op.getOperand(0);
2971 Imms = ShiftImm + Width - 1;
2999 Opd0 =
N->getOperand(0).getOperand(0);
3009 Opc =
N->getValueType(0) == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3016 unsigned &Immr,
unsigned &Imms,
3017 bool BiggerPattern) {
3019 "N must be a SHR/SRA operation to call this function");
3021 EVT VT =
N->getValueType(0);
3026 assert((VT == MVT::i32 || VT == MVT::i64) &&
3027 "Type checking must have been done before calling this function");
3037 Opd0 =
N->getOperand(0).getOperand(0);
3038 }
else if (VT == MVT::i32 &&
N->getOpcode() ==
ISD::SRL &&
3044 Opd0 =
N->getOperand(0).getOperand(0);
3047 assert(VT == MVT::i64 &&
"the promoted type should be i64");
3048 }
else if (BiggerPattern) {
3052 Opd0 =
N->getOperand(0);
3061 <<
": Found large shift immediate, this should not happen\n"));
3070 "bad amount in shift node!");
3071 int immr = SrlImm - ShlImm;
3076 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri;
3078 Opc =
N->getOpcode() ==
ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri;
3082bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *
N) {
3085 EVT VT =
N->getValueType(0);
3086 EVT NarrowVT =
N->getOperand(0)->getValueType(0);
3087 if (VT != MVT::i64 || NarrowVT != MVT::i32)
3091 SDValue
Op =
N->getOperand(0);
3097 SDValue Opd0 =
Widen(CurDAG,
Op.getOperand(0));
3098 unsigned Immr = ShiftImm;
3100 SDValue
Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3101 CurDAG->getTargetConstant(Imms, dl, VT)};
3102 CurDAG->SelectNodeTo(
N, AArch64::SBFMXri, VT,
Ops);
3107 SDValue &Opd0,
unsigned &Immr,
unsigned &Imms,
3108 unsigned NumberOfIgnoredLowBits = 0,
3109 bool BiggerPattern =
false) {
3110 if (
N->getValueType(0) != MVT::i32 &&
N->getValueType(0) != MVT::i64)
3113 switch (
N->getOpcode()) {
3115 if (!
N->isMachineOpcode())
3120 NumberOfIgnoredLowBits, BiggerPattern);
3129 unsigned NOpc =
N->getMachineOpcode();
3133 case AArch64::SBFMWri:
3134 case AArch64::UBFMWri:
3135 case AArch64::SBFMXri:
3136 case AArch64::UBFMXri:
3138 Opd0 =
N->getOperand(0);
3139 Immr =
N->getConstantOperandVal(1);
3140 Imms =
N->getConstantOperandVal(2);
3147bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *
N) {
3148 unsigned Opc, Immr, Imms;
3153 EVT VT =
N->getValueType(0);
3158 if ((
Opc == AArch64::SBFMXri ||
Opc == AArch64::UBFMXri) && VT == MVT::i32) {
3159 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64),
3160 CurDAG->getTargetConstant(Imms, dl, MVT::i64)};
3162 SDNode *BFM = CurDAG->getMachineNode(
Opc, dl, MVT::i64, Ops64);
3163 SDValue Inner = CurDAG->getTargetExtractSubreg(AArch64::sub_32, dl,
3164 MVT::i32, SDValue(BFM, 0));
3169 SDValue
Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT),
3170 CurDAG->getTargetConstant(Imms, dl, VT)};
3171 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
3180 unsigned NumberOfIgnoredHighBits,
EVT VT) {
3181 assert((VT == MVT::i32 || VT == MVT::i64) &&
3182 "i32 or i64 mask type expected!");
3186 APInt SignificantDstMask =
3190 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
3191 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes();
3224 APInt OpUsefulBits(UsefulBits);
3228 OpUsefulBits <<= MSB -
Imm + 1;
3233 OpUsefulBits <<=
Imm;
3235 OpUsefulBits <<= MSB + 1;
3244 UsefulBits &= OpUsefulBits;
3261 APInt Mask(UsefulBits);
3262 Mask.clearAllBits();
3270 Mask.lshrInPlace(ShiftAmt);
3276 Mask.lshrInPlace(ShiftAmt);
3292 APInt OpUsefulBits(UsefulBits);
3306 OpUsefulBits <<= Width;
3309 if (
Op.getOperand(1) == Orig) {
3311 Mask = ResultUsefulBits & OpUsefulBits;
3315 if (
Op.getOperand(0) == Orig)
3317 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3323 OpUsefulBits <<= Width;
3325 OpUsefulBits <<= LSB;
3327 if (
Op.getOperand(1) == Orig) {
3329 Mask = ResultUsefulBits & OpUsefulBits;
3330 Mask.lshrInPlace(LSB);
3333 if (
Op.getOperand(0) == Orig)
3334 Mask |= (ResultUsefulBits & ~OpUsefulBits);
3351 case AArch64::ANDSWri:
3352 case AArch64::ANDSXri:
3353 case AArch64::ANDWri:
3354 case AArch64::ANDXri:
3358 case AArch64::UBFMWri:
3359 case AArch64::UBFMXri:
3362 case AArch64::ORRWrs:
3363 case AArch64::ORRXrs:
3368 case AArch64::BFMWri:
3369 case AArch64::BFMXri:
3372 case AArch64::STRBBui:
3373 case AArch64::STURBBi:
3379 case AArch64::STRHHui:
3380 case AArch64::STURHHi:
3393 unsigned Bitwidth =
Op.getScalarValueSizeInBits();
3395 UsefulBits =
APInt(Bitwidth, 0);
3404 UsersUsefulBits |= UsefulBitsForUse;
3409 UsefulBits &= UsersUsefulBits;
3419 EVT VT =
Op.getValueType();
3422 unsigned UBFMOpc =
BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri;
3425 if (ShlAmount > 0) {
3428 UBFMOpc, dl, VT,
Op,
3433 assert(ShlAmount < 0 &&
"expected right shift");
3434 int ShrAmount = -ShlAmount;
3447 SDValue &Src,
int &DstLSB,
3454 SDValue &Src,
int &DstLSB,
3460 bool BiggerPattern,
SDValue &Src,
3461 int &DstLSB,
int &Width) {
3462 EVT VT =
Op.getValueType();
3475 switch (
Op.getOpcode()) {
3480 NonZeroBits, Src, DstLSB, Width);
3483 NonZeroBits, Src, DstLSB, Width);
3496 EVT VT =
Op.getValueType();
3497 assert((VT == MVT::i32 || VT == MVT::i64) &&
3498 "Caller guarantees VT is one of i32 or i64");
3511 assert((~AndImm & NonZeroBits) == 0 &&
3512 "Something must be wrong (e.g., in SelectionDAG::computeKnownBits)");
3541 if (!BiggerPattern && !AndOp0.
hasOneUse())
3560 <<
"Found large Width in bit-field-positioning -- this indicates no "
3561 "proper combining / constant folding was performed\n");
3570 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3585 "Op.getNode() should be a SHL node to call this function");
3587 "Op.getNode() should shift ShlImm to call this function");
3594 const uint64_t ShiftedAndImm = ((AndImm << ShlImm) >> ShlImm);
3618 EVT VT =
Op.getValueType();
3619 assert((VT == MVT::i32 || VT == MVT::i64) &&
3620 "Caller guarantees that type is i32 or i64");
3627 if (!BiggerPattern && !
Op.hasOneUse())
3636 if (ShlImm !=
uint64_t(DstLSB) && !BiggerPattern)
3644 assert(VT == MVT::i32 || VT == MVT::i64);
3655 EVT VT =
N->getValueType(0);
3656 if (VT != MVT::i32 && VT != MVT::i64)
3674 if (!
And.hasOneUse() ||
3691 if ((OrImm & NotKnownZero) != 0) {
3703 unsigned ImmS = Width - 1;
3709 bool IsBFI = LSB != 0;
3714 unsigned OrChunks = 0, BFIChunks = 0;
3715 for (
unsigned Shift = 0; Shift <
BitWidth; Shift += 16) {
3716 if (((OrImm >> Shift) & 0xFFFF) != 0)
3718 if (((BFIImm >> Shift) & 0xFFFF) != 0)
3721 if (BFIChunks > OrChunks)
3727 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm;
3735 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
3744 if (!Dst.hasOneUse())
3747 EVT VT = Dst.getValueType();
3748 assert((VT == MVT::i32 || VT == MVT::i64) &&
3749 "Caller should guarantee that VT is one of i32 or i64");
3777 if ((SrlImm + NumTrailingZeroInShiftedMask) < SizeInBits) {
3778 unsigned MaskWidth =
3781 (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
3787 SrlImm + NumTrailingZeroInShiftedMask + MaskWidth - 1,
DL, VT));
3788 ShiftedOperand =
SDValue(UBFMNode, 0);
3817 const bool BiggerPattern) {
3818 EVT VT =
N->getValueType(0);
3819 assert(
N->getOpcode() ==
ISD::OR &&
"Expect N to be an OR node");
3820 assert(((
N->getOperand(0) == OrOpd0 &&
N->getOperand(1) == OrOpd1) ||
3821 (
N->getOperand(1) == OrOpd0 &&
N->getOperand(0) == OrOpd1)) &&
3822 "Expect OrOpd0 and OrOpd1 to be operands of ISD::OR");
3823 assert((VT == MVT::i32 || VT == MVT::i64) &&
3824 "Expect result type to be i32 or i64 since N is combinable to BFM");
3831 const unsigned OrrOpc = (VT == MVT::i32) ? AArch64::ORRWrs : AArch64::ORRXrs;
3834 if (BiggerPattern) {
3857 assert((!BiggerPattern) &&
"BiggerPattern should be handled above");
3919 EVT VT =
N->getValueType(0);
3920 if (VT != MVT::i32 && VT != MVT::i64)
3928 unsigned NumberOfIgnoredLowBits = UsefulBits.
countr_zero();
3929 unsigned NumberOfIgnoredHighBits = UsefulBits.
countl_zero();
3949 for (
int I = 0;
I < 4; ++
I) {
3952 unsigned ImmR, ImmS;
3953 bool BiggerPattern =
I / 2;
3954 SDValue OrOpd0Val =
N->getOperand(
I % 2);
3956 SDValue OrOpd1Val =
N->getOperand((
I + 1) % 2);
3962 NumberOfIgnoredLowBits, BiggerPattern)) {
3965 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) ||
3966 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32))
3971 Width = ImmS - ImmR + 1;
3982 Src, DstLSB, Width)) {
3990 assert((VT == MVT::i32 || VT == MVT::i64) &&
"unexpected OR operand");
4000 APInt BitsToBeInserted =
4003 if ((BitsToBeInserted & ~
Known.Zero) != 0)
4027 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
4060 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4062 if (Src->hasOneUse() &&
4065 Src = Src->getOperand(0);
4075 unsigned ImmS = Width - 1;
4081 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri;
4089bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *
N) {
4098 CurDAG->SelectNodeTo(
N, TargetOpcode::IMPLICIT_DEF,
N->getValueType(0));
4111bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *
N) {
4115 EVT VT =
N->getValueType(0);
4116 if (VT != MVT::i32 && VT != MVT::i64)
4122 Op0, DstLSB, Width))
4128 unsigned ImmS = Width - 1;
4131 SDValue
Ops[] = {Op0, CurDAG->getTargetConstant(ImmR,
DL, VT),
4132 CurDAG->getTargetConstant(ImmS,
DL, VT)};
4133 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri;
4134 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4140bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *
N) {
4141 EVT VT =
N->getValueType(0);
4144 switch (
N->getOpcode()) {
4146 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr;
4149 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr;
4152 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr;
4155 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr;
4163 if (VT == MVT::i32) {
4166 }
else if (VT == MVT::i64) {
4172 SDValue ShiftAmt =
N->getOperand(1);
4174 SDValue NewShiftAmt;
4192 (Add0Imm %
Size == 0)) {
4198 if (SubVT == MVT::i32) {
4199 NegOpc = AArch64::SUBWrr;
4200 ZeroReg = AArch64::WZR;
4202 assert(SubVT == MVT::i64);
4203 NegOpc = AArch64::SUBXrr;
4204 ZeroReg = AArch64::XZR;
4207 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4208 MachineSDNode *Neg =
4209 CurDAG->getMachineNode(NegOpc,
DL, SubVT, Zero, Add1);
4210 NewShiftAmt = SDValue(Neg, 0);
4218 if (SubVT == MVT::i32) {
4219 NotOpc = AArch64::ORNWrr;
4220 ZeroReg = AArch64::WZR;
4222 assert(SubVT == MVT::i64);
4223 NotOpc = AArch64::ORNXrr;
4224 ZeroReg = AArch64::XZR;
4227 CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL, ZeroReg, SubVT);
4228 MachineSDNode *
Not =
4229 CurDAG->getMachineNode(NotOpc,
DL, SubVT, Zero, Add1);
4230 NewShiftAmt = SDValue(
Not, 0);
4251 else if (VT == MVT::i64 && NewShiftAmt->
getValueType(0) == MVT::i32) {
4252 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32,
DL, MVT::i32);
4253 MachineSDNode *Ext = CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT,
4254 NewShiftAmt, SubReg);
4255 NewShiftAmt = SDValue(Ext, 0);
4258 SDValue
Ops[] = {
N->getOperand(0), NewShiftAmt};
4259 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
4266 bool isReciprocal) {
4269 FVal = CN->getValueAPF();
4272 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow ||
4282 if (
unsigned FBits =
4295 bool isReciprocal) {
4296 if ((
N.getOpcode() == AArch64ISD::NVCAST ||
N.getOpcode() ==
ISD::BITCAST) &&
4297 N.getValueType().getScalarSizeInBits() ==
4298 N.getOperand(0).getValueType().getScalarSizeInBits())
4299 N =
N.getOperand(0);
4301 auto ImmToFloat = [RegWidth](
APInt Imm) {
4315 switch (
N->getOpcode()) {
4316 case AArch64ISD::MOVIshift:
4317 FVal = ImmToFloat(
APInt(RegWidth,
N.getConstantOperandVal(0)
4318 <<
N.getConstantOperandVal(1)));
4320 case AArch64ISD::FMOV:
4321 FVal = ImmToFloat(
DecodeFMOVImm(
N.getConstantOperandVal(0), RegWidth));
4323 case AArch64ISD::DUP:
4325 FVal = ImmToFloat(
N.getConstantOperandAPInt(0).trunc(RegWidth));
4333 if (
unsigned FBits =
4342bool AArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue
N, SDValue &FixedPos,
4343 unsigned RegWidth) {
4348bool AArch64DAGToDAGISel::SelectCVTFixedPointVec(SDValue
N, SDValue &FixedPos,
4349 unsigned RegWidth) {
4351 CurDAG,
N, FixedPos, RegWidth,
false);
4354bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperandVec(SDValue
N,
4356 unsigned RegWidth) {
4358 CurDAG,
N, FixedPos, RegWidth,
true);
4361bool AArch64DAGToDAGISel::SelectCVTFixedPosRecipOperand(SDValue
N,
4363 unsigned RegWidth) {
4373 RegString.
split(Fields,
':');
4375 if (Fields.
size() == 1)
4379 &&
"Invalid number of fields in read register string");
4382 bool AllIntFields =
true;
4386 AllIntFields &= !
Field.getAsInteger(10, IntField);
4387 Ops.push_back(IntField);
4391 "Unexpected non-integer value in special register string.");
4396 return (
Ops[0] << 14) | (
Ops[1] << 11) | (
Ops[2] << 7) | (
Ops[3] << 3) |
4404bool AArch64DAGToDAGISel::tryReadRegister(SDNode *
N) {
4406 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4409 bool ReadIs128Bit =
N->getOpcode() == AArch64ISD::MRRS;
4411 unsigned Opcode64Bit = AArch64::MRS;
4416 const auto *TheReg =
4417 AArch64SysReg::lookupSysRegByName(RegString->getString());
4418 if (TheReg && TheReg->Readable &&
4419 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4420 Imm = TheReg->Encoding;
4426 if (!ReadIs128Bit && RegString->getString() ==
"pc") {
4427 Opcode64Bit = AArch64::ADR;
4436 RegString->getString());
4437 unsigned PseudoOp = 0;
4438 if (AArch64::GPR64RegClass.
contains(PReg))
4439 PseudoOp = AArch64::READ_REGISTER_GPR64;
4440 else if (AArch64::FPR64RegClass.
contains(PReg))
4441 PseudoOp = AArch64::READ_REGISTER_FPR64;
4442 if (!ReadIs128Bit && PseudoOp &&
N->getValueType(0) == MVT::i64) {
4443 CurDAG->SelectNodeTo(
N, PseudoOp, MVT::i64, MVT::Other,
4444 {CurDAG->getTargetConstant(PReg,
DL, MVT::i32),
4453 SDValue InChain =
N->getOperand(0);
4454 SDValue SysRegImm = CurDAG->getTargetConstant(
Imm,
DL, MVT::i32);
4455 if (!ReadIs128Bit) {
4456 CurDAG->SelectNodeTo(
N, Opcode64Bit, MVT::i64, MVT::Other ,
4457 {SysRegImm, InChain});
4459 SDNode *MRRS = CurDAG->getMachineNode(
4461 {MVT::Untyped , MVT::Other },
4462 {SysRegImm, InChain});
4466 SDValue
Lo = CurDAG->getTargetExtractSubreg(AArch64::sube64,
DL, MVT::i64,
4468 SDValue
Hi = CurDAG->getTargetExtractSubreg(AArch64::subo64,
DL, MVT::i64,
4470 SDValue OutChain = SDValue(MRRS, 1);
4472 ReplaceUses(SDValue(
N, 0),
Lo);
4473 ReplaceUses(SDValue(
N, 1),
Hi);
4474 ReplaceUses(SDValue(
N, 2), OutChain);
4483bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *
N) {
4485 const auto *RegString =
cast<MDString>(MD->getMD()->getOperand(0));
4488 bool WriteIs128Bit =
N->getOpcode() == AArch64ISD::MSRR;
4490 if (!WriteIs128Bit) {
4496 auto trySelectPState = [&](
auto PMapper,
unsigned State) {
4499 "Expected a constant integer expression.");
4500 unsigned Reg = PMapper->Encoding;
4501 uint64_t Immed =
N->getConstantOperandVal(2);
4502 CurDAG->SelectNodeTo(
4503 N, State, MVT::Other, CurDAG->getTargetConstant(
Reg,
DL, MVT::i32),
4504 CurDAG->getTargetConstant(Immed,
DL, MVT::i16),
N->getOperand(0));
4510 if (trySelectPState(
4511 AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
4512 AArch64::MSRpstateImm4))
4514 if (trySelectPState(
4515 AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
4516 AArch64::MSRpstateImm1))
4525 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString());
4526 if (TheReg && TheReg->Writeable &&
4527 TheReg->haveFeatures(Subtarget->getFeatureBits()))
4528 Imm = TheReg->Encoding;
4538 RegString->getString());
4539 bool IsGPR = AArch64::GPR64RegClass.contains(PReg);
4540 bool IsFPR = AArch64::FPR64RegClass.contains(PReg);
4541 if (!WriteIs128Bit && (IsGPR || IsFPR) &&
4542 N->getOperand(2).getValueType() == MVT::i64) {
4544 CurDAG->getCopyToReg(
N->getOperand(0),
DL, PReg,
N->getOperand(2));
4545 SDValue RegOp = CurDAG->getRegister(PReg, MVT::i64);
4546 SDNode *FakeUse = CurDAG->getMachineNode(TargetOpcode::FAKE_USE,
DL,
4547 MVT::Other, {RegOp,
Copy});
4548 ReplaceUses(SDValue(
N, 0), SDValue(FakeUse, 0));
4549 CurDAG->RemoveDeadNode(
N);
4557 if (!WriteIs128Bit) {
4558 CurDAG->SelectNodeTo(
N, AArch64::MSR, MVT::Other,
4559 CurDAG->getTargetConstant(
Imm,
DL, MVT::i32),
4560 N->getOperand(2), InChain);
4564 SDNode *Pair = CurDAG->getMachineNode(
4565 TargetOpcode::REG_SEQUENCE,
DL, MVT::Untyped ,
4566 {CurDAG->getTargetConstant(AArch64::XSeqPairsClassRegClass.getID(),
DL,
4569 CurDAG->getTargetConstant(AArch64::sube64,
DL, MVT::i32),
4571 CurDAG->getTargetConstant(AArch64::subo64,
DL, MVT::i32)});
4573 CurDAG->SelectNodeTo(
N, AArch64::MSRR, MVT::Other,
4574 CurDAG->getTargetConstant(
Imm,
DL, MVT::i32),
4575 SDValue(Pair, 0), InChain);
4582bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *
N) {
4587 if (Subtarget->hasLSE())
return false;
4589 if (MemTy == MVT::i8)
4590 Opcode = AArch64::CMP_SWAP_8;
4591 else if (MemTy == MVT::i16)
4592 Opcode = AArch64::CMP_SWAP_16;
4593 else if (MemTy == MVT::i32)
4594 Opcode = AArch64::CMP_SWAP_32;
4595 else if (MemTy == MVT::i64)
4596 Opcode = AArch64::CMP_SWAP_64;
4600 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32;
4601 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3),
4603 SDNode *CmpSwap = CurDAG->getMachineNode(
4605 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other),
Ops);
4610 ReplaceUses(SDValue(
N, 0), SDValue(CmpSwap, 0));
4611 ReplaceUses(SDValue(
N, 1), SDValue(CmpSwap, 2));
4612 CurDAG->RemoveDeadNode(
N);
4617bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue
N, MVT VT, SDValue &
Imm,
4618 SDValue &Shift,
bool Negate) {
4625 return SelectSVEAddSubImm(SDLoc(
N), Val, VT,
Imm, Shift, Negate);
4628bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDLoc
DL, APInt Val, MVT VT,
4629 SDValue &
Imm, SDValue &Shift,
4637 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4644 if ((Val & ~0xff) == 0) {
4645 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4650 if ((Val & ~0xff00) == 0) {
4651 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4663bool AArch64DAGToDAGISel::SelectSVEAddSubSSatImm(SDValue
N, MVT VT,
4664 SDValue &
Imm, SDValue &Shift,
4687 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4688 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4695 Shift = CurDAG->getTargetConstant(0,
DL, MVT::i32);
4696 Imm = CurDAG->getTargetConstant(Val,
DL, MVT::i32);
4700 if (Val <= 65280 && Val % 256 == 0) {
4701 Shift = CurDAG->getTargetConstant(8,
DL, MVT::i32);
4702 Imm = CurDAG->getTargetConstant(Val >> 8,
DL, MVT::i32);
4713bool AArch64DAGToDAGISel::SelectSVECpyDupImm(SDValue
N, MVT VT, SDValue &
Imm,
4723 int32_t ImmVal, ShiftVal;
4728 Shift = CurDAG->getTargetConstant(ShiftVal,
DL, MVT::i32);
4729 Imm = CurDAG->getTargetConstant(ImmVal,
DL, MVT::i32);
4733bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue
N, SDValue &
Imm) {
4735 return SelectSVESignedArithImm(SDLoc(
N), CNode->getAPIntValue(),
Imm);
4739bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDLoc
DL, APInt Val,
4742 if (ImmVal >= -128 && ImmVal < 128) {
4743 Imm = CurDAG->getSignedTargetConstant(ImmVal,
DL, MVT::i32);
4749bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue
N, MVT VT, SDValue &
Imm) {
4751 uint64_t ImmVal = CNode->getZExtValue();
4761 ImmVal &= 0xFFFFFFFF;
4770 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4777bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue
N, MVT VT, SDValue &
Imm,
4781 ImmVal = CI->getZExtValue();
4783 ImmVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
4794 Imm = CurDAG->getTargetConstant(encoding, SDLoc(
N), MVT::i64);
4803bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue
N,
uint64_t Low,
4807 uint64_t ImmVal = CN->getZExtValue();
4814 if (ImmVal >
High) {
4815 if (!AllowSaturation)
4820 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(
N), MVT::i32);
4827bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *
N) {
4835 SDValue IRG_SP =
N->getOperand(2);
4841 const TargetLowering *TLI = getTargetLowering();
4844 SDValue FiOp = CurDAG->getTargetFrameIndex(
4846 int TagOffset =
N->getConstantOperandVal(3);
4848 SDNode *
Out = CurDAG->getMachineNode(
4849 AArch64::TAGPstack,
DL, MVT::i64,
4850 {FiOp, CurDAG->getTargetConstant(0,
DL, MVT::i64),
N->
getOperand(2),
4851 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4852 ReplaceNode(
N, Out);
4856void AArch64DAGToDAGISel::SelectTagP(SDNode *
N) {
4858 "llvm.aarch64.tagp third argument must be an immediate");
4859 if (trySelectStackSlotTagP(
N))
4866 int TagOffset =
N->getConstantOperandVal(3);
4867 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP,
DL, MVT::i64,
4868 {
N->getOperand(1),
N->getOperand(2)});
4869 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr,
DL, MVT::i64,
4870 {SDValue(N1, 0),
N->getOperand(2)});
4871 SDNode *N3 = CurDAG->getMachineNode(
4872 AArch64::ADDG,
DL, MVT::i64,
4873 {SDValue(N2, 0), CurDAG->getTargetConstant(0,
DL, MVT::i64),
4874 CurDAG->getTargetConstant(TagOffset,
DL, MVT::i64)});
4878bool AArch64DAGToDAGISel::trySelectCastFixedLengthToScalableVector(SDNode *
N) {
4882 if (
N->getConstantOperandVal(2) != 0)
4884 if (!
N->getOperand(0).isUndef())
4888 EVT VT =
N->getValueType(0);
4889 EVT InVT =
N->getOperand(1).getValueType();
4900 "Expected to insert into a packed scalable vector!");
4903 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4904 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4905 N->getOperand(1), RC));
4909bool AArch64DAGToDAGISel::trySelectCastScalableToFixedLengthVector(SDNode *
N) {
4913 if (
N->getConstantOperandVal(1) != 0)
4917 EVT VT =
N->getValueType(0);
4918 EVT InVT =
N->getOperand(0).getValueType();
4929 "Expected to extract from a packed scalable vector!");
4932 auto RC = CurDAG->getTargetConstant(AArch64::ZPRRegClassID,
DL, MVT::i64);
4933 ReplaceNode(
N, CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
DL, VT,
4934 N->getOperand(0), RC));
4938bool AArch64DAGToDAGISel::trySelectXAR(SDNode *
N) {
4941 SDValue N0 =
N->getOperand(0);
4944 EVT VT =
N->getValueType(0);
4957 (Subtarget->hasSVE2() ||
4958 (Subtarget->hasSME() && Subtarget->
isStreaming()))) {
4959 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4962 if (N0.
getOpcode() != AArch64ISD::SHL_PRED ||
4966 auto *TLI =
static_cast<const AArch64TargetLowering *
>(getTargetLowering());
4967 if (!TLI->isAllActivePredicate(*CurDAG, N0.
getOperand(0)) ||
4968 !TLI->isAllActivePredicate(*CurDAG, N1.
getOperand(0)))
4975 bool IsXOROperand =
true;
4977 IsXOROperand =
false;
4983 APInt ShlAmt, ShrAmt;
4991 if (!IsXOROperand) {
4992 SDValue
Zero = CurDAG->getTargetConstant(0,
DL, MVT::i64);
4993 SDNode *MOV = CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, VT, Zero);
4994 SDValue MOVIV = SDValue(MOV, 0);
4996 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
4997 SDNode *SubRegToReg =
4998 CurDAG->getMachineNode(AArch64::SUBREG_TO_REG,
DL, VT, MOVIV, ZSub);
5001 R2 = SDValue(SubRegToReg, 0);
5009 VT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
5010 AArch64::XAR_ZZZI_D})) {
5011 CurDAG->SelectNodeTo(
N,
Opc, VT,
Ops);
5036 SVT = Subtarget->hasSHA3() ? MVT::v2i64 : MVT::nxv2i64;
5046 if (N0->
getOpcode() != AArch64ISD::VSHL ||
5054 bool IsXOROperand =
true;
5056 IsXOROperand =
false;
5059 R1 =
XOR.getOperand(0);
5060 R2 =
XOR.getOperand(1);
5066 SDValue
Imm = CurDAG->getTargetConstant(
5070 if (ShAmt + HsAmt != VTSizeInBits)
5073 if (!IsXOROperand) {
5074 SDValue
Zero = CurDAG->getTargetConstant(0,
DL, MVT::i64);
5076 CurDAG->getMachineNode(AArch64::MOVIv2d_ns,
DL, MVT::v2i64, Zero);
5077 SDValue MOVIV = SDValue(MOV, 0);
5085 SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, SVT), 0);
5090 SDValue UndefQ = SDValue(
5091 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, QVT), 0);
5092 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5094 R1 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5097 if (
R2.getValueType() == VT)
5098 R2 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, QVT,
5103 SDValue SubReg = CurDAG->getTargetConstant(
5106 R1 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
Undef,
5111 R2 = SDValue(CurDAG->getMachineNode(AArch64::INSERT_SUBREG,
DL, SVT,
5117 SDNode *XAR =
nullptr;
5121 SVT, {AArch64::XAR_ZZZI_B, AArch64::XAR_ZZZI_H, AArch64::XAR_ZZZI_S,
5122 AArch64::XAR_ZZZI_D}))
5123 XAR = CurDAG->getMachineNode(
Opc,
DL, SVT,
Ops);
5125 XAR = CurDAG->getMachineNode(AArch64::XAR,
DL, SVT,
Ops);
5128 assert(XAR &&
"Unexpected NULL value for XAR instruction in DAG");
5134 SDValue ZSub = CurDAG->getTargetConstant(AArch64::zsub,
DL, MVT::i32);
5135 SDNode *Q = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, QVT,
5136 SDValue(XAR, 0), ZSub);
5138 SDValue DSub = CurDAG->getTargetConstant(AArch64::dsub,
DL, MVT::i32);
5139 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5140 SDValue(Q, 0), DSub);
5142 SDValue SubReg = CurDAG->getTargetConstant(
5145 XAR = CurDAG->getMachineNode(AArch64::EXTRACT_SUBREG,
DL, VT,
5146 SDValue(XAR, 0), SubReg);
5149 ReplaceNode(
N, XAR);
5156 assert(VT == MVT::i32 || VT == MVT::i64);
5158 VT == MVT::i32 ? AArch64::WZR : AArch64::XZR, VT);
5161void AArch64DAGToDAGISel::Select(SDNode *Node) {
5163 if (
Node->isMachineOpcode()) {
5165 Node->setNodeId(-1);
5170 EVT VT =
Node->getValueType(0);
5172 switch (
Node->getOpcode()) {
5177 if (SelectCMP_SWAP(Node))
5182 case AArch64ISD::MRRS:
5183 if (tryReadRegister(Node))
5188 case AArch64ISD::MSRR:
5189 if (tryWriteRegister(Node))
5196 if (tryIndexedLoad(Node))
5205 if (tryBitfieldExtractOp(Node))
5207 if (tryBitfieldInsertInZeroOp(Node))
5212 if (tryShiftAmountMod(Node))
5217 if (tryBitfieldExtractOpFromSExt(Node))
5222 if (tryBitfieldInsertOp(Node))
5224 if (trySelectXAR(Node))
5229 if (trySelectCastScalableToFixedLengthVector(Node))
5235 if (trySelectCastFixedLengthToScalableVector(Node))
5240 case AArch64ISD::CSEL:
5241 if (tryFoldCselToFMaxMin(Node))
5249 if (ConstNode->
isZero() && (VT == MVT::i32 || VT == MVT::i64)) {
5260 const TargetLowering *TLI = getTargetLowering();
5261 SDValue TFI = CurDAG->getTargetFrameIndex(
5264 SDValue
Ops[] = { TFI, CurDAG->getTargetConstant(0,
DL, MVT::i32),
5265 CurDAG->getTargetConstant(Shifter,
DL, MVT::i32) };
5266 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64,
Ops);
5270 unsigned IntNo =
Node->getConstantOperandVal(1);
5274 case Intrinsic::aarch64_gcsss: {
5276 SDValue Chain =
Node->getOperand(0);
5277 SDValue Val =
Node->getOperand(2);
5278 SDValue
Zero = CurDAG->getCopyFromReg(Chain,
DL, AArch64::XZR, MVT::i64);
5280 CurDAG->getMachineNode(AArch64::GCSSS1,
DL, MVT::Other, Val, Chain);
5281 SDNode *SS2 = CurDAG->getMachineNode(AArch64::GCSSS2,
DL, MVT::i64,
5282 MVT::Other, Zero, SDValue(SS1, 0));
5283 ReplaceNode(Node, SS2);
5286 case Intrinsic::aarch64_ldaxp:
5287 case Intrinsic::aarch64_ldxp: {
5289 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX;
5290 SDValue MemAddr =
Node->getOperand(2);
5292 SDValue Chain =
Node->getOperand(0);
5294 SDNode *Ld = CurDAG->getMachineNode(
Op,
DL, MVT::i64, MVT::i64,
5295 MVT::Other, MemAddr, Chain);
5298 MachineMemOperand *MemOp =
5301 ReplaceNode(Node, Ld);
5304 case Intrinsic::aarch64_stlxp:
5305 case Intrinsic::aarch64_stxp: {
5307 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX;
5309 SDValue Chain =
Node->getOperand(0);
5310 SDValue ValLo =
Node->getOperand(2);
5311 SDValue ValHi =
Node->getOperand(3);
5312 SDValue MemAddr =
Node->getOperand(4);
5315 SDValue
Ops[] = {ValLo, ValHi, MemAddr, Chain};
5317 SDNode *St = CurDAG->getMachineNode(
Op,
DL, MVT::i32, MVT::Other,
Ops);
5319 MachineMemOperand *MemOp =
5323 ReplaceNode(Node, St);
5326 case Intrinsic::aarch64_neon_ld1x2:
5327 if (VT == MVT::v8i8) {
5328 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0);
5330 }
else if (VT == MVT::v16i8) {
5331 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0);
5333 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5334 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0);
5336 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5337 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0);
5339 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5340 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0);
5342 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5343 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0);
5345 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5346 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5348 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5349 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0);
5353 case Intrinsic::aarch64_neon_ld1x3:
5354 if (VT == MVT::v8i8) {
5355 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0);
5357 }
else if (VT == MVT::v16i8) {
5358 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0);
5360 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5361 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0);
5363 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5364 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0);
5366 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5367 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0);
5369 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5370 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0);
5372 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5373 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5375 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5376 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0);
5380 case Intrinsic::aarch64_neon_ld1x4:
5381 if (VT == MVT::v8i8) {
5382 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0);
5384 }
else if (VT == MVT::v16i8) {
5385 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0);
5387 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5388 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0);
5390 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5391 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0);
5393 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5394 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0);
5396 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5397 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0);
5399 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5400 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5402 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5403 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0);
5407 case Intrinsic::aarch64_neon_ld2:
5408 if (VT == MVT::v8i8) {
5409 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0);
5411 }
else if (VT == MVT::v16i8) {
5412 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0);
5414 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5415 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0);
5417 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5418 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0);
5420 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5421 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0);
5423 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5424 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0);
5426 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5427 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0);
5429 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5430 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0);
5434 case Intrinsic::aarch64_neon_ld3:
5435 if (VT == MVT::v8i8) {
5436 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0);
5438 }
else if (VT == MVT::v16i8) {
5439 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0);
5441 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5442 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0);
5444 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5445 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0);
5447 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5448 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0);
5450 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5451 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0);
5453 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5454 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0);
5456 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5457 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0);
5461 case Intrinsic::aarch64_neon_ld4:
5462 if (VT == MVT::v8i8) {
5463 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0);
5465 }
else if (VT == MVT::v16i8) {
5466 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0);
5468 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5469 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0);
5471 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5472 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0);
5474 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5475 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0);
5477 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5478 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0);
5480 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5481 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0);
5483 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5484 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0);
5488 case Intrinsic::aarch64_neon_ld2r:
5489 if (VT == MVT::v8i8) {
5490 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0);
5492 }
else if (VT == MVT::v16i8) {
5493 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0);
5495 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5496 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0);
5498 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5499 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0);
5501 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5502 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0);
5504 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5505 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0);
5507 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5508 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0);
5510 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5511 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0);
5515 case Intrinsic::aarch64_neon_ld3r:
5516 if (VT == MVT::v8i8) {
5517 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0);
5519 }
else if (VT == MVT::v16i8) {
5520 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0);
5522 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5523 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0);
5525 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5526 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0);
5528 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5529 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0);
5531 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5532 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0);
5534 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5535 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0);
5537 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5538 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0);
5542 case Intrinsic::aarch64_neon_ld4r:
5543 if (VT == MVT::v8i8) {
5544 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0);
5546 }
else if (VT == MVT::v16i8) {
5547 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0);
5549 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
5550 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0);
5552 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
5553 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0);
5555 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
5556 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0);
5558 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
5559 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0);
5561 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
5562 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0);
5564 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
5565 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0);
5569 case Intrinsic::aarch64_neon_ld2lane:
5570 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5571 SelectLoadLane(Node, 2, AArch64::LD2i8);
5573 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5574 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5575 SelectLoadLane(Node, 2, AArch64::LD2i16);
5577 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5579 SelectLoadLane(Node, 2, AArch64::LD2i32);
5581 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5583 SelectLoadLane(Node, 2, AArch64::LD2i64);
5587 case Intrinsic::aarch64_neon_ld3lane:
5588 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5589 SelectLoadLane(Node, 3, AArch64::LD3i8);
5591 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5592 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5593 SelectLoadLane(Node, 3, AArch64::LD3i16);
5595 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5597 SelectLoadLane(Node, 3, AArch64::LD3i32);
5599 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5601 SelectLoadLane(Node, 3, AArch64::LD3i64);
5605 case Intrinsic::aarch64_neon_ld4lane:
5606 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
5607 SelectLoadLane(Node, 4, AArch64::LD4i8);
5609 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
5610 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
5611 SelectLoadLane(Node, 4, AArch64::LD4i16);
5613 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
5615 SelectLoadLane(Node, 4, AArch64::LD4i32);
5617 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
5619 SelectLoadLane(Node, 4, AArch64::LD4i64);
5623 case Intrinsic::aarch64_ld64b:
5624 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0);
5626 case Intrinsic::aarch64_sve_ld2q_sret: {
5627 SelectPredicatedLoad(Node, 2, 4, AArch64::LD2Q_IMM, AArch64::LD2Q,
true);
5630 case Intrinsic::aarch64_sve_ld3q_sret: {
5631 SelectPredicatedLoad(Node, 3, 4, AArch64::LD3Q_IMM, AArch64::LD3Q,
true);
5634 case Intrinsic::aarch64_sve_ld4q_sret: {
5635 SelectPredicatedLoad(Node, 4, 4, AArch64::LD4Q_IMM, AArch64::LD4Q,
true);
5638 case Intrinsic::aarch64_sve_ld2_sret: {
5639 if (VT == MVT::nxv16i8) {
5640 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B,
5643 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5644 VT == MVT::nxv8bf16) {
5645 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H,
5648 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5649 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W,
5652 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5653 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D,
5659 case Intrinsic::aarch64_sve_ld1_pn_x2: {
5660 if (VT == MVT::nxv16i8) {
5661 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5662 SelectContiguousMultiVectorLoad(
5663 Node, 2, 0, AArch64::LD1B_2Z_IMM_PSEUDO, AArch64::LD1B_2Z_PSEUDO);
5664 else if (Subtarget->hasSVE2p1())
5665 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LD1B_2Z_IMM,
5670 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5671 VT == MVT::nxv8bf16) {
5672 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5673 SelectContiguousMultiVectorLoad(
5674 Node, 2, 1, AArch64::LD1H_2Z_IMM_PSEUDO, AArch64::LD1H_2Z_PSEUDO);
5675 else if (Subtarget->hasSVE2p1())
5676 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LD1H_2Z_IMM,
5681 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5682 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5683 SelectContiguousMultiVectorLoad(
5684 Node, 2, 2, AArch64::LD1W_2Z_IMM_PSEUDO, AArch64::LD1W_2Z_PSEUDO);
5685 else if (Subtarget->hasSVE2p1())
5686 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LD1W_2Z_IMM,
5691 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5692 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5693 SelectContiguousMultiVectorLoad(
5694 Node, 2, 3, AArch64::LD1D_2Z_IMM_PSEUDO, AArch64::LD1D_2Z_PSEUDO);
5695 else if (Subtarget->hasSVE2p1())
5696 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LD1D_2Z_IMM,
5704 case Intrinsic::aarch64_sve_ld1_pn_x4: {
5705 if (VT == MVT::nxv16i8) {
5706 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5707 SelectContiguousMultiVectorLoad(
5708 Node, 4, 0, AArch64::LD1B_4Z_IMM_PSEUDO, AArch64::LD1B_4Z_PSEUDO);
5709 else if (Subtarget->hasSVE2p1())
5710 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LD1B_4Z_IMM,
5715 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5716 VT == MVT::nxv8bf16) {
5717 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5718 SelectContiguousMultiVectorLoad(
5719 Node, 4, 1, AArch64::LD1H_4Z_IMM_PSEUDO, AArch64::LD1H_4Z_PSEUDO);
5720 else if (Subtarget->hasSVE2p1())
5721 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LD1H_4Z_IMM,
5726 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5727 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5728 SelectContiguousMultiVectorLoad(
5729 Node, 4, 2, AArch64::LD1W_4Z_IMM_PSEUDO, AArch64::LD1W_4Z_PSEUDO);
5730 else if (Subtarget->hasSVE2p1())
5731 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LD1W_4Z_IMM,
5736 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5737 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5738 SelectContiguousMultiVectorLoad(
5739 Node, 4, 3, AArch64::LD1D_4Z_IMM_PSEUDO, AArch64::LD1D_4Z_PSEUDO);
5740 else if (Subtarget->hasSVE2p1())
5741 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LD1D_4Z_IMM,
5749 case Intrinsic::aarch64_sve_ldnt1_pn_x2: {
5750 if (VT == MVT::nxv16i8) {
5751 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5752 SelectContiguousMultiVectorLoad(Node, 2, 0,
5753 AArch64::LDNT1B_2Z_IMM_PSEUDO,
5754 AArch64::LDNT1B_2Z_PSEUDO);
5755 else if (Subtarget->hasSVE2p1())
5756 SelectContiguousMultiVectorLoad(Node, 2, 0, AArch64::LDNT1B_2Z_IMM,
5757 AArch64::LDNT1B_2Z);
5761 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5762 VT == MVT::nxv8bf16) {
5763 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5764 SelectContiguousMultiVectorLoad(Node, 2, 1,
5765 AArch64::LDNT1H_2Z_IMM_PSEUDO,
5766 AArch64::LDNT1H_2Z_PSEUDO);
5767 else if (Subtarget->hasSVE2p1())
5768 SelectContiguousMultiVectorLoad(Node, 2, 1, AArch64::LDNT1H_2Z_IMM,
5769 AArch64::LDNT1H_2Z);
5773 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5774 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5775 SelectContiguousMultiVectorLoad(Node, 2, 2,
5776 AArch64::LDNT1W_2Z_IMM_PSEUDO,
5777 AArch64::LDNT1W_2Z_PSEUDO);
5778 else if (Subtarget->hasSVE2p1())
5779 SelectContiguousMultiVectorLoad(Node, 2, 2, AArch64::LDNT1W_2Z_IMM,
5780 AArch64::LDNT1W_2Z);
5784 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5785 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5786 SelectContiguousMultiVectorLoad(Node, 2, 3,
5787 AArch64::LDNT1D_2Z_IMM_PSEUDO,
5788 AArch64::LDNT1D_2Z_PSEUDO);
5789 else if (Subtarget->hasSVE2p1())
5790 SelectContiguousMultiVectorLoad(Node, 2, 3, AArch64::LDNT1D_2Z_IMM,
5791 AArch64::LDNT1D_2Z);
5798 case Intrinsic::aarch64_sve_ldnt1_pn_x4: {
5799 if (VT == MVT::nxv16i8) {
5800 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5801 SelectContiguousMultiVectorLoad(Node, 4, 0,
5802 AArch64::LDNT1B_4Z_IMM_PSEUDO,
5803 AArch64::LDNT1B_4Z_PSEUDO);
5804 else if (Subtarget->hasSVE2p1())
5805 SelectContiguousMultiVectorLoad(Node, 4, 0, AArch64::LDNT1B_4Z_IMM,
5806 AArch64::LDNT1B_4Z);
5810 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5811 VT == MVT::nxv8bf16) {
5812 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5813 SelectContiguousMultiVectorLoad(Node, 4, 1,
5814 AArch64::LDNT1H_4Z_IMM_PSEUDO,
5815 AArch64::LDNT1H_4Z_PSEUDO);
5816 else if (Subtarget->hasSVE2p1())
5817 SelectContiguousMultiVectorLoad(Node, 4, 1, AArch64::LDNT1H_4Z_IMM,
5818 AArch64::LDNT1H_4Z);
5822 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5823 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5824 SelectContiguousMultiVectorLoad(Node, 4, 2,
5825 AArch64::LDNT1W_4Z_IMM_PSEUDO,
5826 AArch64::LDNT1W_4Z_PSEUDO);
5827 else if (Subtarget->hasSVE2p1())
5828 SelectContiguousMultiVectorLoad(Node, 4, 2, AArch64::LDNT1W_4Z_IMM,
5829 AArch64::LDNT1W_4Z);
5833 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5834 if (Subtarget->hasSME2() && Subtarget->
isStreaming())
5835 SelectContiguousMultiVectorLoad(Node, 4, 3,
5836 AArch64::LDNT1D_4Z_IMM_PSEUDO,
5837 AArch64::LDNT1D_4Z_PSEUDO);
5838 else if (Subtarget->hasSVE2p1())
5839 SelectContiguousMultiVectorLoad(Node, 4, 3, AArch64::LDNT1D_4Z_IMM,
5840 AArch64::LDNT1D_4Z);
5847 case Intrinsic::aarch64_sve_ld3_sret: {
5848 if (VT == MVT::nxv16i8) {
5849 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B,
5852 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5853 VT == MVT::nxv8bf16) {
5854 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H,
5857 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5858 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W,
5861 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5862 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D,
5868 case Intrinsic::aarch64_sve_ld4_sret: {
5869 if (VT == MVT::nxv16i8) {
5870 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B,
5873 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5874 VT == MVT::nxv8bf16) {
5875 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H,
5878 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5879 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W,
5882 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5883 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D,
5889 case Intrinsic::aarch64_sme_read_hor_vg2: {
5890 if (VT == MVT::nxv16i8) {
5891 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5892 AArch64::MOVA_2ZMXI_H_B);
5894 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5895 VT == MVT::nxv8bf16) {
5896 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5897 AArch64::MOVA_2ZMXI_H_H);
5899 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5900 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5901 AArch64::MOVA_2ZMXI_H_S);
5903 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5904 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5905 AArch64::MOVA_2ZMXI_H_D);
5910 case Intrinsic::aarch64_sme_read_ver_vg2: {
5911 if (VT == MVT::nxv16i8) {
5912 SelectMultiVectorMove<14, 2>(Node, 2, AArch64::ZAB0,
5913 AArch64::MOVA_2ZMXI_V_B);
5915 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5916 VT == MVT::nxv8bf16) {
5917 SelectMultiVectorMove<6, 2>(Node, 2, AArch64::ZAH0,
5918 AArch64::MOVA_2ZMXI_V_H);
5920 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5921 SelectMultiVectorMove<2, 2>(Node, 2, AArch64::ZAS0,
5922 AArch64::MOVA_2ZMXI_V_S);
5924 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5925 SelectMultiVectorMove<0, 2>(Node, 2, AArch64::ZAD0,
5926 AArch64::MOVA_2ZMXI_V_D);
5931 case Intrinsic::aarch64_sme_read_hor_vg4: {
5932 if (VT == MVT::nxv16i8) {
5933 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5934 AArch64::MOVA_4ZMXI_H_B);
5936 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5937 VT == MVT::nxv8bf16) {
5938 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5939 AArch64::MOVA_4ZMXI_H_H);
5941 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5942 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAS0,
5943 AArch64::MOVA_4ZMXI_H_S);
5945 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5946 SelectMultiVectorMove<0, 2>(Node, 4, AArch64::ZAD0,
5947 AArch64::MOVA_4ZMXI_H_D);
5952 case Intrinsic::aarch64_sme_read_ver_vg4: {
5953 if (VT == MVT::nxv16i8) {
5954 SelectMultiVectorMove<12, 4>(Node, 4, AArch64::ZAB0,
5955 AArch64::MOVA_4ZMXI_V_B);
5957 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5958 VT == MVT::nxv8bf16) {
5959 SelectMultiVectorMove<4, 4>(Node, 4, AArch64::ZAH0,
5960 AArch64::MOVA_4ZMXI_V_H);
5962 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5963 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAS0,
5964 AArch64::MOVA_4ZMXI_V_S);
5966 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5967 SelectMultiVectorMove<0, 4>(Node, 4, AArch64::ZAD0,
5968 AArch64::MOVA_4ZMXI_V_D);
5973 case Intrinsic::aarch64_sme_read_vg1x2: {
5974 SelectMultiVectorMove<7, 1>(Node, 2, AArch64::ZA,
5975 AArch64::MOVA_VG2_2ZMXI);
5978 case Intrinsic::aarch64_sme_read_vg1x4: {
5979 SelectMultiVectorMove<7, 1>(Node, 4, AArch64::ZA,
5980 AArch64::MOVA_VG4_4ZMXI);
5983 case Intrinsic::aarch64_sme_readz_horiz_x2: {
5984 if (VT == MVT::nxv16i8) {
5985 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_B_PSEUDO, 14, 2);
5987 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
5988 VT == MVT::nxv8bf16) {
5989 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_H_PSEUDO, 6, 2);
5991 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
5992 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_S_PSEUDO, 2, 2);
5994 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
5995 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_H_D_PSEUDO, 0, 2);
6000 case Intrinsic::aarch64_sme_readz_vert_x2: {
6001 if (VT == MVT::nxv16i8) {
6002 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_B_PSEUDO, 14, 2);
6004 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6005 VT == MVT::nxv8bf16) {
6006 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_H_PSEUDO, 6, 2);
6008 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6009 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_S_PSEUDO, 2, 2);
6011 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6012 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_2ZMI_V_D_PSEUDO, 0, 2);
6017 case Intrinsic::aarch64_sme_readz_horiz_x4: {
6018 if (VT == MVT::nxv16i8) {
6019 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_B_PSEUDO, 12, 4);
6021 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6022 VT == MVT::nxv8bf16) {
6023 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_H_PSEUDO, 4, 4);
6025 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6026 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_S_PSEUDO, 0, 4);
6028 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6029 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_H_D_PSEUDO, 0, 4);
6034 case Intrinsic::aarch64_sme_readz_vert_x4: {
6035 if (VT == MVT::nxv16i8) {
6036 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_B_PSEUDO, 12, 4);
6038 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
6039 VT == MVT::nxv8bf16) {
6040 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_H_PSEUDO, 4, 4);
6042 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
6043 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_S_PSEUDO, 0, 4);
6045 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
6046 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_4ZMI_V_D_PSEUDO, 0, 4);
6051 case Intrinsic::aarch64_sme_readz_x2: {
6052 SelectMultiVectorMoveZ(Node, 2, AArch64::MOVAZ_VG2_2ZMXI_PSEUDO, 7, 1,
6056 case Intrinsic::aarch64_sme_readz_x4: {
6057 SelectMultiVectorMoveZ(Node, 4, AArch64::MOVAZ_VG4_4ZMXI_PSEUDO, 7, 1,
6061 case Intrinsic::swift_async_context_addr: {
6063 SDValue Chain =
Node->getOperand(0);
6064 SDValue CopyFP = CurDAG->getCopyFromReg(Chain,
DL, AArch64::FP, MVT::i64);
6065 SDValue Res = SDValue(
6066 CurDAG->getMachineNode(AArch64::SUBXri,
DL, MVT::i64, CopyFP,
6067 CurDAG->getTargetConstant(8,
DL, MVT::i32),
6068 CurDAG->getTargetConstant(0,
DL, MVT::i32)),
6070 ReplaceUses(SDValue(Node, 0), Res);
6071 ReplaceUses(SDValue(Node, 1), CopyFP.
getValue(1));
6072 CurDAG->RemoveDeadNode(Node);
6074 auto &MF = CurDAG->getMachineFunction();
6075 MF.getFrameInfo().setFrameAddressIsTaken(
true);
6076 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(
true);
6079 case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
6081 Node->getValueType(0),
6082 {AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
6083 AArch64::LUTI2_4ZTZI_S}))
6085 SelectMultiVectorLutiLane(Node, 4,
Opc, 3);
6088 case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
6090 Node->getValueType(0),
6091 {0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
6093 SelectMultiVectorLutiLane(Node, 4,
Opc, 1);
6096 case Intrinsic::aarch64_sme_luti2_lane_zt_x2: {
6098 Node->getValueType(0),
6099 {AArch64::LUTI2_2ZTZI_B, AArch64::LUTI2_2ZTZI_H,
6100 AArch64::LUTI2_2ZTZI_S}))
6102 SelectMultiVectorLutiLane(Node, 2,
Opc, 7);
6105 case Intrinsic::aarch64_sme_luti4_lane_zt_x2: {
6107 Node->getValueType(0),
6108 {AArch64::LUTI4_2ZTZI_B, AArch64::LUTI4_2ZTZI_H,
6109 AArch64::LUTI4_2ZTZI_S}))
6111 SelectMultiVectorLutiLane(Node, 2,
Opc, 3);
6114 case Intrinsic::aarch64_sme_luti4_zt_x4: {
6115 SelectMultiVectorLuti(Node, 4, AArch64::LUTI4_4ZZT2Z, 2);
6118 case Intrinsic::aarch64_sme_luti6_zt_x4: {
6119 SelectMultiVectorLuti(Node, 4, AArch64::LUTI6_4ZT3Z, 3);
6122 case Intrinsic::aarch64_sve_fp8_cvtl1_x2:
6124 Node->getValueType(0),
6125 {AArch64::BF1CVTL_2ZZ_BtoH, AArch64::F1CVTL_2ZZ_BtoH}))
6126 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6128 case Intrinsic::aarch64_sve_fp8_cvtl2_x2:
6130 Node->getValueType(0),
6131 {AArch64::BF2CVTL_2ZZ_BtoH, AArch64::F2CVTL_2ZZ_BtoH}))
6132 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6134 case Intrinsic::aarch64_sve_fp8_cvt1_x2:
6136 Node->getValueType(0),
6137 {AArch64::BF1CVT_2ZZ_BtoH, AArch64::F1CVT_2ZZ_BtoH}))
6138 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6140 case Intrinsic::aarch64_sve_fp8_cvt2_x2:
6142 Node->getValueType(0),
6143 {AArch64::BF2CVT_2ZZ_BtoH, AArch64::F2CVT_2ZZ_BtoH}))
6144 SelectCVTIntrinsicFP8(Node, 2,
Opc);
6146 case Intrinsic::ptrauth_resign_load_relative:
6147 SelectPtrauthResign(Node);
6152 unsigned IntNo =
Node->getConstantOperandVal(0);
6156 case Intrinsic::aarch64_tagp:
6160 case Intrinsic::ptrauth_auth:
6161 SelectPtrauthAuth(Node);
6164 case Intrinsic::ptrauth_resign:
6165 SelectPtrauthResign(Node);
6168 case Intrinsic::ptrauth_auth_with_pc_and_resign:
6169 SelectPtrauthResignWithPC(Node);
6172 case Intrinsic::aarch64_neon_tbl2:
6173 SelectTable(Node, 2,
6174 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two,
6177 case Intrinsic::aarch64_neon_tbl3:
6178 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three
6179 : AArch64::TBLv16i8Three,
6182 case Intrinsic::aarch64_neon_tbl4:
6183 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four
6184 : AArch64::TBLv16i8Four,
6187 case Intrinsic::aarch64_neon_tbx2:
6188 SelectTable(Node, 2,
6189 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two,
6192 case Intrinsic::aarch64_neon_tbx3:
6193 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three
6194 : AArch64::TBXv16i8Three,
6197 case Intrinsic::aarch64_neon_tbx4:
6198 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four
6199 : AArch64::TBXv16i8Four,
6202 case Intrinsic::aarch64_sve_srshl_single_x2:
6204 Node->getValueType(0),
6205 {AArch64::SRSHL_VG2_2ZZ_B, AArch64::SRSHL_VG2_2ZZ_H,
6206 AArch64::SRSHL_VG2_2ZZ_S, AArch64::SRSHL_VG2_2ZZ_D}))
6207 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6209 case Intrinsic::aarch64_sve_srshl_single_x4:
6211 Node->getValueType(0),
6212 {AArch64::SRSHL_VG4_4ZZ_B, AArch64::SRSHL_VG4_4ZZ_H,
6213 AArch64::SRSHL_VG4_4ZZ_S, AArch64::SRSHL_VG4_4ZZ_D}))
6214 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6216 case Intrinsic::aarch64_sme_luti6_lane_x4_x2:
6217 SelectMultiVectorLuti6LaneX4(Node, 2);
6219 case Intrinsic::aarch64_sme_luti6_lane_x4_x3:
6220 SelectMultiVectorLuti6LaneX4(Node, 3);
6222 case Intrinsic::aarch64_sve_urshl_single_x2:
6224 Node->getValueType(0),
6225 {AArch64::URSHL_VG2_2ZZ_B, AArch64::URSHL_VG2_2ZZ_H,
6226 AArch64::URSHL_VG2_2ZZ_S, AArch64::URSHL_VG2_2ZZ_D}))
6227 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6229 case Intrinsic::aarch64_sve_urshl_single_x4:
6231 Node->getValueType(0),
6232 {AArch64::URSHL_VG4_4ZZ_B, AArch64::URSHL_VG4_4ZZ_H,
6233 AArch64::URSHL_VG4_4ZZ_S, AArch64::URSHL_VG4_4ZZ_D}))
6234 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6236 case Intrinsic::aarch64_sve_srshl_x2:
6238 Node->getValueType(0),
6239 {AArch64::SRSHL_VG2_2Z2Z_B, AArch64::SRSHL_VG2_2Z2Z_H,
6240 AArch64::SRSHL_VG2_2Z2Z_S, AArch64::SRSHL_VG2_2Z2Z_D}))
6241 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6243 case Intrinsic::aarch64_sve_srshl_x4:
6245 Node->getValueType(0),
6246 {AArch64::SRSHL_VG4_4Z4Z_B, AArch64::SRSHL_VG4_4Z4Z_H,
6247 AArch64::SRSHL_VG4_4Z4Z_S, AArch64::SRSHL_VG4_4Z4Z_D}))
6248 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6250 case Intrinsic::aarch64_sve_urshl_x2:
6252 Node->getValueType(0),
6253 {AArch64::URSHL_VG2_2Z2Z_B, AArch64::URSHL_VG2_2Z2Z_H,
6254 AArch64::URSHL_VG2_2Z2Z_S, AArch64::URSHL_VG2_2Z2Z_D}))
6255 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6257 case Intrinsic::aarch64_sve_urshl_x4:
6259 Node->getValueType(0),
6260 {AArch64::URSHL_VG4_4Z4Z_B, AArch64::URSHL_VG4_4Z4Z_H,
6261 AArch64::URSHL_VG4_4Z4Z_S, AArch64::URSHL_VG4_4Z4Z_D}))
6262 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6264 case Intrinsic::aarch64_sve_sqdmulh_single_vgx2:
6266 Node->getValueType(0),
6267 {AArch64::SQDMULH_VG2_2ZZ_B, AArch64::SQDMULH_VG2_2ZZ_H,
6268 AArch64::SQDMULH_VG2_2ZZ_S, AArch64::SQDMULH_VG2_2ZZ_D}))
6269 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6271 case Intrinsic::aarch64_sve_sqdmulh_single_vgx4:
6273 Node->getValueType(0),
6274 {AArch64::SQDMULH_VG4_4ZZ_B, AArch64::SQDMULH_VG4_4ZZ_H,
6275 AArch64::SQDMULH_VG4_4ZZ_S, AArch64::SQDMULH_VG4_4ZZ_D}))
6276 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6278 case Intrinsic::aarch64_sve_sqdmulh_vgx2:
6280 Node->getValueType(0),
6281 {AArch64::SQDMULH_VG2_2Z2Z_B, AArch64::SQDMULH_VG2_2Z2Z_H,
6282 AArch64::SQDMULH_VG2_2Z2Z_S, AArch64::SQDMULH_VG2_2Z2Z_D}))
6283 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6285 case Intrinsic::aarch64_sve_sqdmulh_vgx4:
6287 Node->getValueType(0),
6288 {AArch64::SQDMULH_VG4_4Z4Z_B, AArch64::SQDMULH_VG4_4Z4Z_H,
6289 AArch64::SQDMULH_VG4_4Z4Z_S, AArch64::SQDMULH_VG4_4Z4Z_D}))
6290 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6292 case Intrinsic::aarch64_sme_fp8_scale_single_x2:
6294 Node->getValueType(0),
6295 {0, AArch64::FSCALE_2ZZ_H, AArch64::FSCALE_2ZZ_S,
6296 AArch64::FSCALE_2ZZ_D}))
6297 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6299 case Intrinsic::aarch64_sme_fp8_scale_single_x4:
6301 Node->getValueType(0),
6302 {0, AArch64::FSCALE_4ZZ_H, AArch64::FSCALE_4ZZ_S,
6303 AArch64::FSCALE_4ZZ_D}))
6304 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6306 case Intrinsic::aarch64_sme_fp8_scale_x2:
6308 Node->getValueType(0),
6309 {0, AArch64::FSCALE_2Z2Z_H, AArch64::FSCALE_2Z2Z_S,
6310 AArch64::FSCALE_2Z2Z_D}))
6311 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6313 case Intrinsic::aarch64_sme_fp8_scale_x4:
6315 Node->getValueType(0),
6316 {0, AArch64::FSCALE_4Z4Z_H, AArch64::FSCALE_4Z4Z_S,
6317 AArch64::FSCALE_4Z4Z_D}))
6318 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6320 case Intrinsic::aarch64_sve_whilege_x2:
6322 Node->getValueType(0),
6323 {AArch64::WHILEGE_2PXX_B, AArch64::WHILEGE_2PXX_H,
6324 AArch64::WHILEGE_2PXX_S, AArch64::WHILEGE_2PXX_D}))
6325 SelectWhilePair(Node,
Op);
6327 case Intrinsic::aarch64_sve_whilegt_x2:
6329 Node->getValueType(0),
6330 {AArch64::WHILEGT_2PXX_B, AArch64::WHILEGT_2PXX_H,
6331 AArch64::WHILEGT_2PXX_S, AArch64::WHILEGT_2PXX_D}))
6332 SelectWhilePair(Node,
Op);
6334 case Intrinsic::aarch64_sve_whilehi_x2:
6336 Node->getValueType(0),
6337 {AArch64::WHILEHI_2PXX_B, AArch64::WHILEHI_2PXX_H,
6338 AArch64::WHILEHI_2PXX_S, AArch64::WHILEHI_2PXX_D}))
6339 SelectWhilePair(Node,
Op);
6341 case Intrinsic::aarch64_sve_whilehs_x2:
6343 Node->getValueType(0),
6344 {AArch64::WHILEHS_2PXX_B, AArch64::WHILEHS_2PXX_H,
6345 AArch64::WHILEHS_2PXX_S, AArch64::WHILEHS_2PXX_D}))
6346 SelectWhilePair(Node,
Op);
6348 case Intrinsic::aarch64_sve_whilele_x2:
6350 Node->getValueType(0),
6351 {AArch64::WHILELE_2PXX_B, AArch64::WHILELE_2PXX_H,
6352 AArch64::WHILELE_2PXX_S, AArch64::WHILELE_2PXX_D}))
6353 SelectWhilePair(Node,
Op);
6355 case Intrinsic::aarch64_sve_whilelo_x2:
6357 Node->getValueType(0),
6358 {AArch64::WHILELO_2PXX_B, AArch64::WHILELO_2PXX_H,
6359 AArch64::WHILELO_2PXX_S, AArch64::WHILELO_2PXX_D}))
6360 SelectWhilePair(Node,
Op);
6362 case Intrinsic::aarch64_sve_whilels_x2:
6364 Node->getValueType(0),
6365 {AArch64::WHILELS_2PXX_B, AArch64::WHILELS_2PXX_H,
6366 AArch64::WHILELS_2PXX_S, AArch64::WHILELS_2PXX_D}))
6367 SelectWhilePair(Node,
Op);
6369 case Intrinsic::aarch64_sve_whilelt_x2:
6371 Node->getValueType(0),
6372 {AArch64::WHILELT_2PXX_B, AArch64::WHILELT_2PXX_H,
6373 AArch64::WHILELT_2PXX_S, AArch64::WHILELT_2PXX_D}))
6374 SelectWhilePair(Node,
Op);
6376 case Intrinsic::aarch64_sve_smax_single_x2:
6378 Node->getValueType(0),
6379 {AArch64::SMAX_VG2_2ZZ_B, AArch64::SMAX_VG2_2ZZ_H,
6380 AArch64::SMAX_VG2_2ZZ_S, AArch64::SMAX_VG2_2ZZ_D}))
6381 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6383 case Intrinsic::aarch64_sve_umax_single_x2:
6385 Node->getValueType(0),
6386 {AArch64::UMAX_VG2_2ZZ_B, AArch64::UMAX_VG2_2ZZ_H,
6387 AArch64::UMAX_VG2_2ZZ_S, AArch64::UMAX_VG2_2ZZ_D}))
6388 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6390 case Intrinsic::aarch64_sve_fmax_single_x2:
6392 Node->getValueType(0),
6393 {AArch64::BFMAX_VG2_2ZZ_H, AArch64::FMAX_VG2_2ZZ_H,
6394 AArch64::FMAX_VG2_2ZZ_S, AArch64::FMAX_VG2_2ZZ_D}))
6395 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6397 case Intrinsic::aarch64_sve_smax_single_x4:
6399 Node->getValueType(0),
6400 {AArch64::SMAX_VG4_4ZZ_B, AArch64::SMAX_VG4_4ZZ_H,
6401 AArch64::SMAX_VG4_4ZZ_S, AArch64::SMAX_VG4_4ZZ_D}))
6402 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6404 case Intrinsic::aarch64_sve_umax_single_x4:
6406 Node->getValueType(0),
6407 {AArch64::UMAX_VG4_4ZZ_B, AArch64::UMAX_VG4_4ZZ_H,
6408 AArch64::UMAX_VG4_4ZZ_S, AArch64::UMAX_VG4_4ZZ_D}))
6409 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6411 case Intrinsic::aarch64_sve_fmax_single_x4:
6413 Node->getValueType(0),
6414 {AArch64::BFMAX_VG4_4ZZ_H, AArch64::FMAX_VG4_4ZZ_H,
6415 AArch64::FMAX_VG4_4ZZ_S, AArch64::FMAX_VG4_4ZZ_D}))
6416 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6418 case Intrinsic::aarch64_sve_smin_single_x2:
6420 Node->getValueType(0),
6421 {AArch64::SMIN_VG2_2ZZ_B, AArch64::SMIN_VG2_2ZZ_H,
6422 AArch64::SMIN_VG2_2ZZ_S, AArch64::SMIN_VG2_2ZZ_D}))
6423 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6425 case Intrinsic::aarch64_sve_umin_single_x2:
6427 Node->getValueType(0),
6428 {AArch64::UMIN_VG2_2ZZ_B, AArch64::UMIN_VG2_2ZZ_H,
6429 AArch64::UMIN_VG2_2ZZ_S, AArch64::UMIN_VG2_2ZZ_D}))
6430 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6432 case Intrinsic::aarch64_sve_fmin_single_x2:
6434 Node->getValueType(0),
6435 {AArch64::BFMIN_VG2_2ZZ_H, AArch64::FMIN_VG2_2ZZ_H,
6436 AArch64::FMIN_VG2_2ZZ_S, AArch64::FMIN_VG2_2ZZ_D}))
6437 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6439 case Intrinsic::aarch64_sve_smin_single_x4:
6441 Node->getValueType(0),
6442 {AArch64::SMIN_VG4_4ZZ_B, AArch64::SMIN_VG4_4ZZ_H,
6443 AArch64::SMIN_VG4_4ZZ_S, AArch64::SMIN_VG4_4ZZ_D}))
6444 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6446 case Intrinsic::aarch64_sve_umin_single_x4:
6448 Node->getValueType(0),
6449 {AArch64::UMIN_VG4_4ZZ_B, AArch64::UMIN_VG4_4ZZ_H,
6450 AArch64::UMIN_VG4_4ZZ_S, AArch64::UMIN_VG4_4ZZ_D}))
6451 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6453 case Intrinsic::aarch64_sve_fmin_single_x4:
6455 Node->getValueType(0),
6456 {AArch64::BFMIN_VG4_4ZZ_H, AArch64::FMIN_VG4_4ZZ_H,
6457 AArch64::FMIN_VG4_4ZZ_S, AArch64::FMIN_VG4_4ZZ_D}))
6458 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6460 case Intrinsic::aarch64_sve_smax_x2:
6462 Node->getValueType(0),
6463 {AArch64::SMAX_VG2_2Z2Z_B, AArch64::SMAX_VG2_2Z2Z_H,
6464 AArch64::SMAX_VG2_2Z2Z_S, AArch64::SMAX_VG2_2Z2Z_D}))
6465 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6467 case Intrinsic::aarch64_sve_umax_x2:
6469 Node->getValueType(0),
6470 {AArch64::UMAX_VG2_2Z2Z_B, AArch64::UMAX_VG2_2Z2Z_H,
6471 AArch64::UMAX_VG2_2Z2Z_S, AArch64::UMAX_VG2_2Z2Z_D}))
6472 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6474 case Intrinsic::aarch64_sve_fmax_x2:
6476 Node->getValueType(0),
6477 {AArch64::BFMAX_VG2_2Z2Z_H, AArch64::FMAX_VG2_2Z2Z_H,
6478 AArch64::FMAX_VG2_2Z2Z_S, AArch64::FMAX_VG2_2Z2Z_D}))
6479 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6481 case Intrinsic::aarch64_sve_smax_x4:
6483 Node->getValueType(0),
6484 {AArch64::SMAX_VG4_4Z4Z_B, AArch64::SMAX_VG4_4Z4Z_H,
6485 AArch64::SMAX_VG4_4Z4Z_S, AArch64::SMAX_VG4_4Z4Z_D}))
6486 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6488 case Intrinsic::aarch64_sve_umax_x4:
6490 Node->getValueType(0),
6491 {AArch64::UMAX_VG4_4Z4Z_B, AArch64::UMAX_VG4_4Z4Z_H,
6492 AArch64::UMAX_VG4_4Z4Z_S, AArch64::UMAX_VG4_4Z4Z_D}))
6493 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6495 case Intrinsic::aarch64_sve_fmax_x4:
6497 Node->getValueType(0),
6498 {AArch64::BFMAX_VG4_4Z2Z_H, AArch64::FMAX_VG4_4Z4Z_H,
6499 AArch64::FMAX_VG4_4Z4Z_S, AArch64::FMAX_VG4_4Z4Z_D}))
6500 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6502 case Intrinsic::aarch64_sme_famax_x2:
6504 Node->getValueType(0),
6505 {0, AArch64::FAMAX_2Z2Z_H, AArch64::FAMAX_2Z2Z_S,
6506 AArch64::FAMAX_2Z2Z_D}))
6507 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6509 case Intrinsic::aarch64_sme_famax_x4:
6511 Node->getValueType(0),
6512 {0, AArch64::FAMAX_4Z4Z_H, AArch64::FAMAX_4Z4Z_S,
6513 AArch64::FAMAX_4Z4Z_D}))
6514 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6516 case Intrinsic::aarch64_sme_famin_x2:
6518 Node->getValueType(0),
6519 {0, AArch64::FAMIN_2Z2Z_H, AArch64::FAMIN_2Z2Z_S,
6520 AArch64::FAMIN_2Z2Z_D}))
6521 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6523 case Intrinsic::aarch64_sme_famin_x4:
6525 Node->getValueType(0),
6526 {0, AArch64::FAMIN_4Z4Z_H, AArch64::FAMIN_4Z4Z_S,
6527 AArch64::FAMIN_4Z4Z_D}))
6528 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6530 case Intrinsic::aarch64_sve_smin_x2:
6532 Node->getValueType(0),
6533 {AArch64::SMIN_VG2_2Z2Z_B, AArch64::SMIN_VG2_2Z2Z_H,
6534 AArch64::SMIN_VG2_2Z2Z_S, AArch64::SMIN_VG2_2Z2Z_D}))
6535 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6537 case Intrinsic::aarch64_sve_umin_x2:
6539 Node->getValueType(0),
6540 {AArch64::UMIN_VG2_2Z2Z_B, AArch64::UMIN_VG2_2Z2Z_H,
6541 AArch64::UMIN_VG2_2Z2Z_S, AArch64::UMIN_VG2_2Z2Z_D}))
6542 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6544 case Intrinsic::aarch64_sve_fmin_x2:
6546 Node->getValueType(0),
6547 {AArch64::BFMIN_VG2_2Z2Z_H, AArch64::FMIN_VG2_2Z2Z_H,
6548 AArch64::FMIN_VG2_2Z2Z_S, AArch64::FMIN_VG2_2Z2Z_D}))
6549 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6551 case Intrinsic::aarch64_sve_smin_x4:
6553 Node->getValueType(0),
6554 {AArch64::SMIN_VG4_4Z4Z_B, AArch64::SMIN_VG4_4Z4Z_H,
6555 AArch64::SMIN_VG4_4Z4Z_S, AArch64::SMIN_VG4_4Z4Z_D}))
6556 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6558 case Intrinsic::aarch64_sve_umin_x4:
6560 Node->getValueType(0),
6561 {AArch64::UMIN_VG4_4Z4Z_B, AArch64::UMIN_VG4_4Z4Z_H,
6562 AArch64::UMIN_VG4_4Z4Z_S, AArch64::UMIN_VG4_4Z4Z_D}))
6563 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6565 case Intrinsic::aarch64_sve_fmin_x4:
6567 Node->getValueType(0),
6568 {AArch64::BFMIN_VG4_4Z2Z_H, AArch64::FMIN_VG4_4Z4Z_H,
6569 AArch64::FMIN_VG4_4Z4Z_S, AArch64::FMIN_VG4_4Z4Z_D}))
6570 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6572 case Intrinsic::aarch64_sve_fmaxnm_single_x2 :
6574 Node->getValueType(0),
6575 {AArch64::BFMAXNM_VG2_2ZZ_H, AArch64::FMAXNM_VG2_2ZZ_H,
6576 AArch64::FMAXNM_VG2_2ZZ_S, AArch64::FMAXNM_VG2_2ZZ_D}))
6577 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6579 case Intrinsic::aarch64_sve_fmaxnm_single_x4 :
6581 Node->getValueType(0),
6582 {AArch64::BFMAXNM_VG4_4ZZ_H, AArch64::FMAXNM_VG4_4ZZ_H,
6583 AArch64::FMAXNM_VG4_4ZZ_S, AArch64::FMAXNM_VG4_4ZZ_D}))
6584 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6586 case Intrinsic::aarch64_sve_fminnm_single_x2:
6588 Node->getValueType(0),
6589 {AArch64::BFMINNM_VG2_2ZZ_H, AArch64::FMINNM_VG2_2ZZ_H,
6590 AArch64::FMINNM_VG2_2ZZ_S, AArch64::FMINNM_VG2_2ZZ_D}))
6591 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6593 case Intrinsic::aarch64_sve_fminnm_single_x4:
6595 Node->getValueType(0),
6596 {AArch64::BFMINNM_VG4_4ZZ_H, AArch64::FMINNM_VG4_4ZZ_H,
6597 AArch64::FMINNM_VG4_4ZZ_S, AArch64::FMINNM_VG4_4ZZ_D}))
6598 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6600 case Intrinsic::aarch64_sve_fscale_single_x4:
6601 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::BFSCALE_4ZZ);
6603 case Intrinsic::aarch64_sve_fscale_single_x2:
6604 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::BFSCALE_2ZZ);
6606 case Intrinsic::aarch64_sve_fmul_single_x4:
6608 Node->getValueType(0),
6609 {AArch64::BFMUL_4ZZ, AArch64::FMUL_4ZZ_H, AArch64::FMUL_4ZZ_S,
6610 AArch64::FMUL_4ZZ_D}))
6611 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6613 case Intrinsic::aarch64_sve_fmul_single_x2:
6615 Node->getValueType(0),
6616 {AArch64::BFMUL_2ZZ, AArch64::FMUL_2ZZ_H, AArch64::FMUL_2ZZ_S,
6617 AArch64::FMUL_2ZZ_D}))
6618 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6620 case Intrinsic::aarch64_sve_fmaxnm_x2:
6622 Node->getValueType(0),
6623 {AArch64::BFMAXNM_VG2_2Z2Z_H, AArch64::FMAXNM_VG2_2Z2Z_H,
6624 AArch64::FMAXNM_VG2_2Z2Z_S, AArch64::FMAXNM_VG2_2Z2Z_D}))
6625 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6627 case Intrinsic::aarch64_sve_fmaxnm_x4:
6629 Node->getValueType(0),
6630 {AArch64::BFMAXNM_VG4_4Z2Z_H, AArch64::FMAXNM_VG4_4Z4Z_H,
6631 AArch64::FMAXNM_VG4_4Z4Z_S, AArch64::FMAXNM_VG4_4Z4Z_D}))
6632 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6634 case Intrinsic::aarch64_sve_fminnm_x2:
6636 Node->getValueType(0),
6637 {AArch64::BFMINNM_VG2_2Z2Z_H, AArch64::FMINNM_VG2_2Z2Z_H,
6638 AArch64::FMINNM_VG2_2Z2Z_S, AArch64::FMINNM_VG2_2Z2Z_D}))
6639 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6641 case Intrinsic::aarch64_sve_fminnm_x4:
6643 Node->getValueType(0),
6644 {AArch64::BFMINNM_VG4_4Z2Z_H, AArch64::FMINNM_VG4_4Z4Z_H,
6645 AArch64::FMINNM_VG4_4Z4Z_S, AArch64::FMINNM_VG4_4Z4Z_D}))
6646 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6648 case Intrinsic::aarch64_sve_aese_lane_x2:
6649 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESE_2ZZI_B);
6651 case Intrinsic::aarch64_sve_aesd_lane_x2:
6652 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESD_2ZZI_B);
6654 case Intrinsic::aarch64_sve_aesemc_lane_x2:
6655 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESEMC_2ZZI_B);
6657 case Intrinsic::aarch64_sve_aesdimc_lane_x2:
6658 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::AESDIMC_2ZZI_B);
6660 case Intrinsic::aarch64_sve_aese_lane_x4:
6661 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESE_4ZZI_B);
6663 case Intrinsic::aarch64_sve_aesd_lane_x4:
6664 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESD_4ZZI_B);
6666 case Intrinsic::aarch64_sve_aesemc_lane_x4:
6667 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESEMC_4ZZI_B);
6669 case Intrinsic::aarch64_sve_aesdimc_lane_x4:
6670 SelectDestructiveMultiIntrinsic(Node, 4,
false, AArch64::AESDIMC_4ZZI_B);
6672 case Intrinsic::aarch64_sve_pmlal_pair_x2:
6673 SelectDestructiveMultiIntrinsic(Node, 2,
false, AArch64::PMLAL_2ZZZ_Q);
6675 case Intrinsic::aarch64_sve_pmull_pair_x2: {
6679 CurDAG->getMachineNode(AArch64::PMULL_2ZZZ_Q,
DL, MVT::Untyped, Regs);
6680 SDValue SuperReg = SDValue(Res, 0);
6681 for (
unsigned I = 0;
I < 2;
I++)
6682 ReplaceUses(SDValue(Node,
I),
6683 CurDAG->getTargetExtractSubreg(AArch64::zsub0 +
I,
DL, VT,
6685 CurDAG->RemoveDeadNode(Node);
6688 case Intrinsic::aarch64_sve_fscale_x4:
6689 SelectDestructiveMultiIntrinsic(Node, 4,
true, AArch64::BFSCALE_4Z4Z);
6691 case Intrinsic::aarch64_sve_fscale_x2:
6692 SelectDestructiveMultiIntrinsic(Node, 2,
true, AArch64::BFSCALE_2Z2Z);
6694 case Intrinsic::aarch64_sve_fmul_x4:
6696 Node->getValueType(0),
6697 {AArch64::BFMUL_4Z4Z, AArch64::FMUL_4Z4Z_H, AArch64::FMUL_4Z4Z_S,
6698 AArch64::FMUL_4Z4Z_D}))
6699 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op);
6701 case Intrinsic::aarch64_sve_fmul_x2:
6703 Node->getValueType(0),
6704 {AArch64::BFMUL_2Z2Z, AArch64::FMUL_2Z2Z_H, AArch64::FMUL_2Z2Z_S,
6705 AArch64::FMUL_2Z2Z_D}))
6706 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op);
6708 case Intrinsic::aarch64_sve_fcvtzs_x2:
6709 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZS_2Z2Z_StoS);
6711 case Intrinsic::aarch64_sve_scvtf_x2:
6712 SelectCVTIntrinsic(Node, 2, AArch64::SCVTF_2Z2Z_StoS);
6714 case Intrinsic::aarch64_sve_fcvtzu_x2:
6715 SelectCVTIntrinsic(Node, 2, AArch64::FCVTZU_2Z2Z_StoS);
6717 case Intrinsic::aarch64_sve_ucvtf_x2:
6718 SelectCVTIntrinsic(Node, 2, AArch64::UCVTF_2Z2Z_StoS);
6720 case Intrinsic::aarch64_sve_fcvtzs_x4:
6721 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZS_4Z4Z_StoS);
6723 case Intrinsic::aarch64_sve_scvtf_x4:
6724 SelectCVTIntrinsic(Node, 4, AArch64::SCVTF_4Z4Z_StoS);
6726 case Intrinsic::aarch64_sve_fcvtzu_x4:
6727 SelectCVTIntrinsic(Node, 4, AArch64::FCVTZU_4Z4Z_StoS);
6729 case Intrinsic::aarch64_sve_ucvtf_x4:
6730 SelectCVTIntrinsic(Node, 4, AArch64::UCVTF_4Z4Z_StoS);
6732 case Intrinsic::aarch64_sve_fcvt_widen_x2:
6733 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVT_2ZZ_H_S);
6735 case Intrinsic::aarch64_sve_fcvtl_widen_x2:
6736 SelectUnaryMultiIntrinsic(Node, 2,
false, AArch64::FCVTL_2ZZ_H_S);
6738 case Intrinsic::aarch64_sve_sclamp_single_x2:
6740 Node->getValueType(0),
6741 {AArch64::SCLAMP_VG2_2Z2Z_B, AArch64::SCLAMP_VG2_2Z2Z_H,
6742 AArch64::SCLAMP_VG2_2Z2Z_S, AArch64::SCLAMP_VG2_2Z2Z_D}))
6743 SelectClamp(Node, 2,
Op);
6745 case Intrinsic::aarch64_sve_uclamp_single_x2:
6747 Node->getValueType(0),
6748 {AArch64::UCLAMP_VG2_2Z2Z_B, AArch64::UCLAMP_VG2_2Z2Z_H,
6749 AArch64::UCLAMP_VG2_2Z2Z_S, AArch64::UCLAMP_VG2_2Z2Z_D}))
6750 SelectClamp(Node, 2,
Op);
6752 case Intrinsic::aarch64_sve_fclamp_single_x2:
6754 Node->getValueType(0),
6755 {0, AArch64::FCLAMP_VG2_2Z2Z_H, AArch64::FCLAMP_VG2_2Z2Z_S,
6756 AArch64::FCLAMP_VG2_2Z2Z_D}))
6757 SelectClamp(Node, 2,
Op);
6759 case Intrinsic::aarch64_sve_bfclamp_single_x2:
6760 SelectClamp(Node, 2, AArch64::BFCLAMP_VG2_2ZZZ_H);
6762 case Intrinsic::aarch64_sve_sclamp_single_x4:
6764 Node->getValueType(0),
6765 {AArch64::SCLAMP_VG4_4Z4Z_B, AArch64::SCLAMP_VG4_4Z4Z_H,
6766 AArch64::SCLAMP_VG4_4Z4Z_S, AArch64::SCLAMP_VG4_4Z4Z_D}))
6767 SelectClamp(Node, 4,
Op);
6769 case Intrinsic::aarch64_sve_uclamp_single_x4:
6771 Node->getValueType(0),
6772 {AArch64::UCLAMP_VG4_4Z4Z_B, AArch64::UCLAMP_VG4_4Z4Z_H,
6773 AArch64::UCLAMP_VG4_4Z4Z_S, AArch64::UCLAMP_VG4_4Z4Z_D}))
6774 SelectClamp(Node, 4,
Op);
6776 case Intrinsic::aarch64_sve_fclamp_single_x4:
6778 Node->getValueType(0),
6779 {0, AArch64::FCLAMP_VG4_4Z4Z_H, AArch64::FCLAMP_VG4_4Z4Z_S,
6780 AArch64::FCLAMP_VG4_4Z4Z_D}))
6781 SelectClamp(Node, 4,
Op);
6783 case Intrinsic::aarch64_sve_bfclamp_single_x4:
6784 SelectClamp(Node, 4, AArch64::BFCLAMP_VG4_4ZZZ_H);
6786 case Intrinsic::aarch64_sve_add_single_x2:
6788 Node->getValueType(0),
6789 {AArch64::ADD_VG2_2ZZ_B, AArch64::ADD_VG2_2ZZ_H,
6790 AArch64::ADD_VG2_2ZZ_S, AArch64::ADD_VG2_2ZZ_D}))
6791 SelectDestructiveMultiIntrinsic(Node, 2,
false,
Op);
6793 case Intrinsic::aarch64_sve_add_single_x4:
6795 Node->getValueType(0),
6796 {AArch64::ADD_VG4_4ZZ_B, AArch64::ADD_VG4_4ZZ_H,
6797 AArch64::ADD_VG4_4ZZ_S, AArch64::ADD_VG4_4ZZ_D}))
6798 SelectDestructiveMultiIntrinsic(Node, 4,
false,
Op);
6800 case Intrinsic::aarch64_sve_zip_x2:
6802 Node->getValueType(0),
6803 {AArch64::ZIP_VG2_2ZZZ_B, AArch64::ZIP_VG2_2ZZZ_H,
6804 AArch64::ZIP_VG2_2ZZZ_S, AArch64::ZIP_VG2_2ZZZ_D}))
6805 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6807 case Intrinsic::aarch64_sve_zipq_x2:
6808 SelectUnaryMultiIntrinsic(Node, 2,
false,
6809 AArch64::ZIP_VG2_2ZZZ_Q);
6811 case Intrinsic::aarch64_sve_zip_x4:
6813 Node->getValueType(0),
6814 {AArch64::ZIP_VG4_4Z4Z_B, AArch64::ZIP_VG4_4Z4Z_H,
6815 AArch64::ZIP_VG4_4Z4Z_S, AArch64::ZIP_VG4_4Z4Z_D}))
6816 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6818 case Intrinsic::aarch64_sve_zipq_x4:
6819 SelectUnaryMultiIntrinsic(Node, 4,
true,
6820 AArch64::ZIP_VG4_4Z4Z_Q);
6822 case Intrinsic::aarch64_sve_uzp_x2:
6824 Node->getValueType(0),
6825 {AArch64::UZP_VG2_2ZZZ_B, AArch64::UZP_VG2_2ZZZ_H,
6826 AArch64::UZP_VG2_2ZZZ_S, AArch64::UZP_VG2_2ZZZ_D}))
6827 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6829 case Intrinsic::aarch64_sve_uzpq_x2:
6830 SelectUnaryMultiIntrinsic(Node, 2,
false,
6831 AArch64::UZP_VG2_2ZZZ_Q);
6833 case Intrinsic::aarch64_sve_uzp_x4:
6835 Node->getValueType(0),
6836 {AArch64::UZP_VG4_4Z4Z_B, AArch64::UZP_VG4_4Z4Z_H,
6837 AArch64::UZP_VG4_4Z4Z_S, AArch64::UZP_VG4_4Z4Z_D}))
6838 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6840 case Intrinsic::aarch64_sve_uzpq_x4:
6841 SelectUnaryMultiIntrinsic(Node, 4,
true,
6842 AArch64::UZP_VG4_4Z4Z_Q);
6844 case Intrinsic::aarch64_sve_sel_x2:
6846 Node->getValueType(0),
6847 {AArch64::SEL_VG2_2ZC2Z2Z_B, AArch64::SEL_VG2_2ZC2Z2Z_H,
6848 AArch64::SEL_VG2_2ZC2Z2Z_S, AArch64::SEL_VG2_2ZC2Z2Z_D}))
6849 SelectDestructiveMultiIntrinsic(Node, 2,
true,
Op,
true);
6851 case Intrinsic::aarch64_sve_sel_x4:
6853 Node->getValueType(0),
6854 {AArch64::SEL_VG4_4ZC4Z4Z_B, AArch64::SEL_VG4_4ZC4Z4Z_H,
6855 AArch64::SEL_VG4_4ZC4Z4Z_S, AArch64::SEL_VG4_4ZC4Z4Z_D}))
6856 SelectDestructiveMultiIntrinsic(Node, 4,
true,
Op,
true);
6858 case Intrinsic::aarch64_sve_frinta_x2:
6859 SelectFrintFromVT(Node, 2, AArch64::FRINTA_2Z2Z_S);
6861 case Intrinsic::aarch64_sve_frinta_x4:
6862 SelectFrintFromVT(Node, 4, AArch64::FRINTA_4Z4Z_S);
6864 case Intrinsic::aarch64_sve_frintm_x2:
6865 SelectFrintFromVT(Node, 2, AArch64::FRINTM_2Z2Z_S);
6867 case Intrinsic::aarch64_sve_frintm_x4:
6868 SelectFrintFromVT(Node, 4, AArch64::FRINTM_4Z4Z_S);
6870 case Intrinsic::aarch64_sve_frintn_x2:
6871 SelectFrintFromVT(Node, 2, AArch64::FRINTN_2Z2Z_S);
6873 case Intrinsic::aarch64_sve_frintn_x4:
6874 SelectFrintFromVT(Node, 4, AArch64::FRINTN_4Z4Z_S);
6876 case Intrinsic::aarch64_sve_frintp_x2:
6877 SelectFrintFromVT(Node, 2, AArch64::FRINTP_2Z2Z_S);
6879 case Intrinsic::aarch64_sve_frintp_x4:
6880 SelectFrintFromVT(Node, 4, AArch64::FRINTP_4Z4Z_S);
6882 case Intrinsic::aarch64_sve_sunpk_x2:
6884 Node->getValueType(0),
6885 {0, AArch64::SUNPK_VG2_2ZZ_H, AArch64::SUNPK_VG2_2ZZ_S,
6886 AArch64::SUNPK_VG2_2ZZ_D}))
6887 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6889 case Intrinsic::aarch64_sve_uunpk_x2:
6891 Node->getValueType(0),
6892 {0, AArch64::UUNPK_VG2_2ZZ_H, AArch64::UUNPK_VG2_2ZZ_S,
6893 AArch64::UUNPK_VG2_2ZZ_D}))
6894 SelectUnaryMultiIntrinsic(Node, 2,
false,
Op);
6896 case Intrinsic::aarch64_sve_sunpk_x4:
6898 Node->getValueType(0),
6899 {0, AArch64::SUNPK_VG4_4Z2Z_H, AArch64::SUNPK_VG4_4Z2Z_S,
6900 AArch64::SUNPK_VG4_4Z2Z_D}))
6901 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6903 case Intrinsic::aarch64_sve_uunpk_x4:
6905 Node->getValueType(0),
6906 {0, AArch64::UUNPK_VG4_4Z2Z_H, AArch64::UUNPK_VG4_4Z2Z_S,
6907 AArch64::UUNPK_VG4_4Z2Z_D}))
6908 SelectUnaryMultiIntrinsic(Node, 4,
true,
Op);
6910 case Intrinsic::aarch64_sve_pext_x2: {
6912 Node->getValueType(0),
6913 {AArch64::PEXT_2PCI_B, AArch64::PEXT_2PCI_H, AArch64::PEXT_2PCI_S,
6914 AArch64::PEXT_2PCI_D}))
6915 SelectPExtPair(Node,
Op);
6922 unsigned IntNo =
Node->getConstantOperandVal(1);
6923 if (
Node->getNumOperands() >= 3)
6924 VT =
Node->getOperand(2)->getValueType(0);
6928 case Intrinsic::aarch64_neon_st1x2: {
6929 if (VT == MVT::v8i8) {
6930 SelectStore(Node, 2, AArch64::ST1Twov8b);
6932 }
else if (VT == MVT::v16i8) {
6933 SelectStore(Node, 2, AArch64::ST1Twov16b);
6935 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6936 VT == MVT::v4bf16) {
6937 SelectStore(Node, 2, AArch64::ST1Twov4h);
6939 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6940 VT == MVT::v8bf16) {
6941 SelectStore(Node, 2, AArch64::ST1Twov8h);
6943 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6944 SelectStore(Node, 2, AArch64::ST1Twov2s);
6946 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6947 SelectStore(Node, 2, AArch64::ST1Twov4s);
6949 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6950 SelectStore(Node, 2, AArch64::ST1Twov2d);
6952 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6953 SelectStore(Node, 2, AArch64::ST1Twov1d);
6958 case Intrinsic::aarch64_neon_st1x3: {
6959 if (VT == MVT::v8i8) {
6960 SelectStore(Node, 3, AArch64::ST1Threev8b);
6962 }
else if (VT == MVT::v16i8) {
6963 SelectStore(Node, 3, AArch64::ST1Threev16b);
6965 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6966 VT == MVT::v4bf16) {
6967 SelectStore(Node, 3, AArch64::ST1Threev4h);
6969 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
6970 VT == MVT::v8bf16) {
6971 SelectStore(Node, 3, AArch64::ST1Threev8h);
6973 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
6974 SelectStore(Node, 3, AArch64::ST1Threev2s);
6976 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
6977 SelectStore(Node, 3, AArch64::ST1Threev4s);
6979 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
6980 SelectStore(Node, 3, AArch64::ST1Threev2d);
6982 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
6983 SelectStore(Node, 3, AArch64::ST1Threev1d);
6988 case Intrinsic::aarch64_neon_st1x4: {
6989 if (VT == MVT::v8i8) {
6990 SelectStore(Node, 4, AArch64::ST1Fourv8b);
6992 }
else if (VT == MVT::v16i8) {
6993 SelectStore(Node, 4, AArch64::ST1Fourv16b);
6995 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
6996 VT == MVT::v4bf16) {
6997 SelectStore(Node, 4, AArch64::ST1Fourv4h);
6999 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7000 VT == MVT::v8bf16) {
7001 SelectStore(Node, 4, AArch64::ST1Fourv8h);
7003 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7004 SelectStore(Node, 4, AArch64::ST1Fourv2s);
7006 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7007 SelectStore(Node, 4, AArch64::ST1Fourv4s);
7009 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7010 SelectStore(Node, 4, AArch64::ST1Fourv2d);
7012 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7013 SelectStore(Node, 4, AArch64::ST1Fourv1d);
7018 case Intrinsic::aarch64_neon_st2: {
7019 if (VT == MVT::v8i8) {
7020 SelectStore(Node, 2, AArch64::ST2Twov8b);
7022 }
else if (VT == MVT::v16i8) {
7023 SelectStore(Node, 2, AArch64::ST2Twov16b);
7025 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7026 VT == MVT::v4bf16) {
7027 SelectStore(Node, 2, AArch64::ST2Twov4h);
7029 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7030 VT == MVT::v8bf16) {
7031 SelectStore(Node, 2, AArch64::ST2Twov8h);
7033 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7034 SelectStore(Node, 2, AArch64::ST2Twov2s);
7036 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7037 SelectStore(Node, 2, AArch64::ST2Twov4s);
7039 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7040 SelectStore(Node, 2, AArch64::ST2Twov2d);
7042 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7043 SelectStore(Node, 2, AArch64::ST1Twov1d);
7048 case Intrinsic::aarch64_neon_st3: {
7049 if (VT == MVT::v8i8) {
7050 SelectStore(Node, 3, AArch64::ST3Threev8b);
7052 }
else if (VT == MVT::v16i8) {
7053 SelectStore(Node, 3, AArch64::ST3Threev16b);
7055 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7056 VT == MVT::v4bf16) {
7057 SelectStore(Node, 3, AArch64::ST3Threev4h);
7059 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7060 VT == MVT::v8bf16) {
7061 SelectStore(Node, 3, AArch64::ST3Threev8h);
7063 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7064 SelectStore(Node, 3, AArch64::ST3Threev2s);
7066 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7067 SelectStore(Node, 3, AArch64::ST3Threev4s);
7069 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7070 SelectStore(Node, 3, AArch64::ST3Threev2d);
7072 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7073 SelectStore(Node, 3, AArch64::ST1Threev1d);
7078 case Intrinsic::aarch64_neon_st4: {
7079 if (VT == MVT::v8i8) {
7080 SelectStore(Node, 4, AArch64::ST4Fourv8b);
7082 }
else if (VT == MVT::v16i8) {
7083 SelectStore(Node, 4, AArch64::ST4Fourv16b);
7085 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 ||
7086 VT == MVT::v4bf16) {
7087 SelectStore(Node, 4, AArch64::ST4Fourv4h);
7089 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 ||
7090 VT == MVT::v8bf16) {
7091 SelectStore(Node, 4, AArch64::ST4Fourv8h);
7093 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7094 SelectStore(Node, 4, AArch64::ST4Fourv2s);
7096 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7097 SelectStore(Node, 4, AArch64::ST4Fourv4s);
7099 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7100 SelectStore(Node, 4, AArch64::ST4Fourv2d);
7102 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7103 SelectStore(Node, 4, AArch64::ST1Fourv1d);
7108 case Intrinsic::aarch64_neon_st2lane: {
7109 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7110 SelectStoreLane(Node, 2, AArch64::ST2i8);
7112 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7113 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7114 SelectStoreLane(Node, 2, AArch64::ST2i16);
7116 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7118 SelectStoreLane(Node, 2, AArch64::ST2i32);
7120 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7122 SelectStoreLane(Node, 2, AArch64::ST2i64);
7127 case Intrinsic::aarch64_neon_st3lane: {
7128 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7129 SelectStoreLane(Node, 3, AArch64::ST3i8);
7131 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7132 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7133 SelectStoreLane(Node, 3, AArch64::ST3i16);
7135 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7137 SelectStoreLane(Node, 3, AArch64::ST3i32);
7139 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7141 SelectStoreLane(Node, 3, AArch64::ST3i64);
7146 case Intrinsic::aarch64_neon_st4lane: {
7147 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7148 SelectStoreLane(Node, 4, AArch64::ST4i8);
7150 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7151 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7152 SelectStoreLane(Node, 4, AArch64::ST4i16);
7154 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7156 SelectStoreLane(Node, 4, AArch64::ST4i32);
7158 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7160 SelectStoreLane(Node, 4, AArch64::ST4i64);
7165 case Intrinsic::aarch64_sve_st2q: {
7166 SelectPredicatedStore(Node, 2, 4, AArch64::ST2Q, AArch64::ST2Q_IMM);
7169 case Intrinsic::aarch64_sve_st3q: {
7170 SelectPredicatedStore(Node, 3, 4, AArch64::ST3Q, AArch64::ST3Q_IMM);
7173 case Intrinsic::aarch64_sve_st4q: {
7174 SelectPredicatedStore(Node, 4, 4, AArch64::ST4Q, AArch64::ST4Q_IMM);
7177 case Intrinsic::aarch64_sve_st2: {
7178 if (VT == MVT::nxv16i8) {
7179 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM);
7181 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7182 VT == MVT::nxv8bf16) {
7183 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM);
7185 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7186 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM);
7188 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7189 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM);
7194 case Intrinsic::aarch64_sve_st3: {
7195 if (VT == MVT::nxv16i8) {
7196 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM);
7198 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7199 VT == MVT::nxv8bf16) {
7200 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM);
7202 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7203 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM);
7205 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7206 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM);
7211 case Intrinsic::aarch64_sve_st4: {
7212 if (VT == MVT::nxv16i8) {
7213 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM);
7215 }
else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 ||
7216 VT == MVT::nxv8bf16) {
7217 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM);
7219 }
else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) {
7220 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM);
7222 }
else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) {
7223 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM);
7231 case AArch64ISD::LD2post: {
7232 if (VT == MVT::v8i8) {
7233 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0);
7235 }
else if (VT == MVT::v16i8) {
7236 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0);
7238 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7239 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0);
7241 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7242 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0);
7244 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7245 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0);
7247 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7248 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0);
7250 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7251 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7253 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7254 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0);
7259 case AArch64ISD::LD3post: {
7260 if (VT == MVT::v8i8) {
7261 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0);
7263 }
else if (VT == MVT::v16i8) {
7264 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0);
7266 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7267 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0);
7269 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7270 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0);
7272 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7273 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0);
7275 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7276 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0);
7278 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7279 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7281 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7282 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0);
7287 case AArch64ISD::LD4post: {
7288 if (VT == MVT::v8i8) {
7289 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0);
7291 }
else if (VT == MVT::v16i8) {
7292 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0);
7294 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7295 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0);
7297 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7298 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0);
7300 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7301 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0);
7303 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7304 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0);
7306 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7307 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7309 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7310 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0);
7315 case AArch64ISD::LD1x2post: {
7316 if (VT == MVT::v8i8) {
7317 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0);
7319 }
else if (VT == MVT::v16i8) {
7320 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0);
7322 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7323 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0);
7325 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7326 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0);
7328 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7329 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0);
7331 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7332 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0);
7334 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7335 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0);
7337 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7338 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0);
7343 case AArch64ISD::LD1x3post: {
7344 if (VT == MVT::v8i8) {
7345 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0);
7347 }
else if (VT == MVT::v16i8) {
7348 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0);
7350 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7351 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0);
7353 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7354 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0);
7356 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7357 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0);
7359 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7360 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0);
7362 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7363 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0);
7365 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7366 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0);
7371 case AArch64ISD::LD1x4post: {
7372 if (VT == MVT::v8i8) {
7373 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0);
7375 }
else if (VT == MVT::v16i8) {
7376 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0);
7378 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7379 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0);
7381 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7382 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0);
7384 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7385 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0);
7387 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7388 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0);
7390 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7391 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0);
7393 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7394 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0);
7399 case AArch64ISD::LD1DUPpost: {
7400 if (VT == MVT::v8i8) {
7401 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0);
7403 }
else if (VT == MVT::v16i8) {
7404 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0);
7406 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7407 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0);
7409 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7410 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0);
7412 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7413 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0);
7415 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7416 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0);
7418 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7419 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0);
7421 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7422 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0);
7427 case AArch64ISD::LD2DUPpost: {
7428 if (VT == MVT::v8i8) {
7429 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0);
7431 }
else if (VT == MVT::v16i8) {
7432 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0);
7434 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7435 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0);
7437 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7438 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0);
7440 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7441 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0);
7443 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7444 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0);
7446 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7447 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0);
7449 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7450 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0);
7455 case AArch64ISD::LD3DUPpost: {
7456 if (VT == MVT::v8i8) {
7457 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0);
7459 }
else if (VT == MVT::v16i8) {
7460 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0);
7462 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7463 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0);
7465 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7466 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0);
7468 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7469 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0);
7471 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7472 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0);
7474 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7475 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0);
7477 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7478 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0);
7483 case AArch64ISD::LD4DUPpost: {
7484 if (VT == MVT::v8i8) {
7485 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0);
7487 }
else if (VT == MVT::v16i8) {
7488 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0);
7490 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7491 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0);
7493 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7494 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0);
7496 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7497 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0);
7499 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7500 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0);
7502 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7503 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0);
7505 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7506 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0);
7511 case AArch64ISD::LD1LANEpost: {
7512 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7513 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST);
7515 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7516 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7517 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST);
7519 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7521 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST);
7523 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7525 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST);
7530 case AArch64ISD::LD2LANEpost: {
7531 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7532 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST);
7534 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7535 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7536 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST);
7538 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7540 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST);
7542 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7544 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST);
7549 case AArch64ISD::LD3LANEpost: {
7550 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7551 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST);
7553 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7554 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7555 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST);
7557 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7559 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST);
7561 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7563 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST);
7568 case AArch64ISD::LD4LANEpost: {
7569 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7570 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST);
7572 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7573 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7574 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST);
7576 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7578 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST);
7580 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7582 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST);
7587 case AArch64ISD::ST2post: {
7588 VT =
Node->getOperand(1).getValueType();
7589 if (VT == MVT::v8i8) {
7590 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST);
7592 }
else if (VT == MVT::v16i8) {
7593 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST);
7595 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7596 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST);
7598 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7599 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST);
7601 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7602 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST);
7604 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7605 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST);
7607 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7608 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST);
7610 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7611 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7616 case AArch64ISD::ST3post: {
7617 VT =
Node->getOperand(1).getValueType();
7618 if (VT == MVT::v8i8) {
7619 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST);
7621 }
else if (VT == MVT::v16i8) {
7622 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST);
7624 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7625 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST);
7627 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7628 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST);
7630 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7631 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST);
7633 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7634 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST);
7636 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7637 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST);
7639 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7640 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7645 case AArch64ISD::ST4post: {
7646 VT =
Node->getOperand(1).getValueType();
7647 if (VT == MVT::v8i8) {
7648 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST);
7650 }
else if (VT == MVT::v16i8) {
7651 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST);
7653 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7654 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST);
7656 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7657 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST);
7659 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7660 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST);
7662 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7663 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST);
7665 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7666 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST);
7668 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7669 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7674 case AArch64ISD::ST1x2post: {
7675 VT =
Node->getOperand(1).getValueType();
7676 if (VT == MVT::v8i8) {
7677 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST);
7679 }
else if (VT == MVT::v16i8) {
7680 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST);
7682 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7683 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST);
7685 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7686 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST);
7688 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7689 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST);
7691 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7692 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST);
7694 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7695 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST);
7697 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7698 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST);
7703 case AArch64ISD::ST1x3post: {
7704 VT =
Node->getOperand(1).getValueType();
7705 if (VT == MVT::v8i8) {
7706 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST);
7708 }
else if (VT == MVT::v16i8) {
7709 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST);
7711 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7712 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST);
7714 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) {
7715 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST);
7717 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7718 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST);
7720 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7721 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST);
7723 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7724 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST);
7726 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7727 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST);
7732 case AArch64ISD::ST1x4post: {
7733 VT =
Node->getOperand(1).getValueType();
7734 if (VT == MVT::v8i8) {
7735 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST);
7737 }
else if (VT == MVT::v16i8) {
7738 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST);
7740 }
else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) {
7741 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST);
7743 }
else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) {
7744 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST);
7746 }
else if (VT == MVT::v2i32 || VT == MVT::v2f32) {
7747 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST);
7749 }
else if (VT == MVT::v4i32 || VT == MVT::v4f32) {
7750 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST);
7752 }
else if (VT == MVT::v1i64 || VT == MVT::v1f64) {
7753 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST);
7755 }
else if (VT == MVT::v2i64 || VT == MVT::v2f64) {
7756 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST);
7761 case AArch64ISD::ST2LANEpost: {
7762 VT =
Node->getOperand(1).getValueType();
7763 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7764 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST);
7766 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7767 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7768 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST);
7770 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7772 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST);
7774 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7776 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST);
7781 case AArch64ISD::ST3LANEpost: {
7782 VT =
Node->getOperand(1).getValueType();
7783 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7784 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST);
7786 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7787 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7788 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST);
7790 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7792 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST);
7794 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7796 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST);
7801 case AArch64ISD::ST4LANEpost: {
7802 VT =
Node->getOperand(1).getValueType();
7803 if (VT == MVT::v16i8 || VT == MVT::v8i8) {
7804 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST);
7806 }
else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 ||
7807 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) {
7808 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST);
7810 }
else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
7812 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST);
7814 }
else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
7816 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST);
7831 return new AArch64DAGToDAGISelLegacy(TM, OptLevel);
7843 assert(NumVec > 0 && NumVec < 5 &&
"Invalid number of vectors.");
7847 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 &&
7848 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1)
7870 return MemIntr->getMemoryVT();
7877 DataVT =
Load->getValueType(0);
7879 DataVT =
Load->getValueType(0);
7881 DataVT =
Store->getValue().getValueType();
7883 DataVT =
Store->getValue().getValueType();
7890 const unsigned Opcode = Root->
getOpcode();
7894 case AArch64ISD::LD1_MERGE_ZERO:
7895 case AArch64ISD::LD1S_MERGE_ZERO:
7896 case AArch64ISD::LDNF1_MERGE_ZERO:
7897 case AArch64ISD::LDNF1S_MERGE_ZERO:
7899 case AArch64ISD::ST1_PRED:
7911 case Intrinsic::aarch64_sme_ldr:
7912 case Intrinsic::aarch64_sme_str:
7913 return MVT::nxv16i8;
7914 case Intrinsic::aarch64_sve_prf:
7919 case Intrinsic::aarch64_sve_ld2_sret:
7920 case Intrinsic::aarch64_sve_ld2q_sret:
7923 case Intrinsic::aarch64_sve_st2q:
7926 case Intrinsic::aarch64_sve_ld3_sret:
7927 case Intrinsic::aarch64_sve_ld3q_sret:
7930 case Intrinsic::aarch64_sve_st3q:
7933 case Intrinsic::aarch64_sve_ld4_sret:
7934 case Intrinsic::aarch64_sve_ld4q_sret:
7937 case Intrinsic::aarch64_sve_st4q:
7940 case Intrinsic::aarch64_sve_ld1_pn_x2:
7941 case Intrinsic::aarch64_sve_ldnt1_pn_x2:
7944 case Intrinsic::aarch64_sve_ld1_pn_x4:
7945 case Intrinsic::aarch64_sve_ldnt1_pn_x4:
7948 case Intrinsic::aarch64_sve_st1_pn_x2:
7949 case Intrinsic::aarch64_sve_stnt1_pn_x2:
7952 case Intrinsic::aarch64_sve_st1_pn_x4:
7953 case Intrinsic::aarch64_sve_stnt1_pn_x4:
7956 case Intrinsic::aarch64_sve_ld1udq:
7957 case Intrinsic::aarch64_sve_st1dq:
7958 return EVT(MVT::nxv1i64);
7959 case Intrinsic::aarch64_sve_ld1uwq:
7960 case Intrinsic::aarch64_sve_st1wq:
7961 return EVT(MVT::nxv1i32);
7968template <
int64_t Min,
int64_t Max>
7969bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue
N,
7973 const DataLayout &
DL = CurDAG->getDataLayout();
7974 const MachineFrameInfo &MFI = MF->getFrameInfo();
7982 OffImm = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
7995 SDValue VScale =
N.getOperand(1);
7996 int64_t MulImm = std::numeric_limits<int64_t>::max();
8000 int64_t ByteOffset =
C->getSExtValue();
8001 const auto KnownVScale =
8004 if (!KnownVScale || ByteOffset % KnownVScale != 0)
8007 MulImm = ByteOffset / KnownVScale;
8014 if ((MulImm % MemWidthBytes) != 0)
8017 int64_t
Offset = MulImm / MemWidthBytes;
8021 Base =
N.getOperand(0);
8030 OffImm = CurDAG->getTargetConstant(
Offset, SDLoc(
N), MVT::i64);
8036bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(SDValue
N,
unsigned Scale,
8043 const SDValue
LHS =
N.getOperand(0);
8044 const SDValue
RHS =
N.getOperand(1);
8055 int64_t ImmOff =
C->getSExtValue();
8056 unsigned Size = 1 << Scale;
8065 Offset = CurDAG->getTargetConstant(ImmOff >> Scale,
DL, MVT::i64);
8067 SDNode *
MI = CurDAG->getMachineNode(AArch64::MOVi64imm,
DL, MVT::i64,
Ops);
8076 const SDValue ShiftRHS =
RHS.getOperand(1);
8078 if (
C->getZExtValue() == Scale) {
8087bool AArch64DAGToDAGISel::SelectAllActivePredicate(SDValue
N) {
8088 const AArch64TargetLowering *TLI =
8089 static_cast<const AArch64TargetLowering *
>(getTargetLowering());
8094bool AArch64DAGToDAGISel::SelectAnyPredicate(SDValue
N) {
8095 return N.getValueType().isScalableVectorOf(MVT::i1);
8098bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue
N,
unsigned MaxSize,
8101 auto MatchConstantOffset = [&](SDValue CN) -> SDValue {
8103 int64_t ImmOff =
C->getSExtValue();
8104 if ((ImmOff > 0 && ImmOff <= MaxSize && (ImmOff % Scale == 0)))
8105 return CurDAG->getTargetConstant(ImmOff / Scale, SDLoc(
N), MVT::i64);
8110 if (SDValue
C = MatchConstantOffset(
N)) {
8117 if (CurDAG->isBaseWithConstantOffset(
N)) {
8118 if (SDValue
C = MatchConstantOffset(
N.getOperand(1))) {
8119 Base =
N.getOperand(0);
8127 Offset = CurDAG->getTargetConstant(0, SDLoc(
N), MVT::i64);
8131bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *
P, SDValue
N,
8169 if (CN->getAPIntValue().uge(LowerBound) &&
8170 CN->getAPIntValue().ult(UpperBound)) {
8172 Imm = CurDAG->getTargetConstant(CN->getZExtValue(),
DL,
N.getValueType());
8180template <
bool MatchCBB>
8181bool AArch64DAGToDAGISel::SelectCmpBranchExtOperand(SDValue
N, SDValue &
Reg,
8187 if (Ty != (MatchCBB ? MVT::i8 : MVT::i16))
8189 Reg =
N.getOperand(0);
8191 SDLoc(
N), MVT::i32);
8199 Reg =
N.getOperand(0);
8219bool AArch64DAGToDAGISel::tryFoldCselToFMaxMin(SDNode *
N) {
8220 EVT VT =
N->getValueType(0);
8226 SDValue TVal =
N->getOperand(0);
8227 SDValue FVal =
N->getOperand(1);
8228 SDValue CCVal =
N->getOperand(2);
8229 SDValue
Cmp =
N->getOperand(3);
8231 if (
Cmp.getOpcode() != AArch64ISD::FCMP)
8238 SDValue CmpLHS =
Cmp.getOperand(0);
8239 SDValue CmpRHS =
Cmp.getOperand(1);
8240 unsigned CondCode = CC->getZExtValue();
8243 auto getOpc = [](EVT VT,
bool isMax) ->
unsigned {
8245 return isMax ? AArch64::FMAXNMHrr : AArch64::FMINNMHrr;
8246 else if (VT == MVT::f32)
8247 return isMax ? AArch64::FMAXNMSrr : AArch64::FMINNMSrr;
8248 else if (VT == MVT::f64)
8249 return isMax ? AArch64::FMAXNMDrr : AArch64::FMINNMDrr;
8257 if (TVal == CmpLHS && FVal == CmpRHS)
8262 if (TVal == CmpLHS && FVal == CmpRHS)
8271 unsigned Opc = getOpc(VT, isMax);
8277 if (!CFP || CFP->getValueAPF().isNaN())
8282 if (CFP->isZero() && !
N->getFlags().hasNoSignedZeros())
8288 if (!CurDAG->isKnownNeverSNaN(CmpLHS))
8291 CurDAG->SelectNodeTo(
N,
Opc, VT, CmpLHS, CmpRHS);
8295void AArch64DAGToDAGISel::PreprocessISelDAG() {
8296 bool MadeChange =
false;
8302 switch (
N.getOpcode()) {
8304 EVT ScalarTy =
N.getValueType(0).getVectorElementType();
8305 if ((ScalarTy == MVT::i32 || ScalarTy == MVT::i64) &&
8306 ScalarTy ==
N.getOperand(0).getValueType())
8311 case AArch64ISD::VSHL: {
8314 EVT VT =
N.getValueType(0);
8315 SDValue
A,
B,
C =
N.getOperand(1);
8321 if (
B.getOpcode() ==
A.getOpcode())
8324 SDValue
SHL = CurDAG->getNode(AArch64ISD::VSHL,
DL, VT,
A,
C);
8334 LLVM_DEBUG(
dbgs() <<
"AArch64 DAG preprocessing replacing:\nOld: ");
8340 CurDAG->ReplaceAllUsesOfValueWith(SDValue(&
N, 0), Result);
8346 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 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.
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.
uint64_t getScalarSizeInBits() const
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
static MVT getVectorVT(MVT VT, unsigned NumElements)
bool hasScalableStackID(int ObjectIdx) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, 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
@ 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)
bool sd_match(SDNode *N, const SelectionDAG *DAG, Pattern &&P)
auto m_SExt(const Opnd &Op)
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.
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.
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.