44#define AARCH64_EXPAND_PSEUDO_NAME "AArch64 pseudo instruction expansion pass"
48class AArch64ExpandPseudoImpl {
62 unsigned ContiguousOpc,
unsigned StridedOpc);
75 unsigned LdarOp,
unsigned StlrOp,
unsigned CmpOp,
76 unsigned ExtendImm,
unsigned ZeroReg,
94 struct ConditionalBlocks {
123char AArch64ExpandPseudoLegacy::ID = 0;
135 assert(MO.isReg() && MO.getReg());
152 uint64_t
Imm =
MI.getOperand(1).getImm();
154 if (DstReg == AArch64::XZR || DstReg == AArch64::WZR) {
157 MI.eraseFromParent();
165 SmallVector<MachineInstrBuilder, 4> MIBS;
167 bool LastItem = std::next(
I) ==
E;
172 case AArch64::ORRWri:
173 case AArch64::ORRXri:
174 case AArch64::ANDXri:
175 case AArch64::EORXri:
178 .
add(
MI.getOperand(0))
179 .
addReg(BitSize == 32 ? AArch64::WZR : AArch64::XZR)
183 bool DstIsDead =
MI.getOperand(0).isDead();
186 .
addReg(DstReg, RegState::Define |
193 case AArch64::EONXrs:
194 case AArch64::EORXrs:
195 case AArch64::ORRWrs:
196 case AArch64::ORRXrs: {
198 bool DstIsDead =
MI.getOperand(0).isDead();
201 .
addReg(DstReg, RegState::Define |
208 case AArch64::MOVNWi:
209 case AArch64::MOVNXi:
210 case AArch64::MOVZWi:
211 case AArch64::MOVZXi: {
212 bool DstIsDead =
MI.getOperand(0).isDead();
214 .
addReg(DstReg, RegState::Define |
220 case AArch64::MOVKWi:
221 case AArch64::MOVKXi: {
223 bool DstIsDead =
MI.getOperand(0).isDead();
236 MI.eraseFromParent();
240bool AArch64ExpandPseudoImpl::expandCMP_SWAP(
242 unsigned StlrOp,
unsigned CmpOp,
unsigned ExtendImm,
unsigned ZeroReg,
246 const MachineOperand &Dest =
MI.getOperand(0);
247 Register StatusReg =
MI.getOperand(1).getReg();
248 bool StatusDead =
MI.getOperand(1).isDead();
251 assert(!
MI.getOperand(2).isUndef() &&
"cannot handle undef");
253 Register DesiredReg =
MI.getOperand(3).getReg();
262 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
263 MF->
insert(++StoreBB->getIterator(), DoneBB);
271 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::MOVZWi), StatusReg)
275 BuildMI(LoadCmpBB, MIMD,
TII->get(CmpOp), ZeroReg)
279 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::Bcc))
282 .
addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
283 LoadCmpBB->addSuccessor(DoneBB);
284 LoadCmpBB->addSuccessor(StoreBB);
289 BuildMI(StoreBB, MIMD,
TII->get(StlrOp), StatusReg)
292 BuildMI(StoreBB, MIMD,
TII->get(AArch64::CBNZW))
295 StoreBB->addSuccessor(LoadCmpBB);
296 StoreBB->addSuccessor(DoneBB);
298 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
299 DoneBB->transferSuccessors(&
MBB);
304 MI.eraseFromParent();
307 LivePhysRegs LiveRegs;
312 StoreBB->clearLiveIns();
314 LoadCmpBB->clearLiveIns();
320bool AArch64ExpandPseudoImpl::expandCMP_SWAP_128(
325 MachineOperand &DestLo =
MI.getOperand(0);
326 MachineOperand &DestHi =
MI.getOperand(1);
327 Register StatusReg =
MI.getOperand(2).getReg();
328 bool StatusDead =
MI.getOperand(2).isDead();
331 assert(!
MI.getOperand(3).isUndef() &&
"cannot handle undef");
333 Register DesiredLoReg =
MI.getOperand(4).getReg();
334 Register DesiredHiReg =
MI.getOperand(5).getReg();
335 Register NewLoReg =
MI.getOperand(6).getReg();
336 Register NewHiReg =
MI.getOperand(7).getReg();
338 unsigned LdxpOp, StxpOp;
340 switch (
MI.getOpcode()) {
341 case AArch64::CMP_SWAP_128_MONOTONIC:
342 LdxpOp = AArch64::LDXPX;
343 StxpOp = AArch64::STXPX;
345 case AArch64::CMP_SWAP_128_RELEASE:
346 LdxpOp = AArch64::LDXPX;
347 StxpOp = AArch64::STLXPX;
349 case AArch64::CMP_SWAP_128_ACQUIRE:
350 LdxpOp = AArch64::LDAXPX;
351 StxpOp = AArch64::STXPX;
353 case AArch64::CMP_SWAP_128:
354 LdxpOp = AArch64::LDAXPX;
355 StxpOp = AArch64::STLXPX;
368 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
369 MF->
insert(++StoreBB->getIterator(), FailBB);
370 MF->
insert(++FailBB->getIterator(), DoneBB);
381 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::SUBSXrs), AArch64::XZR)
385 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CSINCWr), StatusReg)
389 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::SUBSXrs), AArch64::XZR)
393 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CSINCWr), StatusReg)
394 .
addUse(StatusReg, RegState::Kill)
395 .
addUse(StatusReg, RegState::Kill)
397 BuildMI(LoadCmpBB, MIMD,
TII->get(AArch64::CBNZW))
400 LoadCmpBB->addSuccessor(FailBB);
401 LoadCmpBB->addSuccessor(StoreBB);
406 BuildMI(StoreBB, MIMD,
TII->get(StxpOp), StatusReg)
410 BuildMI(StoreBB, MIMD,
TII->get(AArch64::CBNZW))
414 StoreBB->addSuccessor(LoadCmpBB);
415 StoreBB->addSuccessor(DoneBB);
420 BuildMI(FailBB, MIMD,
TII->get(StxpOp), StatusReg)
424 BuildMI(FailBB, MIMD,
TII->get(AArch64::CBNZW))
427 FailBB->addSuccessor(LoadCmpBB);
428 FailBB->addSuccessor(DoneBB);
430 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
431 DoneBB->transferSuccessors(&
MBB);
436 MI.eraseFromParent();
439 LivePhysRegs LiveRegs;
446 FailBB->clearLiveIns();
448 StoreBB->clearLiveIns();
450 LoadCmpBB->clearLiveIns();
494bool AArch64ExpandPseudoImpl::expand_DestructiveOp(
495 MachineInstr &
MI, MachineBasicBlock &
MBB,
502 bool DstIsDead =
MI.getOperand(0).isDead();
504 unsigned PredIdx, DOPIdx, SrcIdx, Src2Idx;
509 if (DstReg ==
MI.getOperand(3).getReg()) {
511 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(1, 3, 2);
518 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(1, 2, 3);
521 std::tie(PredIdx, DOPIdx, SrcIdx) = std::make_tuple(2, 3, 3);
524 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 2, 3, 4);
525 if (DstReg ==
MI.getOperand(3).getReg()) {
527 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 3, 4, 2);
529 }
else if (DstReg ==
MI.getOperand(4).getReg()) {
531 std::tie(PredIdx, DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 4, 3, 2);
538 std::tie(DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 1, 2);
541 std::tie(DOPIdx, SrcIdx, Src2Idx) = std::make_tuple(1, 2, 3);
550 bool DOPRegIsUnique =
false;
553 DOPRegIsUnique = DstReg !=
MI.getOperand(SrcIdx).getReg();
558 DstReg !=
MI.getOperand(DOPIdx).getReg() ||
559 MI.getOperand(DOPIdx).getReg() !=
MI.getOperand(SrcIdx).getReg();
565 DOPRegIsUnique =
true;
569 DstReg !=
MI.getOperand(DOPIdx).getReg() ||
570 (
MI.getOperand(DOPIdx).
getReg() !=
MI.getOperand(SrcIdx).getReg() &&
571 MI.getOperand(DOPIdx).getReg() !=
MI.getOperand(Src2Idx).getReg());
587 uint64_t ElementSize =
TII->getElementSizeForOpcode(Opcode);
588 unsigned MovPrfx, LSLZero, MovPrfxZero;
589 switch (ElementSize) {
592 MovPrfx = AArch64::MOVPRFX_ZZ;
593 LSLZero = AArch64::LSL_ZPmI_B;
594 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_B;
597 MovPrfx = AArch64::MOVPRFX_ZZ;
598 LSLZero = AArch64::LSL_ZPmI_H;
599 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_H;
602 MovPrfx = AArch64::MOVPRFX_ZZ;
603 LSLZero = AArch64::LSL_ZPmI_S;
604 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_S;
607 MovPrfx = AArch64::MOVPRFX_ZZ;
608 LSLZero = AArch64::LSL_ZPmI_D;
609 MovPrfxZero = AArch64::MOVPRFX_ZPzZ_D;
621 MachineInstrBuilder PRFX, DOP;
628 "The destructive operand should be unique");
630 "This instruction is unpredicated");
634 .
addReg(DstReg, RegState::Define)
635 .
addReg(
MI.getOperand(PredIdx).getReg())
636 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState);
650 .
addReg(DstReg, RegState::Define)
651 .
add(
MI.getOperand(PredIdx))
655 }
else if (DstReg !=
MI.getOperand(DOPIdx).getReg()) {
656 assert(DOPRegIsUnique &&
"The destructive operand should be unique");
658 .
addReg(DstReg, RegState::Define)
659 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState);
669 DOPRegState = DOPRegState | RegState::Kill;
673 DOP.
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
674 .
add(
MI.getOperand(PredIdx))
675 .
add(
MI.getOperand(SrcIdx));
681 DOP.
add(
MI.getOperand(PredIdx))
682 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
683 .
add(
MI.getOperand(SrcIdx));
686 DOP.
add(
MI.getOperand(PredIdx))
687 .
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
688 .
add(
MI.getOperand(SrcIdx))
689 .
add(
MI.getOperand(Src2Idx));
693 DOP.
addReg(
MI.getOperand(DOPIdx).getReg(), DOPRegState)
694 .
add(
MI.getOperand(SrcIdx))
695 .
add(
MI.getOperand(Src2Idx));
700 transferImpOps(
MI, PRFX, DOP);
703 transferImpOps(
MI, DOP, DOP);
705 MI.eraseFromParent();
709bool AArch64ExpandPseudoImpl::expandSVEBitwisePseudo(
710 MachineInstr &
MI, MachineBasicBlock &
MBB,
712 MachineInstrBuilder PRFX, DOP;
713 const unsigned Opcode =
MI.getOpcode();
714 const MachineOperand &Op0 =
MI.getOperand(0);
715 const MachineOperand *Op1 = &
MI.getOperand(1);
716 const MachineOperand *Op2 = &
MI.getOperand(2);
719 if (DOPReg == Op2->
getReg()) {
722 }
else if (DOPReg != Op1->
getReg()) {
731 Opcode == AArch64::NAND_ZZZ));
734 assert((DOPReg == Op1->
getReg() || PRFX) &&
"invalid expansion");
743 case AArch64::EON_ZZZ:
746 .
addReg(DOPReg, DOPRegState)
750 case AArch64::NAND_ZZZ:
753 .
addReg(DOPReg, DOPRegState)
757 case AArch64::NOR_ZZZ:
760 .
addReg(DOPReg, DOPRegState)
767 transferImpOps(
MI, PRFX, DOP);
770 transferImpOps(
MI, DOP, DOP);
773 MI.eraseFromParent();
777bool AArch64ExpandPseudoImpl::expandSetTagLoop(
783 Register AddressReg =
MI.getOperand(1).getReg();
787 bool ZeroData =
MI.getOpcode() == AArch64::STZGloop_wback;
788 const unsigned OpCode1 =
789 ZeroData ? AArch64::STZGPostIndex : AArch64::STGPostIndex;
790 const unsigned OpCode2 =
791 ZeroData ? AArch64::STZ2GPostIndex : AArch64::ST2GPostIndex;
793 unsigned Size =
MI.getOperand(2).getImm();
795 if (
Size % (16 * 2) != 0) {
811 MF->
insert(++LoopBB->getIterator(), DoneBB);
828 .
addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
830 LoopBB->addSuccessor(LoopBB);
831 LoopBB->addSuccessor(DoneBB);
833 DoneBB->splice(DoneBB->end(), &
MBB,
MI,
MBB.
end());
834 DoneBB->transferSuccessors(&
MBB);
839 MI.eraseFromParent();
841 LivePhysRegs LiveRegs;
846 LoopBB->clearLiveIns();
848 DoneBB->clearLiveIns();
854bool AArch64ExpandPseudoImpl::expandSVESpillFill(
857 assert((
Opc == AArch64::LDR_ZXI ||
Opc == AArch64::STR_ZXI ||
858 Opc == AArch64::LDR_PXI ||
Opc == AArch64::STR_PXI) &&
859 "Unexpected opcode");
862 unsigned sub0 = (
Opc == AArch64::LDR_ZXI ||
Opc == AArch64::STR_ZXI)
865 const TargetRegisterInfo *
TRI =
869 int ImmOffset =
MI.getOperand(2).getImm() +
Offset;
870 bool Kill = (
Offset + 1 ==
N) ?
MI.getOperand(1).isKill() :
false;
871 assert(ImmOffset >= -256 && ImmOffset < 256 &&
872 "Immediate spill offset out of range");
879 MI.eraseFromParent();
890 unsigned RegMaskStartIdx) {
899 while (!
MBBI->getOperand(RegMaskStartIdx).isRegMask()) {
901 assert(MOP.
isReg() &&
"can only add register operands");
903 MOP.
getReg(),
false,
true,
false,
909 Call->addOperand(MO);
920 unsigned RegMaskStartIdx) {
921 unsigned Opc = CallTarget.
isGlobal() ? AArch64::BL : AArch64::BLR;
924 "invalid operand for regular call");
928bool AArch64ExpandPseudoImpl::expandCALL_RVMARKER(
936 MachineOperand &RVTarget =
MI.getOperand(0);
937 bool DoEmitMarker =
MI.getOperand(1).getImm();
938 assert(RVTarget.
isGlobal() &&
"invalid operand for attached call");
940 MachineInstr *OriginalCall =
nullptr;
942 if (
MI.getOpcode() == AArch64::BLRA_RVMARKER) {
944 const MachineOperand &CallTarget =
MI.getOperand(2);
945 const MachineOperand &
Key =
MI.getOperand(3);
946 const MachineOperand &IntDisc =
MI.getOperand(4);
947 const MachineOperand &AddrDisc =
MI.getOperand(5);
951 "Invalid auth call key");
953 MachineOperand
Ops[] = {CallTarget,
Key, IntDisc, AddrDisc};
958 assert(
MI.getOpcode() == AArch64::BLR_RVMARKER &&
"unknown rvmarker MI");
966 .
addReg(AArch64::FP, RegState::Define)
975 if (
MI.shouldUpdateAdditionalCallInfo())
978 MI.eraseFromParent();
980 std::next(RVCall->getIterator()));
984bool AArch64ExpandPseudoImpl::expandCALL_BTI(MachineBasicBlock &
MBB,
1004 if (
MI.shouldUpdateAdditionalCallInfo())
1007 MI.eraseFromParent();
1012bool AArch64ExpandPseudoImpl::expandStoreSwiftAsyncContext(
1020 if (STI.getTargetTriple().getArchName() !=
"arm64e") {
1037 unsigned Opc =
Offset >= 0 ? AArch64::ADDXri : AArch64::SUBXri;
1069bool AArch64ExpandPseudoImpl::expandSTSHHAtomicStore(
1071 MachineInstr &
MI = *
MBBI;
1074 unsigned Order =
MI.getOperand(2).getImm();
1075 unsigned Policy =
MI.getOperand(3).getImm();
1076 unsigned Size =
MI.getOperand(4).getImm();
1078 bool IsRelaxed = Order == 0;
1079 unsigned StoreOpc = 0;
1084 StoreOpc = IsRelaxed ? AArch64::STRBBui : AArch64::STLRB;
1087 StoreOpc = IsRelaxed ? AArch64::STRHHui : AArch64::STLRH;
1090 StoreOpc = IsRelaxed ? AArch64::STRWui : AArch64::STLRW;
1093 StoreOpc = IsRelaxed ? AArch64::STRXui : AArch64::STLRX;
1108 const TargetRegisterInfo *
TRI =
1110 Register SubReg =
TRI->getSubReg(ValReg, AArch64::sub_32);
1117 .
add(
MI.getOperand(1));
1125 transferImpOps(
MI, Store, Store);
1130 MI.eraseFromParent();
1134AArch64ExpandPseudoImpl::ConditionalBlocks
1135AArch64ExpandPseudoImpl::expandConditionalPseudo(
1137 MachineInstrBuilder &Branch) {
1140 "Unexpected unreachable in block");
1146 MachineInstr &PrevMI = *std::prev(
MBBI);
1147 MachineBasicBlock *CondBB =
MBB.
splitAt(PrevMI,
true);
1148 MachineBasicBlock *EndBB =
1149 std::next(
MBBI) == CondBB->
end()
1162 return {*CondBB, *EndBB};
1166AArch64ExpandPseudoImpl::expandRestoreZASave(MachineBasicBlock &
MBB,
1168 MachineInstr &
MI = *
MBBI;
1172 MachineInstrBuilder
Branch =
1175 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Branch);
1177 MachineInstrBuilder MIB =
1180 for (
unsigned I = 2;
I <
MI.getNumOperands(); ++
I)
1181 MIB.
add(
MI.getOperand(
I));
1183 MIB.
addReg(
MI.getOperand(1).getReg(), RegState::Implicit);
1185 MI.eraseFromParent();
1196 [[maybe_unused]]
auto *RI =
MBB.getParent()->getSubtarget().getRegisterInfo();
1202 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Branch);
1207 for (
unsigned I = 3;
I <
MI.getNumOperands(); ++
I)
1208 MIB.
add(
MI.getOperand(
I));
1211 .
addImm(AArch64SysReg::TPIDR2_EL0)
1213 bool ZeroZA =
MI.getOperand(1).getImm() != 0;
1214 bool ZeroZT0 =
MI.getOperand(2).getImm() != 0;
1216 assert(
MI.definesRegister(AArch64::ZAB0, RI) &&
"should define ZA!");
1222 assert(
MI.definesRegister(AArch64::ZT0, RI) &&
"should define ZT0!");
1227 MI.eraseFromParent();
1232AArch64ExpandPseudoImpl::expandCondSMToggle(MachineBasicBlock &
MBB,
1234 MachineInstr &
MI = *
MBBI;
1241 MI.getParent()->successors().begin() ==
1242 MI.getParent()->successors().end()) {
1243 MI.eraseFromParent();
1286 switch (
MI.getOperand(2).getImm()) {
1290 Opc = AArch64::TBNZW;
1293 Opc = AArch64::TBZW;
1296 auto PStateSM =
MI.getOperand(3).getReg();
1298 unsigned SMReg32 =
TRI->getSubReg(PStateSM, AArch64::sub_32);
1299 MachineInstrBuilder Tbx =
1302 auto [CondBB, EndBB] = expandConditionalPseudo(
MBB,
MBBI,
DL, Tbx);
1304 MachineInstrBuilder MIB =
BuildMI(CondBB, CondBB.
back(),
MI.getDebugLoc(),
1305 TII->get(AArch64::MSRpstatesvcrImm1));
1309 MIB.
add(
MI.getOperand(0));
1310 MIB.
add(
MI.getOperand(1));
1311 for (
unsigned i = 4; i <
MI.getNumOperands(); ++i)
1312 MIB.
add(
MI.getOperand(i));
1314 MI.eraseFromParent();
1318bool AArch64ExpandPseudoImpl::expandMultiVecPseudo(
1320 TargetRegisterClass ContiguousClass, TargetRegisterClass StridedClass,
1321 unsigned ContiguousOp,
unsigned StridedOpc) {
1322 MachineInstr &
MI = *
MBBI;
1336 .
add(
MI.getOperand(0))
1337 .
add(
MI.getOperand(1))
1338 .
add(
MI.getOperand(2))
1339 .
add(
MI.getOperand(3));
1340 transferImpOps(
MI, MIB, MIB);
1341 MI.eraseFromParent();
1345bool AArch64ExpandPseudoImpl::expandFormTuplePseudo(
1349 MachineInstr &
MI = *
MBBI;
1350 Register ReturnTuple =
MI.getOperand(0).getReg();
1352 const TargetRegisterInfo *
TRI =
1354 for (
unsigned I = 0;
I <
Size; ++
I) {
1355 Register FormTupleOpReg =
MI.getOperand(
I + 1).getReg();
1357 TRI->getSubReg(ReturnTuple, AArch64::zsub0 +
I);
1360 if (FormTupleOpReg != ReturnTupleSubReg)
1362 .
addReg(ReturnTupleSubReg, RegState::Define)
1367 MI.eraseFromParent();
1373bool AArch64ExpandPseudoImpl::expandMI(MachineBasicBlock &
MBB,
1376 MachineInstr &
MI = *
MBBI;
1377 unsigned Opcode =
MI.getOpcode();
1381 if (OrigInstr != -1) {
1382 auto &Orig =
TII->get(OrigInstr);
1385 return expand_DestructiveOp(
MI,
MBB,
MBBI);
1393 case AArch64::BSPv8i8:
1394 case AArch64::BSPv16i8: {
1396 if (DstReg ==
MI.getOperand(3).getReg()) {
1399 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BITv8i8
1400 : AArch64::BITv16i8))
1401 .
add(
MI.getOperand(0))
1402 .
add(
MI.getOperand(3))
1403 .
add(
MI.getOperand(2))
1404 .
add(
MI.getOperand(1));
1405 transferImpOps(
MI,
I,
I);
1406 }
else if (DstReg ==
MI.getOperand(2).getReg()) {
1409 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BIFv8i8
1410 : AArch64::BIFv16i8))
1411 .
add(
MI.getOperand(0))
1412 .
add(
MI.getOperand(2))
1413 .
add(
MI.getOperand(3))
1414 .
add(
MI.getOperand(1));
1415 transferImpOps(
MI,
I,
I);
1418 if (DstReg ==
MI.getOperand(1).getReg()) {
1421 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BSLv8i8
1422 : AArch64::BSLv16i8))
1423 .
add(
MI.getOperand(0))
1424 .
add(
MI.getOperand(1))
1425 .
add(
MI.getOperand(2))
1426 .
add(
MI.getOperand(3));
1427 transferImpOps(
MI,
I,
I);
1432 MI.getOperand(1).isKill() &&
1433 MI.getOperand(1).getReg() !=
MI.getOperand(2).getReg() &&
1434 MI.getOperand(1).getReg() !=
MI.getOperand(3).getReg());
1436 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::ORRv8i8
1437 : AArch64::ORRv16i8))
1445 TII->get(Opcode == AArch64::BSPv8i8 ? AArch64::BSLv8i8
1446 : AArch64::BSLv16i8))
1447 .
add(
MI.getOperand(0))
1450 MI.getOperand(0).isRenamable()))
1451 .
add(
MI.getOperand(2))
1452 .
add(
MI.getOperand(3));
1453 transferImpOps(
MI, I2, I2);
1456 MI.eraseFromParent();
1460 case AArch64::ADDWrr:
1461 case AArch64::SUBWrr:
1462 case AArch64::ADDXrr:
1463 case AArch64::SUBXrr:
1464 case AArch64::ADDSWrr:
1465 case AArch64::SUBSWrr:
1466 case AArch64::ADDSXrr:
1467 case AArch64::SUBSXrr:
1468 case AArch64::ANDWrr:
1469 case AArch64::ANDXrr:
1470 case AArch64::BICWrr:
1471 case AArch64::BICXrr:
1472 case AArch64::ANDSWrr:
1473 case AArch64::ANDSXrr:
1474 case AArch64::BICSWrr:
1475 case AArch64::BICSXrr:
1476 case AArch64::EONWrr:
1477 case AArch64::EONXrr:
1478 case AArch64::EORWrr:
1479 case AArch64::EORXrr:
1480 case AArch64::ORNWrr:
1481 case AArch64::ORNXrr:
1482 case AArch64::ORRWrr:
1483 case AArch64::ORRXrr: {
1485 switch (
MI.getOpcode()) {
1488 case AArch64::ADDWrr: Opcode = AArch64::ADDWrs;
break;
1489 case AArch64::SUBWrr: Opcode = AArch64::SUBWrs;
break;
1490 case AArch64::ADDXrr: Opcode = AArch64::ADDXrs;
break;
1491 case AArch64::SUBXrr: Opcode = AArch64::SUBXrs;
break;
1492 case AArch64::ADDSWrr: Opcode = AArch64::ADDSWrs;
break;
1493 case AArch64::SUBSWrr: Opcode = AArch64::SUBSWrs;
break;
1494 case AArch64::ADDSXrr: Opcode = AArch64::ADDSXrs;
break;
1495 case AArch64::SUBSXrr: Opcode = AArch64::SUBSXrs;
break;
1496 case AArch64::ANDWrr: Opcode = AArch64::ANDWrs;
break;
1497 case AArch64::ANDXrr: Opcode = AArch64::ANDXrs;
break;
1498 case AArch64::BICWrr: Opcode = AArch64::BICWrs;
break;
1499 case AArch64::BICXrr: Opcode = AArch64::BICXrs;
break;
1500 case AArch64::ANDSWrr: Opcode = AArch64::ANDSWrs;
break;
1501 case AArch64::ANDSXrr: Opcode = AArch64::ANDSXrs;
break;
1502 case AArch64::BICSWrr: Opcode = AArch64::BICSWrs;
break;
1503 case AArch64::BICSXrr: Opcode = AArch64::BICSXrs;
break;
1504 case AArch64::EONWrr: Opcode = AArch64::EONWrs;
break;
1505 case AArch64::EONXrr: Opcode = AArch64::EONXrs;
break;
1506 case AArch64::EORWrr: Opcode = AArch64::EORWrs;
break;
1507 case AArch64::EORXrr: Opcode = AArch64::EORXrs;
break;
1508 case AArch64::ORNWrr: Opcode = AArch64::ORNWrs;
break;
1509 case AArch64::ORNXrr: Opcode = AArch64::ORNXrs;
break;
1510 case AArch64::ORRWrr: Opcode = AArch64::ORRWrs;
break;
1511 case AArch64::ORRXrr: Opcode = AArch64::ORRXrs;
break;
1515 MachineInstr *NewMI = MF.CreateMachineInstr(
1516 TII->get(Opcode),
MI.getDebugLoc(),
true);
1518 MachineInstrBuilder MIB1(MF, NewMI);
1519 MIB1->setPCSections(MF,
MI.getPCSections());
1520 MIB1.addReg(
MI.getOperand(0).getReg(), RegState::Define)
1521 .add(
MI.getOperand(1))
1522 .add(
MI.getOperand(2))
1524 transferImpOps(
MI, MIB1, MIB1);
1525 if (
auto DebugNumber =
MI.peekDebugInstrNum())
1527 MI.eraseFromParent();
1531 case AArch64::LOADgot: {
1534 const MachineOperand &MO1 =
MI.getOperand(1);
1540 TII->get(AArch64::LDRXl), DstReg);
1548 "Only expect globals, externalsymbols, or constant pools");
1553 MachineFunction &MF = *
MI.getParent()->getParent();
1555 MachineInstrBuilder MIB1 =
1558 MachineInstrBuilder MIB2;
1559 if (MF.
getSubtarget<AArch64Subtarget>().isTargetILP32()) {
1561 unsigned Reg32 =
TRI->getSubReg(DstReg, AArch64::sub_32);
1564 .
addReg(DstReg, RegState::Kill)
1565 .
addReg(DstReg, RegState::Implicit);
1569 .
add(
MI.getOperand(0))
1570 .
addUse(DstReg, RegState::Kill);
1584 "Only expect globals, externalsymbols, or constant pools");
1595 if (
MI.peekDebugInstrNum() != 0)
1597 transferImpOps(
MI, MIB1, MIB2);
1599 MI.eraseFromParent();
1602 case AArch64::MOVaddrBA: {
1603 MachineFunction &MF = *
MI.getParent()->getParent();
1604 if (MF.
getSubtarget<AArch64Subtarget>().isTargetMachO()) {
1609 assert(
MI.getOperand(1).getOffset() == 0 &&
"unexpected offset");
1619 TII->get(AArch64::LDRXui), DstReg)
1623 transferImpOps(
MI, MIB1, MIB2);
1624 MI.eraseFromParent();
1629 case AArch64::MOVaddr:
1630 case AArch64::MOVaddrJT:
1631 case AArch64::MOVaddrCP:
1632 case AArch64::MOVaddrTLS:
1633 case AArch64::MOVaddrEXT: {
1636 assert(DstReg != AArch64::XZR);
1637 MachineInstrBuilder MIB1 =
1639 .
add(
MI.getOperand(1));
1649 auto Tag =
MI.getOperand(1);
1651 Tag.setOffset(0x100000000);
1658 MachineInstrBuilder MIB2 =
1660 .
add(
MI.getOperand(0))
1662 .
add(
MI.getOperand(2))
1665 transferImpOps(
MI, MIB1, MIB2);
1666 MI.eraseFromParent();
1669 case AArch64::ADDlowTLS:
1672 .
add(
MI.getOperand(0))
1673 .
add(
MI.getOperand(1))
1674 .
add(
MI.getOperand(2))
1676 MI.eraseFromParent();
1679 case AArch64::MOVbaseTLS: {
1681 auto SysReg = AArch64SysReg::TPIDR_EL0;
1683 if (MF->
getSubtarget<AArch64Subtarget>().useEL3ForTP())
1684 SysReg = AArch64SysReg::TPIDR_EL3;
1685 else if (MF->
getSubtarget<AArch64Subtarget>().useEL2ForTP())
1686 SysReg = AArch64SysReg::TPIDR_EL2;
1687 else if (MF->
getSubtarget<AArch64Subtarget>().useEL1ForTP())
1688 SysReg = AArch64SysReg::TPIDR_EL1;
1689 else if (MF->
getSubtarget<AArch64Subtarget>().useROEL0ForTP())
1690 SysReg = AArch64SysReg::TPIDRRO_EL0;
1693 MI.eraseFromParent();
1697 case AArch64::MOVi32imm:
1699 case AArch64::MOVi64imm:
1701 case AArch64::RET_ReallyLR: {
1707 MachineInstrBuilder MIB =
1709 .
addReg(AArch64::LR, RegState::Undef);
1710 transferImpOps(
MI, MIB, MIB);
1711 MI.eraseFromParent();
1714 case AArch64::CMP_SWAP_8:
1715 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRB, AArch64::STLXRB,
1718 AArch64::WZR, NextMBBI);
1719 case AArch64::CMP_SWAP_16:
1720 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRH, AArch64::STLXRH,
1723 AArch64::WZR, NextMBBI);
1724 case AArch64::CMP_SWAP_32:
1725 return expandCMP_SWAP(
MBB,
MBBI, AArch64::LDAXRW, AArch64::STLXRW,
1728 AArch64::WZR, NextMBBI);
1729 case AArch64::CMP_SWAP_64:
1730 return expandCMP_SWAP(
MBB,
MBBI,
1731 AArch64::LDAXRX, AArch64::STLXRX, AArch64::SUBSXrs,
1733 AArch64::XZR, NextMBBI);
1734 case AArch64::CMP_SWAP_128:
1735 case AArch64::CMP_SWAP_128_RELEASE:
1736 case AArch64::CMP_SWAP_128_ACQUIRE:
1737 case AArch64::CMP_SWAP_128_MONOTONIC:
1738 return expandCMP_SWAP_128(
MBB,
MBBI, NextMBBI);
1740 case AArch64::AESMCrrTied:
1741 case AArch64::AESIMCrrTied: {
1742 MachineInstrBuilder MIB =
1744 TII->get(Opcode == AArch64::AESMCrrTied ? AArch64::AESMCrr :
1746 .
add(
MI.getOperand(0))
1747 .
add(
MI.getOperand(1));
1748 transferImpOps(
MI, MIB, MIB);
1749 MI.eraseFromParent();
1752 case AArch64::IRGstack: {
1754 const AArch64FunctionInfo *AFI = MF.
getInfo<AArch64FunctionInfo>();
1755 const AArch64FrameLowering *TFI =
1756 MF.
getSubtarget<AArch64Subtarget>().getFrameLowering();
1763 StackOffset FrameRegOffset = TFI->resolveFrameOffsetReference(
1769 if (FrameRegOffset) {
1771 SrcReg =
MI.getOperand(0).getReg();
1773 FrameRegOffset,
TII);
1776 .
add(
MI.getOperand(0))
1778 .
add(
MI.getOperand(2));
1779 MI.eraseFromParent();
1782 case AArch64::TAGPstack: {
1783 int64_t
Offset =
MI.getOperand(2).getImm();
1785 TII->get(
Offset >= 0 ? AArch64::ADDG : AArch64::SUBG))
1786 .
add(
MI.getOperand(0))
1787 .
add(
MI.getOperand(1))
1789 .
add(
MI.getOperand(4));
1790 MI.eraseFromParent();
1793 case AArch64::STGloop_wback:
1794 case AArch64::STZGloop_wback:
1795 return expandSetTagLoop(
MBB,
MBBI, NextMBBI);
1796 case AArch64::STGloop:
1797 case AArch64::STZGloop:
1799 "Non-writeback variants of STGloop / STZGloop should not "
1800 "survive past PrologEpilogInserter.");
1801 case AArch64::STR_ZZZZXI:
1802 case AArch64::STR_ZZZZXI_STRIDED_CONTIGUOUS:
1803 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 4);
1804 case AArch64::STR_ZZZXI:
1805 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 3);
1806 case AArch64::STR_ZZXI:
1807 case AArch64::STR_ZZXI_STRIDED_CONTIGUOUS:
1808 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_ZXI, 2);
1809 case AArch64::STR_PPXI:
1810 return expandSVESpillFill(
MBB,
MBBI, AArch64::STR_PXI, 2);
1811 case AArch64::LDR_ZZZZXI:
1812 case AArch64::LDR_ZZZZXI_STRIDED_CONTIGUOUS:
1813 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 4);
1814 case AArch64::LDR_ZZZXI:
1815 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 3);
1816 case AArch64::LDR_ZZXI:
1817 case AArch64::LDR_ZZXI_STRIDED_CONTIGUOUS:
1818 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_ZXI, 2);
1819 case AArch64::LDR_PPXI:
1820 return expandSVESpillFill(
MBB,
MBBI, AArch64::LDR_PXI, 2);
1821 case AArch64::BLR_RVMARKER:
1822 case AArch64::BLRA_RVMARKER:
1823 return expandCALL_RVMARKER(
MBB,
MBBI);
1824 case AArch64::BLR_BTI:
1825 return expandCALL_BTI(
MBB,
MBBI);
1826 case AArch64::StoreSwiftAsyncContext:
1827 return expandStoreSwiftAsyncContext(
MBB,
MBBI);
1828 case AArch64::STSHH_ATOMIC_STORE_SZ:
1829 return expandSTSHHAtomicStore(
MBB,
MBBI);
1830 case AArch64::RestoreZAPseudo:
1831 case AArch64::CommitZASavePseudo:
1832 case AArch64::MSRpstatePseudo: {
1833 auto *NewMBB = [&] {
1835 case AArch64::RestoreZAPseudo:
1836 return expandRestoreZASave(
MBB,
MBBI);
1837 case AArch64::CommitZASavePseudo:
1838 return expandCommitZASave(
MBB,
MBBI);
1839 case AArch64::MSRpstatePseudo:
1840 return expandCondSMToggle(
MBB,
MBBI);
1849 case AArch64::InOutZAUsePseudo:
1850 case AArch64::RequiresZASavePseudo:
1851 case AArch64::RequiresZT0SavePseudo:
1852 case AArch64::SMEStateAllocPseudo:
1853 case AArch64::COALESCER_BARRIER_FPR16:
1854 case AArch64::COALESCER_BARRIER_FPR32:
1855 case AArch64::COALESCER_BARRIER_FPR64:
1856 case AArch64::COALESCER_BARRIER_FPR128:
1857 MI.eraseFromParent();
1859 case AArch64::LD1B_2Z_IMM_PSEUDO:
1860 return expandMultiVecPseudo(
1861 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1862 AArch64::LD1B_2Z_IMM, AArch64::LD1B_2Z_STRIDED_IMM);
1863 case AArch64::LD1H_2Z_IMM_PSEUDO:
1864 return expandMultiVecPseudo(
1865 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1866 AArch64::LD1H_2Z_IMM, AArch64::LD1H_2Z_STRIDED_IMM);
1867 case AArch64::LD1W_2Z_IMM_PSEUDO:
1868 return expandMultiVecPseudo(
1869 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1870 AArch64::LD1W_2Z_IMM, AArch64::LD1W_2Z_STRIDED_IMM);
1871 case AArch64::LD1D_2Z_IMM_PSEUDO:
1872 return expandMultiVecPseudo(
1873 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1874 AArch64::LD1D_2Z_IMM, AArch64::LD1D_2Z_STRIDED_IMM);
1875 case AArch64::LDNT1B_2Z_IMM_PSEUDO:
1876 return expandMultiVecPseudo(
1877 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1878 AArch64::LDNT1B_2Z_IMM, AArch64::LDNT1B_2Z_STRIDED_IMM);
1879 case AArch64::LDNT1H_2Z_IMM_PSEUDO:
1880 return expandMultiVecPseudo(
1881 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1882 AArch64::LDNT1H_2Z_IMM, AArch64::LDNT1H_2Z_STRIDED_IMM);
1883 case AArch64::LDNT1W_2Z_IMM_PSEUDO:
1884 return expandMultiVecPseudo(
1885 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1886 AArch64::LDNT1W_2Z_IMM, AArch64::LDNT1W_2Z_STRIDED_IMM);
1887 case AArch64::LDNT1D_2Z_IMM_PSEUDO:
1888 return expandMultiVecPseudo(
1889 MBB,
MBBI, AArch64::ZPR2RegClass, AArch64::ZPR2StridedRegClass,
1890 AArch64::LDNT1D_2Z_IMM, AArch64::LDNT1D_2Z_STRIDED_IMM);
1891 case AArch64::LD1B_2Z_PSEUDO:
1892 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1893 AArch64::ZPR2StridedRegClass, AArch64::LD1B_2Z,
1894 AArch64::LD1B_2Z_STRIDED);
1895 case AArch64::LD1H_2Z_PSEUDO:
1896 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1897 AArch64::ZPR2StridedRegClass, AArch64::LD1H_2Z,
1898 AArch64::LD1H_2Z_STRIDED);
1899 case AArch64::LD1W_2Z_PSEUDO:
1900 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1901 AArch64::ZPR2StridedRegClass, AArch64::LD1W_2Z,
1902 AArch64::LD1W_2Z_STRIDED);
1903 case AArch64::LD1D_2Z_PSEUDO:
1904 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1905 AArch64::ZPR2StridedRegClass, AArch64::LD1D_2Z,
1906 AArch64::LD1D_2Z_STRIDED);
1907 case AArch64::LDNT1B_2Z_PSEUDO:
1908 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1909 AArch64::ZPR2StridedRegClass,
1910 AArch64::LDNT1B_2Z, AArch64::LDNT1B_2Z_STRIDED);
1911 case AArch64::LDNT1H_2Z_PSEUDO:
1912 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1913 AArch64::ZPR2StridedRegClass,
1914 AArch64::LDNT1H_2Z, AArch64::LDNT1H_2Z_STRIDED);
1915 case AArch64::LDNT1W_2Z_PSEUDO:
1916 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1917 AArch64::ZPR2StridedRegClass,
1918 AArch64::LDNT1W_2Z, AArch64::LDNT1W_2Z_STRIDED);
1919 case AArch64::LDNT1D_2Z_PSEUDO:
1920 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR2RegClass,
1921 AArch64::ZPR2StridedRegClass,
1922 AArch64::LDNT1D_2Z, AArch64::LDNT1D_2Z_STRIDED);
1923 case AArch64::LD1B_4Z_IMM_PSEUDO:
1924 return expandMultiVecPseudo(
1925 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1926 AArch64::LD1B_4Z_IMM, AArch64::LD1B_4Z_STRIDED_IMM);
1927 case AArch64::LD1H_4Z_IMM_PSEUDO:
1928 return expandMultiVecPseudo(
1929 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1930 AArch64::LD1H_4Z_IMM, AArch64::LD1H_4Z_STRIDED_IMM);
1931 case AArch64::LD1W_4Z_IMM_PSEUDO:
1932 return expandMultiVecPseudo(
1933 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1934 AArch64::LD1W_4Z_IMM, AArch64::LD1W_4Z_STRIDED_IMM);
1935 case AArch64::LD1D_4Z_IMM_PSEUDO:
1936 return expandMultiVecPseudo(
1937 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1938 AArch64::LD1D_4Z_IMM, AArch64::LD1D_4Z_STRIDED_IMM);
1939 case AArch64::LDNT1B_4Z_IMM_PSEUDO:
1940 return expandMultiVecPseudo(
1941 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1942 AArch64::LDNT1B_4Z_IMM, AArch64::LDNT1B_4Z_STRIDED_IMM);
1943 case AArch64::LDNT1H_4Z_IMM_PSEUDO:
1944 return expandMultiVecPseudo(
1945 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1946 AArch64::LDNT1H_4Z_IMM, AArch64::LDNT1H_4Z_STRIDED_IMM);
1947 case AArch64::LDNT1W_4Z_IMM_PSEUDO:
1948 return expandMultiVecPseudo(
1949 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1950 AArch64::LDNT1W_4Z_IMM, AArch64::LDNT1W_4Z_STRIDED_IMM);
1951 case AArch64::LDNT1D_4Z_IMM_PSEUDO:
1952 return expandMultiVecPseudo(
1953 MBB,
MBBI, AArch64::ZPR4RegClass, AArch64::ZPR4StridedRegClass,
1954 AArch64::LDNT1D_4Z_IMM, AArch64::LDNT1D_4Z_STRIDED_IMM);
1955 case AArch64::LD1B_4Z_PSEUDO:
1956 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1957 AArch64::ZPR4StridedRegClass, AArch64::LD1B_4Z,
1958 AArch64::LD1B_4Z_STRIDED);
1959 case AArch64::LD1H_4Z_PSEUDO:
1960 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1961 AArch64::ZPR4StridedRegClass, AArch64::LD1H_4Z,
1962 AArch64::LD1H_4Z_STRIDED);
1963 case AArch64::LD1W_4Z_PSEUDO:
1964 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1965 AArch64::ZPR4StridedRegClass, AArch64::LD1W_4Z,
1966 AArch64::LD1W_4Z_STRIDED);
1967 case AArch64::LD1D_4Z_PSEUDO:
1968 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1969 AArch64::ZPR4StridedRegClass, AArch64::LD1D_4Z,
1970 AArch64::LD1D_4Z_STRIDED);
1971 case AArch64::LDNT1B_4Z_PSEUDO:
1972 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1973 AArch64::ZPR4StridedRegClass,
1974 AArch64::LDNT1B_4Z, AArch64::LDNT1B_4Z_STRIDED);
1975 case AArch64::LDNT1H_4Z_PSEUDO:
1976 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1977 AArch64::ZPR4StridedRegClass,
1978 AArch64::LDNT1H_4Z, AArch64::LDNT1H_4Z_STRIDED);
1979 case AArch64::LDNT1W_4Z_PSEUDO:
1980 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1981 AArch64::ZPR4StridedRegClass,
1982 AArch64::LDNT1W_4Z, AArch64::LDNT1W_4Z_STRIDED);
1983 case AArch64::LDNT1D_4Z_PSEUDO:
1984 return expandMultiVecPseudo(
MBB,
MBBI, AArch64::ZPR4RegClass,
1985 AArch64::ZPR4StridedRegClass,
1986 AArch64::LDNT1D_4Z, AArch64::LDNT1D_4Z_STRIDED);
1987 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO:
1988 return expandFormTuplePseudo(
MBB,
MBBI, NextMBBI, 2);
1989 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO:
1990 return expandFormTuplePseudo(
MBB,
MBBI, NextMBBI, 4);
1991 case AArch64::EON_ZZZ:
1992 case AArch64::NAND_ZZZ:
1993 case AArch64::NOR_ZZZ:
1994 return expandSVEBitwisePseudo(
MI,
MBB,
MBBI);
2001bool AArch64ExpandPseudoImpl::expandMBB(MachineBasicBlock &
MBB) {
2014bool AArch64ExpandPseudoImpl::run(MachineFunction &MF) {
2018 for (
auto &
MBB : MF)
2023bool AArch64ExpandPseudoLegacy::runOnMachineFunction(MachineFunction &MF) {
2024 return AArch64ExpandPseudoImpl().run(MF);
2029 return new AArch64ExpandPseudoLegacy();
2035 const bool Changed = AArch64ExpandPseudoImpl().run(MF);
#define AARCH64_EXPAND_PSEUDO_NAME
MachineInstrBuilder & UseMI
static MachineInstr * createCallWithOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const AArch64InstrInfo *TII, unsigned Opcode, ArrayRef< MachineOperand > ExplicitOps, unsigned RegMaskStartIdx)
static constexpr unsigned ZERO_ALL_ZA_MASK
static MachineInstr * createCall(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const AArch64InstrInfo *TII, MachineOperand &CallTarget, unsigned RegMaskStartIdx)
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned getTaggedBasePointerOffset() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void moveAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
void setDebugInstrNum(unsigned Num)
Set instruction number of this MachineInstr.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
LLVM_ABI bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
int64_t getOffset() const
Return the offset from the symbol in this operand.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
CodeModel::Model getCodeModel() const
Returns the code model.
ArrayRef< MCPhysReg > getRegisters() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_PREL
MO_PREL - Indicates that the bits of the symbol operand represented by MO_G0 etc are PC relative.
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TAGGED
MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag in bits 56-63.
@ MO_G3
MO_G3 - A symbol operand with this flag (granule 3) represents the high 16-bits of a 64-bit address,...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
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 ==...
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...
@ Destructive2xRegImmUnpred
@ DestructiveBinaryShImmUnpred
@ DestructiveInstTypeMask
@ DestructiveUnaryPassthru
@ DestructiveTernaryCommWithRev
@ DestructiveBinaryCommWithRev
int32_t getSVERevInstr(uint32_t Opcode)
int32_t getSVENonRevInstr(uint32_t Opcode)
int32_t getSVEPseudoMap(uint32_t Opcode)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr RegState getDeadRegState(bool B)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
FunctionPass * createAArch64ExpandPseudoLegacyPass()
Returns an instance of the pseudo instruction expansion pass.
constexpr RegState getRenamableRegState(bool B)
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr RegState getDefRegState(bool B)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
constexpr RegState getUndefRegState(bool B)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.