[MachineOutliner] AArch64: Don't outline ADRPs with un-outlinable operands

If an ADRP appears with, say, a CPI operand, we shouldn't outline it.

This moves the check for unsafe operands so that it occurs before the special-case
for ADRPs. Also add a test for outlining ADRPs.

llvm-svn: 328674
This commit is contained in:
Jessica Paquette 2018-03-27 22:23:48 +00:00
parent e4208bfa5b
commit 2519ee7081
2 changed files with 48 additions and 11 deletions

View File

@ -5053,6 +5053,13 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
return MachineOutlinerInstrType::Illegal;
}
// Make sure none of the operands are un-outlinable.
for (const MachineOperand &MOP : MI.operands()) {
if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() ||
MOP.isTargetIndex())
return MachineOutlinerInstrType::Illegal;
}
// Special cases for instructions that can always be outlined, but will fail
// the later tests. e.g, ADRPs, which are PC-relative use LR, but can always
// be outlined because they don't require a *specific* value to be in LR.
@ -5132,17 +5139,6 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
MI.modifiesRegister(AArch64::W30, &getRegisterInfo()))
return MachineOutlinerInstrType::Illegal;
// Make sure none of the operands are un-outlinable.
for (const MachineOperand &MOP : MI.operands()) {
if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() ||
MOP.isTargetIndex())
return MachineOutlinerInstrType::Illegal;
// Don't outline anything that uses the link register.
if (MOP.isReg() && getRegisterInfo().regsOverlap(MOP.getReg(), AArch64::LR))
return MachineOutlinerInstrType::Illegal;
}
// Does this use the stack?
if (MI.modifiesRegister(AArch64::SP, &RI) ||
MI.readsRegister(AArch64::SP, &RI)) {

View File

@ -0,0 +1,41 @@
# RUN: llc -mtriple=aarch64--- -verify-machineinstrs -simplify-mir -run-pass=machine-outliner %s -o - | FileCheck %s
--- |
define void @foo() #0 {
ret void
}
attributes #0 = { noredzone }
...
---
name: foo
constants:
- id: 0
value: 'float 1.990000e+02'
alignment: 4
isTargetSpecific: false
body: |
bb.0:
liveins: $w1, $w10, $x14, $x15, $x16, $x10, $lr
; CHECK-NOT: BL
$w10 = MOVZWi 4, 0, implicit-def $x10
renamable $x14 = ADRP target-flags(aarch64-page) %const.0
renamable $x15 = ADRP target-flags(aarch64-page) %const.0
renamable $x16 = ADRP target-flags(aarch64-page) %const.0
$w10 = MOVZWi 5, 0, implicit-def $x10
renamable $x14 = ADRP target-flags(aarch64-page) %const.0
renamable $x15 = ADRP target-flags(aarch64-page) %const.0
renamable $x16 = ADRP target-flags(aarch64-page) %const.0
$w10 = MOVZWi 6, 0, implicit-def $x10
renamable $x14 = ADRP target-flags(aarch64-page) %const.0
renamable $x15 = ADRP target-flags(aarch64-page) %const.0
renamable $x16 = ADRP target-flags(aarch64-page) %const.0
RET undef $lr