@@ -9547,7 +9547,10 @@ AArch64InstrInfo::getOutliningCandidateInfo(
95479547
95489548 unsigned NumBytesToCreateFrame = 0 ;
95499549
9550- // Avoid splitting ADRP-ADD/LDR pair into outlined functions.
9550+ // Avoid splitting ADRP ADD/LDR pair into outlined functions.
9551+ // These instructions are fused together by the scheduler.
9552+ // Any candidate where ADRP is the last instruction should be rejected
9553+ // as that will lead to splitting ADRP pair.
95519554 MachineInstr &LastMI = RepeatedSequenceLocs[0 ].back ();
95529555 MachineInstr &FirstMI = RepeatedSequenceLocs[0 ].front ();
95539556 if (LastMI.getOpcode () == AArch64::ADRP &&
@@ -9556,6 +9559,8 @@ AArch64InstrInfo::getOutliningCandidateInfo(
95569559 return std::nullopt ;
95579560 }
95589561
9562+ // Similarly any candidate where the first instruction is ADD/LDR with a
9563+ // page offset should be rejected to avoid ADRP splitting.
95599564 if ((FirstMI.getOpcode () == AArch64::ADDXri || FirstMI.getOpcode () == AArch64::LDRXui) &&
95609565 (FirstMI.getOperand (2 ).getTargetFlags () & AArch64II::MO_PAGEOFF) != 0 &&
95619566 (FirstMI.getOperand (2 ).getTargetFlags () & AArch64II::MO_GOT) != 0 ) {
@@ -10194,6 +10199,12 @@ AArch64InstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
1019410199 return outliner::InstrType::Illegal;
1019510200 }
1019610201
10202+ // Special cases for instructions that can always be outlined, but will fail
10203+ // the later tests. e.g, ADRPs, which are PC-relative use LR, but can always
10204+ // be outlined because they don't require a *specific* value to be in LR.
10205+ if (MI.getOpcode () == AArch64::ADRP)
10206+ return outliner::InstrType::Legal;
10207+
1019710208 // If MI is a call we might be able to outline it. We don't want to outline
1019810209 // any calls that rely on the position of items on the stack. When we outline
1019910210 // something containing a call, we have to emit a save and restore of LR in
0 commit comments