[WinEH] Push and pop EBP for 32-bit funclets

The Win32 EH runtime caller does not preserve EBP, even though it does
preserve the CSRs (EBX, ESI, EDI) for us. The result was that each
finally funclet call would leave the frame pointer off by 12 bytes.

llvm-svn: 247348
This commit is contained in:
Reid Kleckner 2015-09-10 22:00:02 +00:00
parent 82f01fab24
commit 22d50caa1c
4 changed files with 24 additions and 8 deletions

View File

@ -702,6 +702,11 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
// Set up the FramePtr and BasePtr physical registers using the address
// passed as EBP or RDX by the MSVC EH runtime.
if (STI.is32Bit()) {
// PUSH32r %ebp
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
.addReg(MachineFramePtr, RegState::Kill)
.setMIFlag(MachineInstr::FrameSetup);
// Reset EBP / ESI to something good.
MBBI = restoreWin32EHFrameAndBasePtr(MBB, MBBI, DL);
} else {
// FIXME: Add SEH directives.
@ -715,7 +720,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
.addReg(RDX)
.setMIFlag(MachineInstr::FrameSetup);
// PUSH64r %rbp
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r))
.addReg(MachineFramePtr, RegState::Kill)
.setMIFlag(MachineInstr::FrameSetup);
// MOV64rr %rdx, %rbp
@ -1066,13 +1071,11 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
if (isFuncletReturnInstr(MBBI)) {
NumBytes = MFI->getMaxCallFrameSize();
assert(hasFP(MF) && "win64 EH funclets without FP not yet implemented");
if (Is64Bit) {
assert(hasFP(MF) && "win64 EH funclets without FP not yet implemented");
// POP64r %rbp
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr);
}
// Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr);
} else if (hasFP(MF)) {
// Calculate required stack adjustment.
uint64_t FrameSize = StackSize - SlotSize;

View File

@ -73,6 +73,7 @@ catchendblock: ; preds = %catch,
; X86: retl
; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
; X86: pushl %ebp
; X86-NOT: pushl
; X86: addl $12, %ebp
; X86: subl $16, %esp
@ -81,7 +82,7 @@ catchendblock: ; preds = %catch,
; X86: calll _f
; X86: movl $[[contbb]], %eax
; X86-NEXT: addl $16, %esp
; X86-NOT: popl
; X86-NEXT: popl %ebp
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:

View File

@ -76,6 +76,7 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86: retl
; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
; X86: pushl %ebp
; X86: addl $12, %ebp
; X86: subl $8, %esp
; X86: movl $1, -{{[0-9]+}}(%ebp)
@ -85,9 +86,11 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86: calll _f
; X86: movl $[[contbb]], %eax
; X86-NEXT: addl $8, %esp
; X86-NEXT: popl %ebp
; X86-NEXT: retl
; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
; X86: pushl %ebp
; X86: addl $12, %ebp
; X86: subl $8, %esp
; X86: movl $1, -{{[0-9]+}}(%ebp)
@ -97,6 +100,7 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86: calll _f
; X86: movl $[[contbb]], %eax
; X86-NEXT: addl $8, %esp
; X86-NEXT: popl %ebp
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:

View File

@ -63,14 +63,22 @@ attributes #3 = { noinline }
; CHECK: retl
; CHECK: LBB0_[[inner:[0-9]+]]: # %ehcleanup
; CHECK: pushl %ebp
; CHECK: addl $12, %ebp
; CHECK: movl $0, -[[state]](%ebp)
; CHECK: movl $2, (%esp)
; CHECK: calll _f
; CHECK: popl %ebp
; CHECK: retl
; CHECK: LBB0_[[outer:[0-9]+]]: # %ehcleanup.3
; CHECK: pushl %ebp
; CHECK: addl $12, %ebp
; CHECK: movl $-1, -[[state]](%ebp)
; CHECK: movl $3, (%esp)
; CHECK: calll _f
; CHECK: popl %ebp
; CHECK: retl
; CHECK: L__ehtable$nested_finally:
; CHECK: .long -1