[SEH] Update SEH codegen tests to use the new IR
authorReid Kleckner <rnk@google.com>
Fri, 9 Oct 2015 23:05:54 +0000 (23:05 +0000)
committerReid Kleckner <rnk@google.com>
Fri, 9 Oct 2015 23:05:54 +0000 (23:05 +0000)
Also Fix a buglet where SEH tables had ranges that spanned funclets.

The remaining tests using the old landingpad IR are preparation tests,
and will be deleted along with the old preparation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249917 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
lib/CodeGen/AsmPrinter/WinException.cpp
test/CodeGen/X86/seh-catch-all-win32.ll
test/CodeGen/X86/seh-catchpad.ll
test/CodeGen/X86/seh-except-finally.ll
test/CodeGen/X86/seh-filter.ll [deleted file]
test/CodeGen/X86/seh-finally.ll
test/CodeGen/X86/seh-safe-div-win32.ll
test/CodeGen/X86/seh-safe-div.ll
test/CodeGen/X86/seh-stack-realign-win32.ll [deleted file]
test/CodeGen/X86/seh-stack-realign.ll
test/CodeGen/X86/win-mixed-ehpersonality.ll [new file with mode: 0644]
test/CodeGen/X86/win_eh_prepare.ll [deleted file]

index a5172fd..63be0da 100644 (file)
@@ -458,6 +458,11 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
     // the actions that would be taken in that state. This means our tables are
     // slightly bigger, which is OK.
     for (const auto &MBB : *MF) {
+      // Break out before we enter into a finally funclet.
+      // FIXME: We need to emit separate EH tables for cleanups.
+      if (MBB.isEHFuncletEntry() && &MBB != MF->begin())
+        break;
+
       for (InvokeRange &I : invoke_ranges(FuncInfo, MBB)) {
         // If this invoke is in the same state as the last invoke and there were
         // no non-throwing calls between it, extend the range to include both
index a4ea8ab..0ad3853 100644 (file)
@@ -22,23 +22,19 @@ entry:
           to label %__try.cont unwind label %lpad
 
 lpad:                                             ; preds = %entry
-  %0 = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 ()* @"filt$main" to i8*)
-  %1 = extractvalue { i8*, i32 } %0, 1
-  %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @"filt$main" to i8*)) #4
-  %matches = icmp eq i32 %1, %2
-  br i1 %matches, label %__except, label %eh.resume
+  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)]
+          to label %__except unwind label %endpad
 
 __except:                                         ; preds = %lpad
-  %3 = load i32, i32* %__exceptioncode, align 4
-  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %3) #4
-  br label %__try.cont
+  %code = load i32, i32* %__exceptioncode, align 4
+  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4
+  catchret %p to label %__try.cont
+
+endpad:                                        ; preds = %lpad
+  catchendpad unwind to caller
 
 __try.cont:                                       ; preds = %entry, %__except
   ret i32 0
-
-eh.resume:                                        ; preds = %lpad
-  resume { i8*, i32 } %0
 }
 
 define internal i32 @"filt$main"() {
@@ -71,19 +67,18 @@ entry:
 ; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
 ; CHECK: movl %esp, [[reg_offs]](%ebp)
 ; CHECK: movl $L__ehtable$main,
-;      EH state 0
+;       EH state 0
 ; 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: LBB0_[[lpbb:[0-9]+]]: # %lpad{{$}}
+;       stackrestore
 ; CHECK: movl -24(%ebp), %esp
-;      EH state -1
+;       EH state -1
 ; CHECK: movl [[code_offs]](%ebp), %[[code:[a-z]+]]
-; CHECK: movl $-1, -16(%ebp)
 ; CHECK-DAG: movl %[[code]], 4(%esp)
 ; CHECK-DAG: movl $_str, (%esp)
 ; CHECK: calll _printf
@@ -94,7 +89,7 @@ entry:
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _filt$main
-; CHECK-NEXT: .long Ltmp{{[0-9]+}}
+; CHECK-NEXT: .long LBB0_[[lpbb]]
 
 ; CHECK-LABEL: _filt$main:
 ; CHECK: pushl %ebp
index e981744..b59aa8d 100644 (file)
@@ -147,7 +147,7 @@ ehcleanup.end:                                    ; preds = %ehcleanup
 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
 ; CHECK-NEXT:         .long   .LBB1_6@IMGREL
 ; CHECK-NEXT:         .long   .Ltmp6@IMGREL+1
-; CHECK-NEXT:         .long   .Ltmp5@IMGREL+1
+; CHECK-NEXT:         .long   .Ltmp7@IMGREL+1
 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
 ; CHECK-NEXT:         .long   .LBB1_6@IMGREL
 ; CHECK-NEXT: .Llsda_end0:
index 5a529cd..7acb802 100644 (file)
@@ -38,49 +38,38 @@ entry:
   %exn.slot = alloca i8*
   %ehselector.slot = alloca i32
   invoke void @crash() #5
-          to label %invoke.cont unwind label %lpad
+          to label %invoke.cont unwind label %__finally
 
 invoke.cont:                                      ; preds = %entry
   %0 = call i8* @llvm.localaddress()
   invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext false, i8* %0) #5
