Functions calling __builtin_eh_return must have a frame pointer.

The code in X86TargetLowering::LowerEH_RETURN() assumes that a frame
pointer exists, but the frame pointer was forced by the presence of
llvm.eh.unwind.init which isn't guaranteed.

If llvm.eh.unwind.init is actually required in functions calling
eh.return (is it?), we should diagnose that instead of emitting bad
machine code.

This should fix the dragonegg-x86_64-linux-gcc-4.6-test bot.

llvm-svn: 158961
This commit is contained in:
Jakob Stoklund Olesen 2012-06-22 03:04:27 +00:00
parent 77d0b88999
commit 321d41a871
2 changed files with 25 additions and 4 deletions

View File

@ -52,7 +52,7 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
MFI->hasVarSizedObjects() ||
MFI->isFrameAddressTaken() ||
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
MMI.callsUnwindInit());
MMI.callsUnwindInit() || MMI.callsEHReturn());
}
static unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) {

View File

@ -1,15 +1,36 @@
; Check that eh_return & unwind_init were properly lowered
; RUN: llc < %s | grep %ebp | count 9
; RUN: llc < %s | grep %ecx | count 5
; RUN: llc < %s -verify-machineinstrs | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
target triple = "i386-pc-linux"
define i8* @test(i32 %a, i8* %b) {
; CHECK: test1
; CHECK: pushl %ebp
define i8* @test1(i32 %a, i8* %b) {
entry:
call void @llvm.eh.unwind.init()
%foo = alloca i32
call void @llvm.eh.return.i32(i32 %a, i8* %b)
; CHECK: movl 12(%ebp), %[[ECX:e..]]
; CHECK: movl 8(%ebp), %[[EAX:e..]]
; CHECK: movl %[[ECX]], 4(%ebp,%[[EAX]])
; CHECK: leal 4(%ebp,%[[EAX]]), %[[ECX2:e..]]
; CHECK: movl %[[ECX2]], %esp
; CHECK: ret
unreachable
}
; CHECK: test2
; CHECK: pushl %ebp
define i8* @test2(i32 %a, i8* %b) {
entry:
call void @llvm.eh.return.i32(i32 %a, i8* %b)
; CHECK: movl 12(%ebp), %[[ECX:e..]]
; CHECK: movl 8(%ebp), %[[EAX:e..]]
; CHECK: movl %[[ECX]], 4(%ebp,%[[EAX]])
; CHECK: leal 4(%ebp,%[[EAX]]), %[[ECX2:e..]]
; CHECK: movl %[[ECX2]], %esp
; CHECK: ret
unreachable
}