mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[ARM][MachineOutliner] Add stack fixup feature
This patch handles cases where we have to save/restore the link register into the stack and and load/store instruction which use the stack are part of the outlined region. It checks that there will be no overflow introduced by the new offset and fixup these instructions accordingly. Differential Revision: https://reviews.llvm.org/D92934
This commit is contained in:
parent
d6f7a6374a
commit
178bc607c9
@ -5914,6 +5914,112 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
|
||||
NumBytesToCreateFrame, FrameID);
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::checkAndUpdateStackOffset(MachineInstr *MI,
|
||||
int64_t Fixup,
|
||||
bool Updt) const {
|
||||
int SPIdx = MI->findRegisterUseOperandIdx(ARM::SP);
|
||||
unsigned AddrMode = (MI->getDesc().TSFlags & ARMII::AddrModeMask);
|
||||
if (SPIdx < 0)
|
||||
// No SP operand
|
||||
return true;
|
||||
else if (SPIdx != 1 && (AddrMode != ARMII::AddrModeT2_i8s4 || SPIdx != 2))
|
||||
// If SP is not the base register we can't do much
|
||||
return false;
|
||||
|
||||
// Stack might be involved but addressing mode doesn't handle any offset.
|
||||
// Rq: AddrModeT1_[1|2|4] don't operate on SP
|
||||
if (AddrMode == ARMII::AddrMode1 // Arithmetic instructions
|
||||
|| AddrMode == ARMII::AddrMode4 // Load/Store Multiple
|
||||
|| AddrMode == ARMII::AddrMode6 // Neon Load/Store Multiple
|
||||
|| AddrMode == ARMII::AddrModeT2_so // SP can't be used as based register
|
||||
|| AddrMode == ARMII::AddrModeT2_pc // PCrel access
|
||||
|| AddrMode == ARMII::AddrMode2 // Used by PRE and POST indexed LD/ST
|
||||
|| AddrMode == ARMII::AddrModeNone)
|
||||
return false;
|
||||
|
||||
unsigned NumOps = MI->getDesc().getNumOperands();
|
||||
unsigned ImmIdx = NumOps - 3;
|
||||
|
||||
const MachineOperand &Offset = MI->getOperand(ImmIdx);
|
||||
assert(Offset.isImm() && "Is not an immediate");
|
||||
int64_t OffVal = Offset.getImm();
|
||||
|
||||
if (OffVal < 0)
|
||||
// Don't override data if the are below SP.
|
||||
return false;
|
||||
|
||||
unsigned NumBits = 0;
|
||||
unsigned Scale = 1;
|
||||
|
||||
switch (AddrMode) {
|
||||
case ARMII::AddrMode3:
|
||||
if (ARM_AM::getAM3Op(OffVal) == ARM_AM::sub)
|
||||
return false;
|
||||
OffVal = ARM_AM::getAM3Offset(OffVal);
|
||||
NumBits = 8;
|
||||
break;
|
||||
case ARMII::AddrMode5:
|
||||
if (ARM_AM::getAM5Op(OffVal) == ARM_AM::sub)
|
||||
return false;
|
||||
OffVal = ARM_AM::getAM5Offset(OffVal);
|
||||
NumBits = 8;
|
||||
Scale = 4;
|
||||
break;
|
||||
case ARMII::AddrMode5FP16:
|
||||
if (ARM_AM::getAM5FP16Op(OffVal) == ARM_AM::sub)
|
||||
return false;
|
||||
OffVal = ARM_AM::getAM5FP16Offset(OffVal);
|
||||
NumBits = 8;
|
||||
Scale = 2;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i8:
|
||||
NumBits = 8;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i8s4:
|
||||
case ARMII::AddrModeT2_ldrex:
|
||||
NumBits = 8;
|
||||
Scale = 4;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i12:
|
||||
case ARMII::AddrMode_i12:
|
||||
NumBits = 12;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i7:
|
||||
NumBits = 7;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i7s2:
|
||||
NumBits = 7;
|
||||
Scale = 2;
|
||||
break;
|
||||
case ARMII::AddrModeT2_i7s4:
|
||||
NumBits = 7;
|
||||
Scale = 4;
|
||||
break;
|
||||
case ARMII::AddrModeT1_s: // SP-relative LD/ST
|
||||
NumBits = 8;
|
||||
Scale = 4;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported addressing mode!");
|
||||
}
|
||||
// Make sure the offset is encodable for instructions that scale the
|
||||
// immediate.
|
||||
if (((OffVal * Scale + Fixup) & (Scale - 1)) != 0)
|
||||
return false;
|
||||
OffVal += Fixup / Scale;
|
||||
|
||||
unsigned Mask = (1 << NumBits) - 1;
|
||||
|
||||
if (OffVal <= Mask) {
|
||||
if (Updt)
|
||||
MI->getOperand(ImmIdx).setImm(OffVal);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool ARMBaseInstrInfo::isFunctionSafeToOutlineFrom(
|
||||
MachineFunction &MF, bool OutlineFromLinkOnceODRs) const {
|
||||
const Function &F = MF.getFunction();
|
||||
@ -6125,6 +6231,19 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
|
||||
if (!MightNeedStackFixUp)
|
||||
return outliner::InstrType::Legal;
|
||||
|
||||
// Any modification of SP will break our code to save/restore LR.
|
||||
// FIXME: We could handle some instructions which add a constant offset to
|
||||
// SP, with a bit more work.
|
||||
if (MI.modifiesRegister(ARM::SP, TRI))
|
||||
return outliner::InstrType::Illegal;
|
||||
|
||||
// At this point, we have a stack instruction that we might need to fix up.
|
||||
// up. We'll handle it if it's a load or store.
|
||||
if (checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(),
|
||||
false))
|
||||
return outliner::InstrType::Legal;
|
||||
|
||||
// We can't fix it up, so don't outline it.
|
||||
return outliner::InstrType::Illegal;
|
||||
}
|
||||
|
||||
@ -6140,6 +6259,12 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
|
||||
return outliner::InstrType::Legal;
|
||||
}
|
||||
|
||||
void ARMBaseInstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
|
||||
for (MachineInstr &MI : MBB) {
|
||||
checkAndUpdateStackOffset(&MI, Subtarget.getStackAlignment().value(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator It) const {
|
||||
unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
|
||||
@ -6275,6 +6400,12 @@ void ARMBaseInstrInfo::buildOutlinedFrame(
|
||||
saveLROnStack(MBB, It);
|
||||
emitCFIForLRSaveOnStack(MBB, It);
|
||||
|
||||
// Fix up the instructions in the range, since we're going to modify the
|
||||
// stack.
|
||||
assert(OF.FrameConstructionID != MachineOutlinerDefault &&
|
||||
"Can only fix up stack references once");
|
||||
fixupPostOutline(MBB);
|
||||
|
||||
// Insert a restore before the terminator for the function. Restore LR.
|
||||
restoreLRFromStack(MBB, Et);
|
||||
emitCFIForLRRestoreFromStack(MBB, Et);
|
||||
@ -6289,6 +6420,15 @@ void ARMBaseInstrInfo::buildOutlinedFrame(
|
||||
// current feature set.
|
||||
BuildMI(MBB, MBB.end(), DebugLoc(), get(Subtarget.getReturnOpcode()))
|
||||
.add(predOps(ARMCC::AL));
|
||||
|
||||
// Did we have to modify the stack by saving the link register?
|
||||
if (OF.FrameConstructionID != MachineOutlinerDefault &&
|
||||
OF.Candidates[0].CallConstructionID != MachineOutlinerDefault)
|
||||
return;
|
||||
|
||||
// We modified the stack.
|
||||
// Walk over the basic block and fix up all the stack accesses.
|
||||
fixupPostOutline(MBB);
|
||||
}
|
||||
|
||||
MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
|
||||
@ -6345,6 +6485,8 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
|
||||
return CallPt;
|
||||
}
|
||||
// We have the default case. Save and restore from SP.
|
||||
if (!MBB.isLiveIn(ARM::LR))
|
||||
MBB.addLiveIn(ARM::LR);
|
||||
saveLROnStack(MBB, It);
|
||||
if (!AFI.isLRSpilled())
|
||||
emitCFIForLRSaveOnStack(MBB, It);
|
||||
|
@ -404,6 +404,16 @@ private:
|
||||
/// after the LR is was restored from a register.
|
||||
void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator It) const;
|
||||
/// \brief Sets the offsets on outlined instructions in \p MBB which use SP
|
||||
/// so that they will be valid post-outlining.
|
||||
///
|
||||
/// \param MBB A \p MachineBasicBlock in an outlined function.
|
||||
void fixupPostOutline(MachineBasicBlock &MBB) const;
|
||||
|
||||
/// Returns true if the machine instruction offset can handle the stack fixup
|
||||
/// and updates it if requested.
|
||||
bool checkAndUpdateStackOffset(MachineInstr *MI, int64_t Fixup,
|
||||
bool Updt) const;
|
||||
|
||||
unsigned getInstBundleLength(const MachineInstr &MI) const;
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
--- |
|
||||
define void @outline_default_arm() #0 { ret void }
|
||||
define void @outline_default_thumb() #1 { ret void }
|
||||
define void @outline_default_KO_stack_arm() #0 { ret void }
|
||||
define void @outline_default_KO_stack_thumb() #0 { ret void }
|
||||
declare void @bar()
|
||||
|
||||
attributes #0 = { minsize optsize }
|
||||
@ -113,121 +111,6 @@ body: |
|
||||
liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r2 = tMOVr $lr, 14, $noreg
|
||||
tBX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: outline_default_KO_stack_arm
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: outline_default_KO_stack_arm
|
||||
; CHECK: bb.0:
|
||||
; CHECK: liveins: $lr
|
||||
; CHECK: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.1:
|
||||
; CHECK: liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.2:
|
||||
; CHECK: liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.3:
|
||||
; CHECK: liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r2 = MOVr $lr, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: BX_RET 14 /* CC::al */, $noreg
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
$r0 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = MOVi 3, 14, $noreg, $noreg
|
||||
$r4 = MOVi 3, 14, $noreg, $noreg
|
||||
$r5 = MOVi 3, 14, $noreg, $noreg
|
||||
bb.1:
|
||||
liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r0 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = MOVi 3, 14, $noreg, $noreg
|
||||
$r4 = MOVi 3, 14, $noreg, $noreg
|
||||
$r5 = MOVi 3, 14, $noreg, $noreg
|
||||
bb.2:
|
||||
liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r0 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = MOVi 3, 14, $noreg, $noreg
|
||||
$r4 = MOVi 3, 14, $noreg, $noreg
|
||||
$r5 = MOVi 3, 14, $noreg, $noreg
|
||||
bb.3:
|
||||
liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r2 = MOVr $lr, 14, $noreg, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: outline_default_KO_stack_thumb
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: outline_default_KO_stack_thumb
|
||||
; CHECK: bb.0:
|
||||
; CHECK: liveins: $lr
|
||||
; CHECK: $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.1:
|
||||
; CHECK: liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.2:
|
||||
; CHECK: liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
|
||||
; CHECK: $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK: bb.3:
|
||||
; CHECK: liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
; CHECK: $r2 = tMOVr $lr, 14 /* CC::al */, $noreg
|
||||
; CHECK: tBX_RET 14 /* CC::al */, $noreg
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = t2MOVi 3, 14, $noreg, $noreg
|
||||
bb.1:
|
||||
liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = t2MOVi 3, 14, $noreg, $noreg
|
||||
bb.2:
|
||||
liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r1 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 3, 14, $noreg, $noreg
|
||||
$r3 = t2MOVi 3, 14, $noreg, $noreg
|
||||
bb.3:
|
||||
liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
$r2 = tMOVr $lr, 14, $noreg
|
||||
tBX_RET 14, $noreg
|
||||
|
||||
|
||||
; CHECK-LABEL: name: OUTLINED_FUNCTION_0
|
||||
; CHECK: bb.0:
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
--- |
|
||||
define void @outline_no_save_ok_arm() #0 { ret void }
|
||||
define void @outline_no_save_ko_arm() #0 { ret void }
|
||||
define void @outline_no_save_ok_thumb() #1 { ret void }
|
||||
define void @outline_no_save_ko_thumb() #1 { ret void }
|
||||
|
||||
declare void @foo()
|
||||
|
||||
@ -42,33 +40,6 @@ body: |
|
||||
...
|
||||
---
|
||||
|
||||
name: outline_no_save_ko_arm
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: outline_no_save_ko_arm
|
||||
; CHECK-NOT: OUTLINED_FUNCTION
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r3 = LDRi12 $sp, 8, 14, $noreg
|
||||
$r2 = MOVr $lr, 14, $noreg, $noreg
|
||||
bb.1:
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = MOVi 2, 14, $noreg, $noreg
|
||||
$r3 = LDRi12 $sp, 8, 14, $noreg
|
||||
$r4 = MOVi 4, 14, $noreg, $noreg
|
||||
BL @foo
|
||||
bb.2:
|
||||
liveins: $lr
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: outline_no_save_ok_thumb
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
@ -93,33 +64,6 @@ body: |
|
||||
t2STRi12 $r2, $sp, 0, 14, $noreg
|
||||
bb.2:
|
||||
tBX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: outline_no_save_ko_thumb
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
; CHECK-LABEL: name: outline_no_save_ko_thumb
|
||||
; CHECK-NOT: OUTLINED_FUNCTION
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
t2STRi12 $r2, $sp, 0, 14, $noreg
|
||||
$r2 = tMOVr $lr, 14, $noreg
|
||||
bb.1:
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
$r2 = t2MOVi 2, 14, $noreg, $noreg
|
||||
t2STRi12 $r2, $sp, 0, 14, $noreg
|
||||
$r4 = t2MOVi 3, 14, $noreg, $noreg
|
||||
tBL 14, $noreg, @foo
|
||||
bb.2:
|
||||
liveins: $lr, $r0, $r6, $r7, $r8, $r9, $r10, $r11
|
||||
tBX_RET 14, $noreg
|
||||
|
||||
; CHECK-LABEL: name: OUTLINED_FUNCTION_0
|
||||
; CHECK: bb.0:
|
||||
|
186
test/CodeGen/ARM/machine-outliner-stack-fixup-arm.mir
Normal file
186
test/CodeGen/ARM/machine-outliner-stack-fixup-arm.mir
Normal file
@ -0,0 +1,186 @@
|
||||
# RUN: llc -mtriple=armv7-- -run-pass=prologepilog -run-pass=machine-outliner \
|
||||
# RUN: -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
--- |
|
||||
define void @CheckAddrMode_i12() { ret void }
|
||||
define void @CheckAddrMode3() { ret void }
|
||||
define void @CheckAddrMode5() { ret void }
|
||||
define void @CheckAddrMode5FP16() { ret void }
|
||||
define void @foo() { ret void }
|
||||
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrMode_i12
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0
|
||||
; CHECK-LABEL: name: CheckAddrMode_i12
|
||||
; CHECK: $r1 = MOVr killed $r0, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK-NEXT: BL @OUTLINED_FUNCTION_[[I12:[0-9]+]]
|
||||
; CHECK-NEXT: $r6 = LDRi12 $sp, 4088, 14 /* CC::al */, $noreg
|
||||
$r1 = MOVr killed $r0, 14, $noreg, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r2 = LDRi12 $sp, 8, 14, $noreg
|
||||
$r5 = LDRi12 $sp, 4086, 14, $noreg
|
||||
$r6 = LDRi12 $sp, 4088, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r2 = LDRi12 $sp, 8, 14, $noreg
|
||||
$r5 = LDRi12 $sp, 4086, 14, $noreg
|
||||
$r6 = LDRi12 $sp, 4088, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRi12 $sp, 0, 14, $noreg
|
||||
$r2 = LDRi12 $sp, 8, 14, $noreg
|
||||
$r5 = LDRi12 $sp, 4086, 14, $noreg
|
||||
$r6 = LDRi12 $sp, 4088, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrMode3
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r1
|
||||
; CHECK-LABEL: name: CheckAddrMode3
|
||||
; CHECK: $r0 = MOVr killed $r1, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK-NEXT: BL @OUTLINED_FUNCTION_[[I3:[0-9]+]]
|
||||
; CHECK-NEXT: $r6 = LDRSH $sp, $noreg, 248, 14 /* CC::al */, $noreg
|
||||
$r0 = MOVr killed $r1, 14, $noreg, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRSH $sp, $noreg, 0, 14, $noreg
|
||||
$r2 = LDRSH $sp, $noreg, 8, 14, $noreg
|
||||
$r5 = LDRSH $sp, $noreg, 247, 14, $noreg
|
||||
$r6 = LDRSH $sp, $noreg, 248, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRSH $sp, $noreg, 0, 14, $noreg
|
||||
$r2 = LDRSH $sp, $noreg, 8, 14, $noreg
|
||||
$r5 = LDRSH $sp, $noreg, 247, 14, $noreg
|
||||
$r6 = LDRSH $sp, $noreg, 248, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = LDRSH $sp, $noreg, 0, 14, $noreg
|
||||
$r2 = LDRSH $sp, $noreg, 8, 14, $noreg
|
||||
$r5 = LDRSH $sp, $noreg, 247, 14, $noreg
|
||||
$r6 = LDRSH $sp, $noreg, 248, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrMode5
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r2
|
||||
; CHECK-LABEL: name: CheckAddrMode5
|
||||
; CHECK: $r0 = MOVr killed $r2, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK-NEXT: BL @OUTLINED_FUNCTION_[[I5:[0-9]+]]
|
||||
; CHECK-NEXT: $d5 = VLDRD $sp, 254, 14 /* CC::al */, $noreg
|
||||
$r0 = MOVr killed $r2, 14, $noreg, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$d0 = VLDRD $sp, 0, 14, $noreg
|
||||
$d1 = VLDRD $sp, 8, 14, $noreg
|
||||
$d4 = VLDRD $sp, 253, 14, $noreg
|
||||
$d5 = VLDRD $sp, 254, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$d0 = VLDRD $sp, 0, 14, $noreg
|
||||
$d1 = VLDRD $sp, 8, 14, $noreg
|
||||
$d4 = VLDRD $sp, 253, 14, $noreg
|
||||
$d5 = VLDRD $sp, 254, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$d0 = VLDRD $sp, 0, 14, $noreg
|
||||
$d1 = VLDRD $sp, 8, 14, $noreg
|
||||
$d4 = VLDRD $sp, 253, 14, $noreg
|
||||
$d5 = VLDRD $sp, 254, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$d0 = VLDRD $sp, 0, 14, $noreg
|
||||
$d1 = VLDRD $sp, 8, 14, $noreg
|
||||
$d4 = VLDRD $sp, 253, 14, $noreg
|
||||
$d5 = VLDRD $sp, 254, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrMode5FP16
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r3
|
||||
; CHECK-LABEL: name: CheckAddrMode5FP16
|
||||
; CHECK: $r0 = MOVr killed $r3, 14 /* CC::al */, $noreg, $noreg
|
||||
; CHECK-NEXT: BL @OUTLINED_FUNCTION_[[I5FP16:[0-9]+]]
|
||||
; CHECK-NEXT: $s6 = VLDRH $sp, 252, 14, $noreg
|
||||
$r0 = MOVr killed $r3, 14, $noreg, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$s1 = VLDRH $sp, 0, 14, $noreg
|
||||
$s2 = VLDRH $sp, 8, 14, $noreg
|
||||
$s5 = VLDRH $sp, 240, 14, $noreg
|
||||
$s6 = VLDRH $sp, 252, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$s1 = VLDRH $sp, 0, 14, $noreg
|
||||
$s2 = VLDRH $sp, 8, 14, $noreg
|
||||
$s5 = VLDRH $sp, 240, 14, $noreg
|
||||
$s6 = VLDRH $sp, 252, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$s1 = VLDRH $sp, 0, 14, $noreg
|
||||
$s2 = VLDRH $sp, 8, 14, $noreg
|
||||
$s5 = VLDRH $sp, 240, 14, $noreg
|
||||
$s6 = VLDRH $sp, 252, 14, $noreg
|
||||
BL @foo, implicit-def dead $lr, implicit $sp
|
||||
$s1 = VLDRH $sp, 0, 14, $noreg
|
||||
$s2 = VLDRH $sp, 8, 14, $noreg
|
||||
$s5 = VLDRH $sp, 240, 14, $noreg
|
||||
$s6 = VLDRH $sp, 252, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: foo
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
|
||||
BX_RET 14, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I5]]
|
||||
;CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: BL @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $d0 = VLDRD $sp, 2, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $d1 = VLDRD $sp, 10, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $d4 = VLDRD $sp, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I5FP16]]
|
||||
;CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: BL @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $s1 = VLDRH $sp, 4, 14, $noreg
|
||||
;CHECK-NEXT: $s2 = VLDRH $sp, 12, 14, $noreg
|
||||
;CHECK-NEXT: $s5 = VLDRH $sp, 244, 14, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I12]]
|
||||
;CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: BL @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $r1 = LDRi12 $sp, 8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r2 = LDRi12 $sp, 16, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r5 = LDRi12 $sp, 4094, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I3]]
|
||||
;CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: BL @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $r1 = LDRSH $sp, $noreg, 8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r2 = LDRSH $sp, $noreg, 16, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r5 = LDRSH $sp, $noreg, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
|
231
test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
Normal file
231
test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
Normal file
@ -0,0 +1,231 @@
|
||||
# RUN: llc -mtriple=thumbv7-- -run-pass=prologepilog \
|
||||
# RUN: -run-pass=machine-outliner %s -o - | FileCheck %s
|
||||
|
||||
--- |
|
||||
define void @CheckAddrModeT2_i12() { ret void }
|
||||
define void @CheckAddrModeT2_i8() { ret void }
|
||||
define void @CheckAddrModeT2_i8s4() { ret void }
|
||||
define void @CheckAddrModeT2_ldrex() { ret void }
|
||||
define void @CheckAddrModeT1_s() { ret void }
|
||||
define void @foo() { ret void }
|
||||
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrModeT2_i12
|
||||
tracksRegLiveness: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r1
|
||||
;CHECK-LABEL: name: CheckAddrModeT2_i12
|
||||
;CHECK: $r0 = tMOVr killed $r1, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I12:[0-9]+]]
|
||||
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 4088, 14 /* CC::al */, $noreg
|
||||
$r0 = tMOVr killed $r1, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
||||
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrModeT2_i8
|
||||
tracksRegLiveness: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r1
|
||||
;CHECK-LABEL: name: CheckAddrModeT2_i8
|
||||
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I8:[0-9]+]]
|
||||
;CHECK-NEXT: t2STRHi8 $r0, $sp, 248, 14 /* CC::al */, $noreg
|
||||
$r0 = tMOVr $r1, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
||||
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrModeT2_i8s4
|
||||
tracksRegLiveness: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r1
|
||||
;CHECK-LABEL: name: CheckAddrModeT2_i8s4
|
||||
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I8S4:[0-9]+]]
|
||||
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 254, 14 /* CC::al */, $noreg
|
||||
$r0 = tMOVr $r1, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
||||
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrModeT2_ldrex
|
||||
tracksRegLiveness: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r1
|
||||
;CHECK-LABEL: name: CheckAddrModeT2_ldrex
|
||||
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[LDREX:[0-9]+]]
|
||||
;CHECK-NEXT: $r1 = t2LDREX $sp, 254, 14 /* CC::al */, $noreg
|
||||
$r0 = tMOVr $r1, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = t2LDREX $sp, 0, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 8, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 253, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = t2LDREX $sp, 0, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 8, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 253, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = t2LDREX $sp, 0, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 8, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 253, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
$r1 = t2LDREX $sp, 0, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 8, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 253, 14, $noreg
|
||||
$r1 = t2LDREX $sp, 254, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: CheckAddrModeT1_s
|
||||
tracksRegLiveness: true
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $r0, $r1
|
||||
;CHECK-LABEL: name: CheckAddrModeT1_s
|
||||
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[T1_S:[0-9]+]]
|
||||
;CHECK-NEXT: tSTRspi $r0, $sp, 254, 14 /* CC::al */, $noreg
|
||||
$r0 = tMOVr $r1, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
tSTRspi $r0, $sp, 0, 14, $noreg
|
||||
tSTRspi $r0, $sp, 4, 14, $noreg
|
||||
tSTRspi $r0, $sp, 253, 14, $noreg
|
||||
tSTRspi $r0, $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
tSTRspi $r0, $sp, 0, 14, $noreg
|
||||
tSTRspi $r0, $sp, 4, 14, $noreg
|
||||
tSTRspi $r0, $sp, 253, 14, $noreg
|
||||
tSTRspi $r0, $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
tSTRspi $r0, $sp, 0, 14, $noreg
|
||||
tSTRspi $r0, $sp, 4, 14, $noreg
|
||||
tSTRspi $r0, $sp, 253, 14, $noreg
|
||||
tSTRspi $r0, $sp, 254, 14, $noreg
|
||||
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
tSTRspi $r0, $sp, 0, 14, $noreg
|
||||
tSTRspi $r0, $sp, 4, 14, $noreg
|
||||
tSTRspi $r0, $sp, 253, 14, $noreg
|
||||
tSTRspi $r0, $sp, 254, 14, $noreg
|
||||
BX_RET 14, $noreg
|
||||
...
|
||||
---
|
||||
|
||||
name: foo
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: $lr
|
||||
|
||||
BX_RET 14, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[LDREX]]
|
||||
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $r1 = t2LDREX $sp, 2, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r1 = t2LDREX $sp, 10, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r1 = t2LDREX $sp, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I8]]
|
||||
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: t2STRHi8 $r0, $sp, 8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: t2STRHi8 $r0, $sp, 12, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: t2STRHi8 $r0, $sp, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I8S4]]
|
||||
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 2, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 10, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[I12]]
|
||||
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 12, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 4094, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
||||
|
||||
;CHECK: name: OUTLINED_FUNCTION_[[T1_S]]
|
||||
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
||||
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
||||
;CHECK-NEXT: tSTRspi $r0, $sp, 2, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tSTRspi $r0, $sp, 6, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: tSTRspi $r0, $sp, 255, 14 /* CC::al */, $noreg
|
||||
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
@ -1,6 +1,4 @@
|
||||
; RUN: llc -enable-machine-outliner -mtriple=arm-unknown-linux < %s | FileCheck %s
|
||||
;
|
||||
; NOTE: Machine outliner runs, but doesn't do anything.
|
||||
@x = global i32 0, align 4
|
||||
|
||||
define dso_local i32 @check_boundaries() #0 {
|
||||
|
@ -1,6 +1,5 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs
|
||||
; RUN: llc -enable-machine-outliner -mtriple=arm-unknown-linux < %s | FileCheck %s
|
||||
; NOTE: Machine outliner runs, but doesn't do anything.
|
||||
@x = global i32 0, align 4
|
||||
|
||||
define dso_local i32 @check_boundaries() #0 {
|
||||
@ -76,14 +75,9 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: b .LBB0_3
|
||||
; CHECK-NEXT: .LBB0_2:
|
||||
; CHECK-NEXT: mov r0, #2
|
||||
; CHECK-NEXT: str r0, [sp, #8]
|
||||
; CHECK-NEXT: mov r0, #1
|
||||
; CHECK-NEXT: str r0, [sp, #12]
|
||||
; CHECK-NEXT: mov r0, #3
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: mov r0, #4
|
||||
; CHECK-NEXT: str r0, [sp]
|
||||
; CHECK-NEXT: mov r1, lr
|
||||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
|
||||
; CHECK-NEXT: mov lr, r1
|
||||
; CHECK-NEXT: .LBB0_3:
|
||||
; CHECK-NEXT: ldr r0, [sp, #12]
|
||||
; CHECK-NEXT: cmp r0, #0
|
||||
@ -93,14 +87,9 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: b .LBB0_6
|
||||
; CHECK-NEXT: .LBB0_5:
|
||||
; CHECK-NEXT: mov r0, #2
|
||||
; CHECK-NEXT: str r0, [sp, #8]
|
||||
; CHECK-NEXT: mov r0, #1
|
||||
; CHECK-NEXT: str r0, [sp, #12]
|
||||
; CHECK-NEXT: mov r0, #3
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: mov r0, #4
|
||||
; CHECK-NEXT: str r0, [sp]
|
||||
; CHECK-NEXT: mov r1, lr
|
||||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
|
||||
; CHECK-NEXT: mov lr, r1
|
||||
; CHECK-NEXT: .LBB0_6:
|
||||
; CHECK-NEXT: mov r0, #0
|
||||
; CHECK-NEXT: add sp, sp, #20
|
||||
@ -134,3 +123,15 @@ attributes #0 = { noredzone nounwind ssp uwtable "frame-pointer"="all" }
|
||||
; CHECK-NEXT: @ %bb.1:
|
||||
; CHECK-NEXT: .LCPI1_0:
|
||||
; CHECK-NEXT: .long x
|
||||
;
|
||||
; CHECK-LABEL: OUTLINED_FUNCTION_0:
|
||||
; CHECK: @ %bb.0:
|
||||
; CHECK-NEXT: mov r0, #2
|
||||
; CHECK-NEXT: str r0, [sp, #8]
|
||||
; CHECK-NEXT: mov r0, #1
|
||||
; CHECK-NEXT: str r0, [sp, #12]
|
||||
; CHECK-NEXT: mov r0, #3
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: mov r0, #4
|
||||
; CHECK-NEXT: str r0, [sp]
|
||||
; CHECK-NEXT: mov pc, lr
|
||||
|
@ -1,7 +1,5 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -enable-machine-outliner -mtriple=arm-unknown-linux < %s | FileCheck %s
|
||||
;
|
||||
; NOTE: Machine outliner runs, but doesn't do anything.
|
||||
@x = global i32 0, align 4
|
||||
|
||||
define dso_local i32 @check_boundaries() #0 {
|
||||
@ -18,14 +16,9 @@ define dso_local i32 @check_boundaries() #0 {
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: b .LBB0_3
|
||||
; CHECK-NEXT: .LBB0_2:
|
||||
; CHECK-NEXT: mov r0, #2
|
||||
; CHECK-NEXT: str r0, [sp, #8]
|
||||
; CHECK-NEXT: mov r0, #1
|
||||
; CHECK-NEXT: str r0, [sp, #12]
|
||||
; CHECK-NEXT: mov r0, #3
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: mov r0, #4
|
||||
; CHECK-NEXT: str r0, [sp]
|
||||
; CHECK-NEXT: mov r1, lr
|
||||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
|
||||
; CHECK-NEXT: mov lr, r1
|
||||
; CHECK-NEXT: .LBB0_3:
|
||||
; CHECK-NEXT: ldr r0, [sp, #12]
|
||||
; CHECK-NEXT: cmp r0, #0
|
||||
@ -35,14 +28,9 @@ define dso_local i32 @check_boundaries() #0 {
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: b .LBB0_6
|
||||
; CHECK-NEXT: .LBB0_5:
|
||||
; CHECK-NEXT: mov r0, #2
|
||||
; CHECK-NEXT: str r0, [sp, #8]
|
||||
; CHECK-NEXT: mov r0, #1
|
||||
; CHECK-NEXT: str r0, [sp, #12]
|
||||
; CHECK-NEXT: mov r0, #3
|
||||
; CHECK-NEXT: str r0, [sp, #4]
|
||||
; CHECK-NEXT: mov r0, #4
|
||||
; CHECK-NEXT: str r0, [sp]
|
||||
; CHECK-NEXT: mov r1, lr
|
||||
; CHECK-NEXT: bl OUTLINED_FUNCTION_0
|
||||
; CHECK-NEXT: mov lr, r1
|
||||
; CHECK-NEXT: .LBB0_6:
|
||||
; CHECK-NEXT: mov r0, #0
|
||||
; CHECK-NEXT: add sp, sp, #20
|
||||
|
Loading…
x
Reference in New Issue
Block a user