-          to label %invoke.cont2 unwind label %lpad1
+          to label %invoke.cont2 unwind label %catch.dispatch
 
 invoke.cont2:                                     ; preds = %invoke.cont
   br label %__try.cont
 
-lpad:                                             ; preds = %entry
-  %1 = landingpad { i8*, i32 }
-          cleanup
-          catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)
-  %2 = extractvalue { i8*, i32 } %1, 0
-  store i8* %2, i8** %exn.slot
-  %3 = extractvalue { i8*, i32 } %1, 1
-  store i32 %3, i32* %ehselector.slot
-  %4 = call i8* @llvm.localaddress()
-  invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %4) #5
-          to label %invoke.cont3 unwind label %lpad1
-
-lpad1:                                            ; preds = %lpad, %invoke.cont
-  %5 = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)
-  %6 = extractvalue { i8*, i32 } %5, 0
-  store i8* %6, i8** %exn.slot
-  %7 = extractvalue { i8*, i32 } %5, 1
-  store i32 %7, i32* %ehselector.slot
-  br label %catch.dispatch
+__finally:                                             ; preds = %entry
+  %cleanuppad = cleanuppad []
+  %locals = call i8* @llvm.localaddress()
+  invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %locals) #5
+          to label %invoke.cont3 unwind label %cleanupendpad
+
+invoke.cont3:                                     ; preds = %__finally
+  cleanupret %cleanuppad unwind label %catch.dispatch
 
