1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 04:22:57 +02:00

[WinEH] Give up on using CSRs across 32-bit invokes for now

The runtime does not restore CSRs when transferring control back to the
function handling the exception. According to the experts on IRC, LLVM's
register allocator has no way to model register clobbers that only
happen on one edge of the CFG. For now, don't worry about trying to use
the meager three CSRs available on 32-bit X86 and just say that such
invokes preserve nothing.

llvm-svn: 241865
This commit is contained in:
Reid Kleckner 2015-07-09 22:09:41 +00:00
parent 620d7274c1
commit 733508d4e8
3 changed files with 54 additions and 25 deletions

View File

@ -3258,9 +3258,24 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
RegsToPass[i].second.getValueType()));
// Add a register mask operand representing the call-preserved registers.
const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv);
assert(Mask && "Missing call preserved mask for calling convention");
// If this is an invoke in a 32-bit function using an MSVC personality, assume
// the function clobbers all registers. If an exception is thrown, the runtime
// will not restore CSRs.
// FIXME: Model this more precisely so that we can register allocate across
// the normal edge and spill and fill across the exceptional edge.
if (!Is64Bit && CLI.CS && CLI.CS->isInvoke()) {
const Function *CallerFn = MF.getFunction();
EHPersonality Pers =
CallerFn->hasPersonalityFn()
? classifyEHPersonality(CallerFn->getPersonalityFn())
: EHPersonality::Unknown;
if (isMSVCEHPersonality(Pers))
Mask = RegInfo->getNoPreservedMask();
}
Ops.push_back(DAG.getRegisterMask(Mask));
if (InFlag.getNode())

View File

@ -59,20 +59,31 @@ entry:
; Check that we can get the exception code from eax to the printf.
; CHECK-LABEL: _main:
; CHECK: pushl %ebp
; CHECK: movl %esp, %ebp
; Ensure that we push *all* the CSRs, since they are clobbered by the
; __except block.
; CHECK: pushl %ebx
; CHECK: pushl %edi
; CHECK: pushl %esi
; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
; CHECK: movl %esp, [[reg_offs]](%ebp)
; CHECK: movl $L__ehtable$main,
; EH state 0
; CHECK: movl $0, -4(%ebp)
; CHECK: movl $0, -16(%ebp)
; CHECK: calll _crash
; CHECK: popl %esi
; CHECK: popl %edi
; CHECK: popl %ebx
; CHECK: retl
; CHECK: # Block address taken
; stackrestore
; CHECK: movl [[reg_offs]](%ebp), %esp
; CHECK: movl -24(%ebp), %esp
; EH state -1
; CHECK: movl [[code_offs]](%ebp), %[[code:[a-z]+]]
; CHECK: movl $-1, -4(%ebp)
; CHECK: movl $-1, -16(%ebp)
; CHECK-DAG: movl %[[code]], 4(%esp)
; CHECK-DAG: movl $_str, (%esp)
; CHECK: calll _printf

View File

@ -32,16 +32,19 @@ eh.resume:
; CHECK-LABEL: _use_except_handler3:
; CHECK: pushl %ebp
; CHECK: movl %esp, %ebp
; CHECK: pushl %ebx
; CHECK: pushl %edi
; CHECK: pushl %esi
; CHECK: subl ${{[0-9]+}}, %esp
; CHECK: movl $-1, -4(%ebp)
; CHECK: movl $L__ehtable$use_except_handler3, -8(%ebp)
; CHECK: leal -16(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $__except_handler3, -12(%ebp)
; CHECK: movl $-1, -16(%ebp)
; CHECK: movl $L__ehtable$use_except_handler3, -20(%ebp)
; CHECK: leal -28(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $__except_handler3, -24(%ebp)
; CHECK: movl %fs:0, %[[next:[^ ,]*]]
; CHECK: movl %[[next]], -16(%ebp)
; CHECK: movl %[[next]], -28(%ebp)
; CHECK: movl %[[node]], %fs:0
; CHECK: calll _may_throw_or_crash
; CHECK: movl -16(%ebp), %[[next:[^ ,]*]]
; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
; CHECK: movl %[[next]], %fs:0
; CHECK: retl
@ -72,18 +75,18 @@ eh.resume:
; CHECK: pushl %ebp
; CHECK: movl %esp, %ebp
; CHECK: subl ${{[0-9]+}}, %esp
; CHECK: movl %esp, -24(%ebp)
; CHECK: movl $-2, -4(%ebp)
; CHECK: movl %esp, -36(%ebp)
; CHECK: movl $-2, -16(%ebp)
; CHECK: movl $L__ehtable$use_except_handler4, %[[lsda:[^ ,]*]]
; CHECK: xorl ___security_cookie, %[[lsda]]
; CHECK: movl %[[lsda]], -8(%ebp)
; CHECK: leal -16(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $__except_handler4, -12(%ebp)
; CHECK: movl %[[lsda]], -20(%ebp)
; CHECK: leal -28(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $__except_handler4, -24(%ebp)
; CHECK: movl %fs:0, %[[next:[^ ,]*]]
; CHECK: movl %[[next]], -16(%ebp)
; CHECK: movl %[[next]], -28(%ebp)
; CHECK: movl %[[node]], %fs:0
; CHECK: calll _may_throw_or_crash
; CHECK: movl -16(%ebp), %[[next:[^ ,]*]]
; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
; CHECK: movl %[[next]], %fs:0
; CHECK: retl
@ -115,16 +118,16 @@ catchall:
; CHECK: pushl %ebp
; CHECK: movl %esp, %ebp
; CHECK: subl ${{[0-9]+}}, %esp
; CHECK: movl %esp, -16(%ebp)
; CHECK: movl $-1, -4(%ebp)
; CHECK: leal -12(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $___ehhandler$use_CxxFrameHandler3, -8(%ebp)
; CHECK: movl %esp, -28(%ebp)
; CHECK: movl $-1, -16(%ebp)
; CHECK: leal -24(%ebp), %[[node:[^ ,]*]]
; CHECK: movl $___ehhandler$use_CxxFrameHandler3, -20(%ebp)
; CHECK: movl %fs:0, %[[next:[^ ,]*]]
; CHECK: movl %[[next]], -12(%ebp)
; CHECK: movl %[[next]], -24(%ebp)
; CHECK: movl %[[node]], %fs:0
; CHECK: movl $0, -4(%ebp)
; CHECK: movl $0, -16(%ebp)
; CHECK: calll _may_throw_or_crash
; CHECK: movl -12(%ebp), %[[next:[^ ,]*]]
; CHECK: movl -24(%ebp), %[[next:[^ ,]*]]
; CHECK: movl %[[next]], %fs:0
; CHECK: retl