Skip to content

Commit

Permalink
[ARM CodeGen] @llvm.debugtrap call may be removed when restoring call…
Browse files Browse the repository at this point in the history
…ee saved registers

Summary:
When ARMFrameLowering::emitPopInst generates a "pop" instruction to restore the callee saved registers, it checks if the LR register is among them. If so, the function may decide to remove the basic block's terminator and replace it with a "pop" to the PC register instead of LR.

This leads to a problem when the block's terminator is preceded by a "llvm.debugtrap" call. The MI iterator points to the trap in such a case, which is also a terminator. If the function decides to restore LR to PC, it erroneously removes the trap.

Reviewers: asl, rengolin

Subscribers: aemerson, jfb, rengolin, dschuff, llvm-commits

Differential Revision: http://reviews.llvm.org/D13672

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251123 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
o-ran committed Oct 23, 2015
1 parent cd69ab5 commit f1c1676
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/Target/ARM/ARMFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,12 +968,16 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
DebugLoc DL;
bool isTailCall = false;
bool isInterrupt = false;
bool isTrap = false;
if (MBB.end() != MI) {
DL = MI->getDebugLoc();
unsigned RetOpcode = MI->getOpcode();
isTailCall = (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri);
isInterrupt =
RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
isTrap =
RetOpcode == ARM::TRAP || RetOpcode == ARM::TRAPNaCl ||
RetOpcode == ARM::tTRAP;
}

SmallVector<unsigned, 4> Regs;
Expand All @@ -990,7 +994,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
continue;

if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
STI.hasV5TOps()) {
!isTrap && STI.hasV5TOps()) {
if (MBB.succ_empty()) {
Reg = ARM::PC;
DeleteRet = true;
Expand Down
17 changes: 17 additions & 0 deletions test/CodeGen/ARM/debugtrap.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; This test ensures the @llvm.debugtrap() call is not removed when generating
; the 'pop' instruction to restore the callee saved registers on ARM.

; RUN: llc < %s -mtriple=armv7 -O0 -filetype=asm | FileCheck %s

declare void @llvm.debugtrap() nounwind
declare void @foo() nounwind

define void @test() nounwind {
entry:
; CHECK: bl foo
; CHECK-NEXT: pop
; CHECK-NEXT: trap
call void @foo()
call void @llvm.debugtrap()
ret void
}

0 comments on commit f1c1676

Please sign in to comment.