-invoke.cont3:                                     ; preds = %lpad
-  br label %catch.dispatch
+cleanupendpad:
+  cleanupendpad %cleanuppad unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %invoke.cont3, %lpad1
-  %sel = load i32, i32* %ehselector.slot
-  %8 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)) #6
-  %matches = icmp eq i32 %sel, %8
-  br i1 %matches, label %__except, label %eh.resume
+  %catchpad = catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)]
+          to label %__except unwind label %catchendpad
 
 __except:                                         ; preds = %catch.dispatch
   %call = call i32 @puts(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08MLCMLGHM@__except?$AA@", i32 0, i32 0))
-  br label %__try.cont
+  catchret %catchpad to label %__try.cont
+
+catchendpad:
+  catchendpad unwind to caller
 
 __try.cont:                                       ; preds = %__except, %invoke.cont2
   ret void
@@ -97,29 +86,27 @@ eh.resume:                                        ; preds = %catch.dispatch
 ; CHECK: .Ltmp0
 ; CHECK: callq crash
 ; CHECK: .Ltmp1
-; CHECK: .Ltmp3
-; CHECK: callq "?fin$0@0@use_both@@"
 ; CHECK: .Ltmp4
+; CHECK: callq "?fin$0@0@use_both@@"
+; CHECK: .Ltmp5
 ; CHECK: retq
 ;
 ; CHECK: .seh_handlerdata
-; CHECK-NEXT: .text
-; CHECK-NEXT: .Ltmp{{[0-9]+}}
-; CHECK-NEXT: .seh_endproc
-; CHECK-NEXT: .section .xdata,"dr"
-; CHECK-NEXT: .long 3
-; CHECK-NEXT: .long .Ltmp0@IMGREL
+; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
+; CHECK-NEXT: .Llsda_begin0:
+; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
-; CHECK-NEXT: .long "?fin$0@0@use_both@@"@IMGREL
+; CHECK-NEXT: .long "?dtor$2@?0?use_both@4HA"@IMGREL
 ; CHECK-NEXT: .long 0
-; CHECK-NEXT: .long .Ltmp0@IMGREL
+; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
 ; CHECK-NEXT: .long "?filt$0@0@use_both@@"@IMGREL
-; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL
-; CHECK-NEXT: .long .Ltmp3@IMGREL
+; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
 ; CHECK-NEXT: .long .Ltmp4@IMGREL+1
+; CHECK-NEXT: .long .Ltmp5@IMGREL+1
 ; CHECK-NEXT: .long "?filt$0@0@use_both@@"@IMGREL
-; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL
+; CHECK-NEXT: .long .LBB0_{{[0-9]+}}@IMGREL
+; CHECK-NEXT: .Llsda_end0:
 
 ; Function Attrs: noinline nounwind
 define internal i32 @"\01?filt$0@0@use_both@@"(i8* %exception_pointers, i8* %frame_pointer) #2 {
diff --git a/test/CodeGen/X86/seh-filter.ll b/test/CodeGen/X86/seh-filter.ll
deleted file mode 100644 (file)
index 37ed158..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-; RUN: llc -O0 -mtriple=x86_64-windows-msvc < %s | FileCheck %s
-
-declare void @g()
-define void @f() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
-  invoke void @g() to label %return unwind label %lpad
-
-return:
-  ret void
-
-lpad:
-  %ehptrs = landingpad {i8*, i32}
-    filter [0 x i8*] zeroinitializer
-  call void @__cxa_call_unexpected(i8* null)
-  unreachable
-}
-declare i32 @__C_specific_handler(...)
-declare void @__cxa_call_unexpected(i8*)
-
-; We don't emit entries for filters.
-; CHECK: .seh_handlerdata
-; CHECK: .long 0
index 99f3b65..57c2c8c 100644 (file)
@@ -17,53 +17,46 @@ invoke.cont:                                      ; preds = %entry
   ret i32 0
 
 lpad:                                             ; preds = %entry
-  %0 = landingpad { i8*, i32 }
-          cleanup
-  %1 = extractvalue { i8*, i32 } %0, 0
-  %2 = extractvalue { i8*, i32 } %0, 1
+  %p = cleanuppad []
   %call2 = invoke i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0))
-          to label %invoke.cont1 unwind label %terminate.lpad
+          to label %invoke.cont1 unwind label %endpad
 
 invoke.cont1:                                     ; preds = %lpad
-  resume { i8*, i32 } %0
+  cleanupret %p unwind to caller
 
-terminate.lpad:                                   ; preds = %lpad
-  %3 = landingpad { i8*, i32 }
-          catch i8* null
-  call void @abort()
-  unreachable
+endpad:                                   ; preds = %lpad
+  cleanupendpad %p unwind to caller
 }
 
 ; X64-LABEL: main:
 ; X64: retq
 
 ; X64: .seh_handlerdata
-; X64-NEXT: .text
-; X64-NEXT: .Ltmp{{[0-9]+}}:
-; X64-NEXT: .seh_endproc
-; X64-NEXT: .section .xdata,"dr"
-; X64-NEXT: .long 1
-; X64-NEXT: .long .Ltmp0@IMGREL
-; X64-NEXT: .long .Ltmp1@IMGREL
-; X64-NEXT: .long main.cleanup@IMGREL
-; X64-NEXT: .long 0
-
-; X64-LABEL: main.cleanup:
+; X64-NEXT: .long   (.Llsda_end0-.Llsda_begin0)/16
+; X64-NEXT: .Llsda_begin0:
+; X64-NEXT: .long   .Ltmp0@IMGREL+1
+; X64-NEXT: .long   .Ltmp1@IMGREL+1
+; X64-NEXT: .long   "?dtor$2@?0?main@4HA"@IMGREL
+; X64-NEXT: .long   0
+; X64-NEXT: .Llsda_end0:
+
+; X64-LABEL: "?dtor$2@?0?main@4HA":
 ; X64: callq puts
 ; X64: retq
 
 ; X86-LABEL: _main:
 ; X86: retl
 
