[WinEH] Don't visit the same catchswitch twice
[oota-llvm.git] / test / CodeGen / WinEH / wineh-statenumbering.ll
index 84b56fe64114eb4ed2992daba3589f831830f9e8..dab7fde61a6676d70656a11974dd8c9c7689e290 100644 (file)
@@ -37,9 +37,10 @@ entry:
           to label %unreachable.for.entry unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %1 = catchpad token [i8* null, i8* null] to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
   ; CHECK: catch:
   ; CHECK:   store i32 2
   ; CHECK:   invoke void @_CxxThrowException(
@@ -47,43 +48,94 @@ catch:                                            ; preds = %catch.dispatch
           to label %unreachable unwind label %catch.dispatch.1
 
 catch.dispatch.1:                                 ; preds = %catch
-  %2 = catchpad token [i8* null, i8* null] to label %catch.3 unwind label %catchendblock.2
-
+  %cs2 = catchswitch within %1 [label %catch.3] unwind to caller
 catch.3:                                          ; preds = %catch.dispatch.1
+  %2 = catchpad within %cs2 [i8* null, i32 u0x40, i8* null]
   ; CHECK: catch.3:
   ; CHECK:   store i32 3
-  ; CHECK:   invoke void @g(i32 1)
-  invoke void @g(i32 1)
-          to label %invoke.cont unwind label %catchendblock.2
-
-invoke.cont:                                      ; preds = %catch.3
-  catchret token %2 to label %try.cont
+  ; CHECK:   call void @g(i32 1)
+  call void @g(i32 1)
+  catchret from %2 to label %try.cont
 
-try.cont:                                         ; preds = %invoke.cont
+try.cont:                                         ; preds = %catch.3
   ; CHECK: try.cont:
   ; CHECK:   store i32 1
-  ; CHECK:   invoke void @g(i32 2)
-  invoke void @g(i32 2)
-          to label %invoke.cont.4 unwind label %catchendblock
+  ; CHECK:   call void @g(i32 2)
+  call void @g(i32 2)
+  unreachable
 
-invoke.cont.4:                                    ; preds = %try.cont
+unreachable:                                      ; preds = %catch
   unreachable
 
-catchendblock.2:                                  ; preds = %catch.3, %catch.dispatch.1
-  catchendpad unwind label %catchendblock
+unreachable.for.entry:                            ; preds = %entry
+  unreachable
+}
 
-catchendblock:                                    ; preds = %catchendblock.2, %try.cont, %catch.dispatch
-  catchendpad unwind to caller
+define i32 @nopads() #0 personality i32 (...)* @__CxxFrameHandler3 {
+  ret i32 0
+}
 
-unreachable:                                      ; preds = %catch
+; CHECK-LABEL: define i32 @nopads()
+; CHECK-NEXT: ret i32 0
+; CHECK-NOT: __ehhandler$nopads
+
+; CHECK-LABEL: define void @PR25926()
+define void @PR25926() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  ; CHECK: entry:
+  ; CHECK:   store i32 -1
+  ; CHECK:   store i32 0
+  ; CHECK:   invoke void @_CxxThrowException(
+  invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null)
+          to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %catch] unwind to caller
+
+catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %0 [i8* null, i32 64, i8* null]
+  ; CHECK: catch:
+  ; CHECK:   store i32 3
+  ; CHECK:   invoke void @_CxxThrowException(
+  invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) [ "funclet"(token %1) ]
+          to label %unreachable1 unwind label %catch.dispatch1
+
+catch.dispatch1:                                  ; preds = %catch
+  %2 = catchswitch within %1 [label %catch2] unwind label %ehcleanup
+
+catch2:                                           ; preds = %catch.dispatch1
+  %3 = catchpad within %2 [i8* null, i32 64, i8* null]
+  catchret from %3 to label %try.cont
+
+try.cont:                                         ; preds = %catch2
+  ; CHECK: try.cont:
+  ; CHECK:   store i32 1
+  ; CHECK:   call void @dtor()
+  call void @dtor() #3 [ "funclet"(token %1) ]
+  catchret from %1 to label %try.cont4
+
+try.cont4:                                        ; preds = %try.cont
+  ret void
+
+ehcleanup:                                        ; preds = %catch.dispatch1
+  %4 = cleanuppad within %1 []
+  ; CHECK: ehcleanup:
+  ; CHECK:   store i32 -1
+  ; CHECK:   call void @dtor()
+  call void @dtor() #3 [ "funclet"(token %4) ]
+  cleanupret from %4 unwind to caller
+
+unreachable:                                      ; preds = %entry
   unreachable
 
-unreachable.for.entry:                            ; preds = %entry
+unreachable1:                                     ; preds = %catch
   unreachable
 }
 
 declare void @g(i32) #0
 
+declare void @dtor()
+
 declare x86_stdcallcc void @_CxxThrowException(i8*, %eh.ThrowInfo*)
 
 declare i32 @__CxxFrameHandler3(...)