diff options
author | Reid Kleckner <rnk@google.com> | 2015-10-08 18:41:52 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-10-08 18:41:52 +0000 |
commit | b2244cb8f07d1cfe592d91532dfaf0804f662200 (patch) | |
tree | efaa967f36e8bb4e139e0b3c256c810bfe3ab5ea | |
parent | e5d3ac8240f817ed40948b7f41c0fc69efd47679 (diff) | |
download | bcm5719-llvm-b2244cb8f07d1cfe592d91532dfaf0804f662200.tar.gz bcm5719-llvm-b2244cb8f07d1cfe592d91532dfaf0804f662200.zip |
[WinEH] Relax assertion in the presence of stack realignment
The code is correct as is, but we should test it.
llvm-svn: 249715
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll | 80 |
2 files changed, 85 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 7f05e5b3b13..f63be63efed 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/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/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll b/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll new file mode 100644 index 00000000000..9cc9118965c --- /dev/null +++ b/llvm/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 |