+; X86-LABEL: "?dtor$2@?0?main@4HA":
+; X86: LBB0_2:
+; X86: calll _puts
+; X86: retl
+
 ; X86: .section .xdata,"dr"
 ; X86: L__ehtable$main:
 ; X86-NEXT: .long -1
 ; X86-NEXT: .long 0
-; X86-NEXT: .long _main.cleanup
-
-; X86-LABEL: _main.cleanup:
-; X86: calll _puts
-; X86: retl
+; X86-NEXT: .long LBB0_2
 
 declare i32 @__C_specific_handler(...)
 
index b1bcde2..d17f221 100644 (file)
@@ -28,35 +28,31 @@ entry:
   %r = alloca i32, align 4
   store i32 42, i32* %r
   invoke void @try_body(i32* %r, i32* %n, i32* %d)
-          to label %__try.cont unwind label %lpad
-
-lpad:
-  %vals = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 ()* @safe_div_filt0 to i8*)
-          catch i8* bitcast (i32 ()* @safe_div_filt1 to i8*)
-  %ehptr = extractvalue { i8*, i32 } %vals, 0
-  %sel = extractvalue { i8*, i32 } %vals, 1
-  %filt0_val = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @safe_div_filt0 to i8*))
-  %is_filt0 = icmp eq i32 %sel, %filt0_val
-  br i1 %is_filt0, label %handler0, label %eh.dispatch1
-
-eh.dispatch1:
-  %filt1_val = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @safe_div_filt1 to i8*))
-  %is_filt1 = icmp eq i32 %sel, %filt1_val
-  br i1 %is_filt1, label %handler1, label %eh.resume
+          to label %__try.cont unwind label %lpad0
+
+lpad0:
+  %p0 = catchpad [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)]
+          to label %handler0 unwind label %endpad0
 
 handler0:
   call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))
   store i32 -1, i32* %r, align 4
-  br label %__try.cont
+  catchret %p0 to label %__try.cont
+
+endpad0:
+  catchendpad unwind label %lpad1
+
+lpad1:
+  %p1 = catchpad [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)]
+          to label %handler1 unwind label %endpad1
 
 handler1:
   call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))
   store i32 -2, i32* %r, align 4
-  br label %__try.cont
+  catchret %p1 to label %__try.cont
 
-eh.resume:
-  resume { i8*, i32 } %vals
+endpad1:
+  catchendpad unwind to caller
 
 __try.cont:
   %safe_ret = load i32, i32* %r, align 4
@@ -75,15 +71,13 @@ __try.cont:
 
 ; Landing pad code
 
-; CHECK: [[handler0:Ltmp[0-9]+]]: # Block address taken
-; CHECK: # %handler0
+; CHECK: [[lpad1:LBB0_[0-9]+]]: # %lpad1
 ;      Restore SP
 ; CHECK: movl {{.*}}(%ebp), %esp
 ; CHECK: calll _puts
 ; CHECK: jmp [[cont_bb]]
 
-; CHECK: [[handler1:Ltmp[0-9]+]]: # Block address taken
-; CHECK: # %handler1
+; CHECK: [[lpad0:LBB0_[0-9]+]]: # %lpad0
 ;      Restore SP
 ; CHECK: movl {{.*}}(%ebp), %esp
 ; CHECK: calll _puts
@@ -93,10 +87,10 @@ __try.cont:
 ; CHECK: L__ehtable$safe_div:
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _safe_div_filt1
-; CHECK-NEXT: .long [[handler1]]
+; CHECK-NEXT: .long [[lpad1]]
 ; CHECK-NEXT: .long 0
 ; CHECK-NEXT: .long _safe_div_filt0
