From 7db72f8f999dba2d5e0573f57cc28c42b4b4dbba Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 8 Oct 2015 18:41:52 +0000 Subject: [PATCH] [WinEH] Relax assertion in the presence of stack realignment The code is correct as is, but we should test it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249715 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86FrameLowering.cpp | 10 +-- .../CodeGen/X86/win32-seh-catchpad-realign.ll | 80 +++++++++++++++++++ 2 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/win32-seh-catchpad-realign.ll diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 7f05e5b3b13..f63be63efed 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -2178,12 +2178,9 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers( int EHRegOffset = getFrameIndexReference(MF, FI, UsedReg); int EndOffset = -EHRegOffset - EHRegSize; FuncInfo.EHRegNodeEndOffset = EndOffset; - assert(EndOffset >= 0 && - "end of registration object above normal EBP position!"); if (UsedReg == FramePtr) { // ADD $offset, %ebp - assert(UsedReg == FramePtr); unsigned ADDri = getADDriOpcode(false, EndOffset); BuildMI(MBB, MBBI, DL, TII.get(ADDri), FramePtr) .addReg(FramePtr) @@ -2191,8 +2188,9 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers( .setMIFlag(MachineInstr::FrameSetup) ->getOperand(3) .setIsDead(); - } else { - assert(UsedReg == BasePtr); + assert(EndOffset >= 0 && + "end of registration object above normal EBP position!"); + } else if (UsedReg == BasePtr) { // LEA offset(%ebp), %esi addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::LEA32r), BasePtr), FramePtr, false, EndOffset) @@ -2205,6 +2203,8 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers( addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32rm), FramePtr), UsedReg, true, Offset) .setMIFlag(MachineInstr::FrameSetup); + } else { + llvm_unreachable("32-bit frames with WinEH must use FramePtr or BasePtr"); } return MBBI; } diff --git a/test/CodeGen/X86/win32-seh-catchpad-realign.ll b/test/CodeGen/X86/win32-seh-catchpad-realign.ll new file mode 100644 index 00000000000..9cc9118965c --- /dev/null +++ b/test/CodeGen/X86/win32-seh-catchpad-realign.ll @@ -0,0 +1,80 @@ +; RUN: llc < %s | FileCheck %s + +; The aligned alloca means that we have to realign the stack, which forces the +; use of ESI to address local variables. + +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686--windows-msvc" + +; Function Attrs: nounwind +define void @realigned_try() personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) { +entry: + %x = alloca [4 x i32], align 16 + %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %x, i32 0, i32 0 + invoke void @useit(i32* %arrayidx) + to label %__try.cont unwind label %catch.dispatch + +catch.dispatch: ; preds = %entry + %pad = catchpad [i8* bitcast (i32 ()* @"\01?filt$0@0@realigned_try@@" to i8*)] + to label %__except.ret unwind label %catchendblock + +__except.ret: ; preds = %catch.dispatch + catchret %pad to label %__try.cont + +__try.cont: ; preds = %entry, %__except.ret + ret void + +catchendblock: ; preds = %catch.dispatch + catchendpad unwind to caller +} + +; Function Attrs: nounwind argmemonly + +; Function Attrs: nounwind +define internal i32 @"\01?filt$0@0@realigned_try@@"() { +entry: + ret i32 1 +} + +declare void @useit(i32*) + +declare i32 @_except_handler3(...) + +; CHECK-LABEL: _realigned_try: +; Prologue +; CHECK: pushl %ebp +; CHECK: movl %esp, %ebp +; CHECK: pushl %ebx +; CHECK: pushl %edi +; CHECK: pushl %esi +; CHECK: andl $-16, %esp +; CHECK: subl $64, %esp +; CHECK: movl %esp, %esi +; Spill EBP +; CHECK: movl %ebp, 12(%esi) +; Spill ESP +; CHECK: movl %esp, 36(%esi) +; The state is stored at ESI+56, the end of the node is ESI+60. +; CHECK: movl $-1, 56(%esi) +; +; __try +; CHECK: calll _useit +; +; Epilogue +; CHECK: LBB0_1: # %__try.cont +; CHECK: leal -12(%ebp), %esp +; CHECK: popl %esi +; CHECK: popl %edi +; CHECK: popl %ebx +; CHECK: popl %ebp +; CHECK: retl +; +; CHECK: LBB0_2: # %catch.dispatch +; Restore ESP +; CHECK: movl -24(%ebp), %esp +; Recompute ESI by subtracting 60 from the end of the registration node. +; CHECK: leal -60(%ebp), %esi +; Restore EBP +; CHECK: movl 12(%esi), %ebp +; Rejoin normal control flow +; CHECK: jmp LBB0_1 -- 2.34.1