ARM: correctly determine final tBX_LR in Thumb1 functions

The changes caused by folding an sp-adjustment into a "pop" previously
disrupted the forward search for the final real instruction in a
terminating block. This switches to a backward search (skipping debug
instrs).

This fixes PR18399.

Patch by Zhaoshi.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199266 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2014-01-14 22:53:28 +00:00
parent 4e1247b836
commit 196c8e5fbb
2 changed files with 26 additions and 3 deletions

View File

@ -304,9 +304,9 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
// we need to update the SP after popping the value. Therefore, we
// pop the old LR into R3 as a temporary.
// Move back past the callee-saved register restoration
while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs))
++MBBI;
// Get the last instruction, tBX_RET
MBBI = MBB.getLastNonDebugInstr();
assert (MBBI->getOpcode() == ARM::tBX_RET);
// Epilogue for vararg functions: pop LR to R3 and branch off it.
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
.addReg(ARM::R3, RegState::Define);

View File

@ -162,3 +162,26 @@ end:
; the correct edge-case (first inst in block is correct one to adjust).
ret void
}
define void @test_varsize(...) minsize {
; CHECK-T1-LABEL: test_varsize:
; CHECK-T1: sub sp, #16
; CHECK-T1: push {r2, r3, r4, r5, r7, lr}
; ...
; CHECK-T1: pop {r2, r3, r4, r5, r7}
; CHECK-T1: pop {r3}
; CHECK-T1: add sp, #16
; CHECK-T1: bx r3
; CHECK-LABEL: test_varsize:
; CHECK: sub sp, #16
; CHECK: push {r5, r6, r7, lr}
; ...
; CHECK: pop.w {r2, r3, r7, lr}
; CHECK: add sp, #16
; CHECK: bx lr
%var = alloca i8, i32 8
call void @bar(i8* %var)
ret void
}