-; CHECK-NEXT: .long [[handler0]]
+; CHECK-NEXT: .long [[lpad0]]
 
 define void @try_body(i32* %r, i32* %n, i32* %d) {
 entry:
index cd0ef71..809d261 100644 (file)
@@ -27,35 +27,31 @@ define i32 @safe_div(i32* %n, i32* %d) personality i8* bitcast (i32 (...)* @__C_
 entry:
   %r = alloca i32, align 4
   invoke void @try_body(i32* %r, i32* %n, i32* %d)
-          to label %__try.cont unwind label %lpad
-
-lpad:
-  %vals = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)
-          catch i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)
-  %ehptr = extractvalue { i8*, i32 } %vals, 0
-  %sel = extractvalue { i8*, i32 } %vals, 1
-  %filt0_val = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*))
-  %is_filt0 = icmp eq i32 %sel, %filt0_val
-  br i1 %is_filt0, label %handler0, label %eh.dispatch1
-
-eh.dispatch1:
-  %filt1_val = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*))
-  %is_filt1 = icmp eq i32 %sel, %filt1_val
-  br i1 %is_filt1, label %handler1, label %eh.resume
+          to label %__try.cont unwind label %lpad0
+
+lpad0:
+  %p0 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)]
+          to label %handler0 unwind label %endpad0
 
 handler0:
   call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))
   store i32 -1, i32* %r, align 4
-  br label %__try.cont
+  catchret %p0 to label %__try.cont
+
+endpad0:
+  catchendpad unwind label %lpad1
+
+lpad1:
+  %p1 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)]
+          to label %handler1 unwind label %endpad1
 
 handler1:
   call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))
   store i32 -2, i32* %r, align 4
-  br label %__try.cont
+  catchret %p1 to label %__try.cont
 
-eh.resume:
-  resume { i8*, i32 } %vals
+endpad1:
+  catchendpad unwind to caller
 
 __try.cont:
   %safe_ret = load i32, i32* %r, align 4
@@ -68,7 +64,7 @@ __try.cont:
 ; CHECK: .seh_proc safe_div
 ; CHECK: .seh_handler __C_specific_handler, @unwind, @except
 ; CHECK: .Ltmp0:
-; CHECK: leaq [[rloc:.*\(%rsp\)]], %rcx
+; CHECK: leaq [[rloc:.*\(%rbp\)]], %rcx
 ; CHECK: callq try_body
 ; CHECK-NEXT: .Ltmp1
 ; CHECK: [[cont_bb:\.LBB0_[0-9]+]]:
@@ -77,36 +73,31 @@ __try.cont:
 
 ; Landing pad code
 
-; CHECK: [[handler0:\.Ltmp[0-9]+]]: # Block address taken
-; CHECK: # %handler0
+; CHECK: [[lpad1:\.LBB0_[0-9]+]]: # %lpad1
 ; CHECK: callq puts
-; CHECK: movl $-1, [[rloc]]
+; CHECK: movl $-2, [[rloc]]
 ; CHECK: jmp [[cont_bb]]
 
-; CHECK: [[handler1:\.Ltmp[0-9]+]]: # Block address taken
-; CHECK: # %handler1
+; CHECK: [[lpad0:\.LBB0_[0-9]+]]: # %lpad0
 ; CHECK: callq puts
-; CHECK: movl $-2, [[rloc]]
+; CHECK: movl $-1, [[rloc]]
 ; CHECK: jmp [[cont_bb]]
 
 ; CHECK: .seh_handlerdata
-; CHECK-NEXT: .text
-; CHECK-NEXT: .Ltmp{{[0-9]+}}
-; CHECK-NEXT: .seh_endproc
-; CHECK-NEXT: .section .xdata,"dr"
-; CHECK-NEXT: .long 2
-; CHECK-NEXT: .long .Ltmp0@IMGREL
+; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
+; CHECK-NEXT: .Llsda_begin0:
+; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
 ; CHECK-NEXT: .long safe_div_filt0@IMGREL
-; CHECK-NEXT: .long [[handler0]]@IMGREL
-; CHECK-NEXT: .long .Ltmp0@IMGREL
+; CHECK-NEXT: .long [[lpad0]]@IMGREL
+; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
 ; CHECK-NEXT: .long safe_div_filt1@IMGREL
-; CHECK-NEXT: .long [[handler1]]@IMGREL
+; CHECK-NEXT: .long [[lpad1]]@IMGREL
+; CHECK-NEXT: .Llsda_end0:
 ; CHECK: .text
 ; CHECK: .seh_endproc
 
-
 define void @try_body(i32* %r, i32* %n, i32* %d) {
 entry:
   %0 = load i32, i32* %n, align 4
diff --git a/test/CodeGen/X86/seh-stack-realign-win32.ll b/test/CodeGen/X86/seh-stack-realign-win32.ll
deleted file mode 100644 (file)
index f3ab718..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s
-
-; 32-bit catch-all has to use a filter function because that's how it saves the
-; exception code.
-
-@str = linkonce_odr unnamed_addr constant [27 x i8] c"GetExceptionCode(): 0x%lx\0A\00", align 1
-
-declare i32 @_except_handler3(...)
-declare void @crash()
-declare i32 @printf(i8* nocapture readonly, ...) nounwind
-declare i32 @llvm.eh.typeid.for(i8*)
-declare i8* @llvm.frameaddress(i32)
-declare i8* @llvm.localrecover(i8*, i8*, i32)
-declare void @llvm.localescape(...)
-declare i8* @llvm.x86.seh.recoverfp(i8*, i8*)
-
-define i32 @main() personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
-entry:
-  ; The EH code allocation is overaligned, triggering realignment.
-  %__exceptioncode = alloca i32, align 8
-  call void (...) @llvm.localescape(i32* %__exceptioncode)
-  invoke void @crash() #5
-          to label %__try.cont unwind label %lpad
-
-lpad:                                             ; preds = %entry
-  %0 = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 ()* @"filt$main" to i8*)
-  %1 = extractvalue { i8*, i32 } %0, 1
-  %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @"filt$main" to i8*)) #4
-  %matches = icmp eq i32 %1, %2
-  br i1 %matches, label %__except, label %eh.resume
-
-__except:                                         ; preds = %lpad
-  %3 = load i32, i32* %__exceptioncode, align 4
-  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %3) #4
-  br label %__try.cont
-
-__try.cont:                                       ; preds = %entry, %__except
-  ret i32 0
-
-eh.resume:                                        ; preds = %lpad
-  resume { i8*, i32 } %0
-}
-
-define internal i32 @"filt$main"() {
-entry:
-  %ebp = tail call i8* @llvm.frameaddress(i32 1)
-  %parentfp = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @main to i8*), i8* %ebp)
-  %code.i8 = tail call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %parentfp, i32 0)
-  %__exceptioncode = bitcast i8* %code.i8 to i32*
-  %info.addr = getelementptr inbounds i8, i8* %ebp, i32 -20
-  %0 = bitcast i8* %info.addr to i32***
-  %1 = load i32**, i32*** %0, align 4
-  %2 = load i32*, i32** %1, align 4
-  %3 = load i32, i32* %2, align 4
-  store i32 %3, i32* %__exceptioncode, align 4
-  ret i32 1
-}
-
-; Check that we can get the exception code from eax to the printf.
-
-; CHECK-LABEL: _main:
-; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
-; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
-; CHECK: movl %esp, [[reg_offs]](%esi)
-; CHECK: movl $L__ehtable$main,
-;       EH state 0
-; CHECK: movl $0, 40(%esi)
-; CHECK: calll _crash
-; CHECK: retl
-; CHECK: # Block address taken
-;       stackrestore
-; CHECK: movl -24(%ebp), %esp
-; CHECK: movl $Lmain$parent_frame_offset, %eax
-; CHECK: negl %eax
-; CHECK: leal -24(%ebp,%eax), %esi
-; CHECK: movl 12(%esi), %ebp    # 4-byte Reload
-;       EH state -1
-; CHECK: movl [[code_offs]](%esi), %[[code:[a-z]+]]
-; CHECK: movl $-1, 40(%esi)
-; CHECK-DAG: movl %[[code]], 4(%esp)
-; CHECK-DAG: movl $_str, (%esp)
-; CHECK: calll _printf
-
-; CHECK: .section .xdata,"dr"
-; CHECK: Lmain$parent_frame_offset = Lmain$frame_escape_1
-; CHECK: L__ehtable$main
-; CHECK-NEXT: .long -1
-; CHECK-NEXT: .long _filt$main
-; CHECK-NEXT: .long Ltmp{{[0-9]+}}
-
-; CHECK-LABEL: _filt$main:
-; CHECK: pushl %ebp
-; CHECK: movl %esp, %ebp
-; CHECK: movl (%ebp), %[[oldebp:[a-z]+]]
-; CHECK: movl -20(%[[oldebp]]), %[[ehinfo:[a-z]+]]
-; CHECK: movl (%[[ehinfo]]), %[[ehrec:[a-z]+]]
-; CHECK: movl (%[[ehrec]]), %[[ehcode:[a-z]+]]
-; CHECK: movl %[[ehcode]], {{.*}}(%{{.*}})
index f2fb28a..a06b236 100644 (file)
@@ -23,23 +23,19 @@ entry:
           to label %__try.cont unwind label %lpad
 
 lpad:                                             ; preds = %entry
-  %0 = landingpad { i8*, i32 }
-          catch i8* bitcast (i32 ()* @"filt$main" to i8*)
-  %1 = extractvalue { i8*, i32 } %0, 1
-  %2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @"filt$main" to i8*)) #4
-  %matches = icmp eq i32 %1, %2
-  br i1 %matches, label %__except, label %eh.resume
+  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)]
+          to label %__except unwind label %endpad
 
 __except:                                         ; preds = %lpad
-  %3 = load i32, i32* %__exceptioncode, align 4
-  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %3) #4
-  br label %__try.cont
+  %code = load i32, i32* %__exceptioncode, align 4
+  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4
+  catchret %p to label %__try.cont
+
+endpad:
+  catchendpad unwind to caller
 
 __try.cont:                                       ; preds = %entry, %__except
   ret i32 0
-
-eh.resume:                                        ; preds = %lpad
-  resume { i8*, i32 } %0
 }
 
 define internal i32 @"filt$main"() {
@@ -68,18 +64,14 @@ entry:
 ; CHECK: movl $0, 40(%esi)
 ; CHECK: calll _crash
 ; CHECK: retl
-; CHECK: # Block address taken
+; CHECK: LBB0_[[lpbb:[0-9]+]]: # %lpad
 ;       Restore ESP
 ; CHECK: movl -24(%ebp), %esp
 ;       Restore ESI
-; CHECK: movl $Lmain$parent_frame_offset, %eax
-; CHECK: negl %eax
-; CHECK: leal -24(%ebp,%eax), %esi
+; CHECK: leal -44(%ebp), %esi
 ;       Restore EBP
-; CHECK: movl 12(%esi), %ebp    # 4-byte Reload
-;       EH state -1
+; CHECK: movl 12(%esi), %ebp
 ; CHECK: movl [[code_offs]](%esi), %[[code:[a-z]+]]
-; CHECK: movl $-1, 40(%esi)
 ; CHECK-DAG: movl %[[code]], 4(%esp)
 ; CHECK-DAG: movl $_str, (%esp)
 ; CHECK: calll _printf
@@ -89,7 +81,7 @@ entry:
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _filt$main
-; CHECK-NEXT: .long Ltmp{{[0-9]+}}
+; CHECK-NEXT: .long LBB0_[[lpbb]]
 
 ; CHECK-LABEL: _filt$main:
 ; CHECK: pushl %ebp
diff --git a/test/CodeGen/X86/win-mixed-ehpersonality.ll b/test/CodeGen/X86/win-mixed-ehpersonality.ll
new file mode 100644 (file)
index 0000000..9b69165
--- /dev/null
@@ -0,0 +1,83 @@
+; RUN: llc -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
+
+declare void @maybe_throw()
+
+@_ZTIi = external constant i8*
+@g = external global i32
+
+declare i32 @__C_specific_handler(...)
+declare i32 @__gxx_personality_seh0(...)
+declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind
+
+define i32 @use_seh() personality i32 (...)* @__C_specific_handler {
+entry:
+  invoke void @maybe_throw()
+      to label %cont unwind label %lpad
+
+cont:
+  ret i32 0
+
+lpad:
+  %p = catchpad [i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)]
+      to label %catch unwind label %endpad
+catch:
+  catchret %p to label %ret1
+endpad:
+  catchendpad unwind to caller
+
+ret1:
+  ret i32 1
+}
+
+define internal i32 @filt_g(i8*, i8*) {
+  %g = load i32, i32* @g
+  ret i32 %g
+}
+
+; CHECK-LABEL: use_seh:
+; CHECK: callq maybe_throw
+; CHECK: xorl %eax, %eax
+; CHECK: .LBB0_[[epilogue:[0-9]+]]
+; CHECK: retq
+; CHECK: # %lpad
+; CHECK: movl $1, %eax
+; CHECK: jmp .LBB0_[[epilogue]]
+
+; A MinGW64-ish EH style. It could happen if a binary uses both MSVC CRT and
+; mingw CRT and is linked with LTO.
+define i32 @use_gcc() personality i32 (...)* @__gxx_personality_seh0 {
+entry:
+  invoke void @maybe_throw()
+      to label %cont unwind label %lpad
+
+cont:
+  ret i32 0
+
+lpad:
+  %ehvals = landingpad { i8*, i32 }
+      cleanup
+      catch i8* bitcast (i8** @_ZTIi to i8*)
+  %ehsel = extractvalue { i8*, i32 } %ehvals, 1
+  %filt_g_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*))
+  %matches = icmp eq i32 %ehsel, %filt_g_sel
+  br i1 %matches, label %ret1, label %eh.resume
+
+ret1:
+  ret i32 1
+
+eh.resume:
+  resume { i8*, i32 } %ehvals
+}
+
+; CHECK-LABEL: use_gcc:
+; CHECK: callq maybe_throw
+; CHECK: xorl %eax, %eax
+;
+; CHECK: # %lpad
+; CHECK: cmpl $2, %edx
+; CHECK: jne
+;
+; CHECK: # %ret1
+; CHECK: movl $1, %eax
+;
+; CHECK: callq _Unwind_Resume
diff --git a/test/CodeGen/X86/win_eh_prepare.ll b/test/CodeGen/X86/win_eh_prepare.ll
deleted file mode 100644 (file)
index 3e3f9af..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-; RUN: opt -S -winehprepare -dwarfehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
-
-; FIXME: Add and test outlining here.
-
-declare void @maybe_throw()
-
-@_ZTIi = external constant i8*
-@g = external global i32
-
-declare i32 @__C_specific_handler(...)
-declare i32 @__gxx_personality_seh0(...)
-declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind
-
-define i32 @use_seh() personality i32 (...)* @__C_specific_handler {
-entry:
-  invoke void @maybe_throw()
-      to label %cont unwind label %lpad
-
-cont:
-  ret i32 0
-
-lpad:
-  %ehvals = landingpad { i8*, i32 }
-      cleanup
-      catch i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)
-  %ehsel = extractvalue { i8*, i32 } %ehvals, 1
-  %filt_g_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*))
-  %matches = icmp eq i32 %ehsel, %filt_g_sel
-  br i1 %matches, label %ret1, label %eh.resume
-
-ret1:
-  ret i32 1
-
-eh.resume:
-  resume { i8*, i32 } %ehvals
-}
-
-define internal i32 @filt_g(i8*, i8*) {
-  %g = load i32, i32* @g
-  ret i32 %g
-}
-
-; CHECK-LABEL: define i32 @use_seh()
-; CHECK: invoke void @maybe_throw()
-; CHECK-NEXT: to label %cont unwind label %lpad
-; CHECK: landingpad
-; CHECK-NEXT: cleanup
-; CHECK-NEXT: catch
-; CHECK-NEXT: call i8* (...) @llvm.eh.actions({{.*}})
-
-
-; A MinGW64-ish EH style. It could happen if a binary uses both MSVC CRT and
-; mingw CRT and is linked with LTO.
-define i32 @use_gcc() personality i32 (...)* @__gxx_personality_seh0 {
-entry:
-  invoke void @maybe_throw()
-      to label %cont unwind label %lpad
-
-cont:
-  ret i32 0
-
-lpad:
-  %ehvals = landingpad { i8*, i32 }
-      cleanup
-      catch i8* bitcast (i8** @_ZTIi to i8*)
-  %ehsel = extractvalue { i8*, i32 } %ehvals, 1
-  %filt_g_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*))
-  %matches = icmp eq i32 %ehsel, %filt_g_sel
-  br i1 %matches, label %ret1, label %eh.resume
-
-ret1:
-  ret i32 1
-
-eh.resume:
-  resume { i8*, i32 } %ehvals
-}
-
-; CHECK-LABEL: define i32 @use_gcc()
-; CHECK: invoke void @maybe_throw()
-; CHECK-NEXT: to label %cont unwind label %lpad
-; CHECK: eh.resume:
-; CHECK: call void @_Unwind_Resume(i8* %exn.obj)