; RUN: opt < %s -simplifycfg -S | FileCheck %s declare void @f() declare void @llvm.foo(i32) nounwind declare void @ProcessCLRException() define void @test1() personality void ()* @ProcessCLRException { entry: invoke void @f() to label %exit unwind label %exn.dispatch exn.dispatch: %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller pad1: %cp1 = catchpad within %cs [i32 1] call void @llvm.foo(i32 1) catchret from %cp1 to label %exit pad2: %cp2 = catchpad within %cs [i32 2] unreachable exit: ret void } ; Remove unreachble catch2, leave catch1 as-is ; CHECK-LABEL: define void @test1() ; CHECK: %cs = catchswitch within none [label %pad1] unwind to caller ; CHECK-NOT: catchpad ; CHECK: %cp1 = catchpad within %cs [i32 1] ; CHECK-NOT: catchpad ; Remove both catchpads and the catchswitch from exn.dispatch ; CHECK-LABEL: define void @test2() define void @test2() personality void ()* @ProcessCLRException { entry: invoke void @f() to label %via.cleanup unwind label %exn.dispatch ; CHECK-NOT: invoke ; CHECK: call void @f() via.cleanup: invoke void @f() to label %via.catchswitch unwind label %cleanup.inner cleanup.inner: %cp.inner = cleanuppad within none [] call void @llvm.foo(i32 0) cleanupret from %cp.inner unwind label %exn.dispatch ; CHECK: cleanupret from %cp.inner unwind to caller via.catchswitch: invoke void @f() to label %exit unwind label %dispatch.inner dispatch.inner: %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind to caller pad.inner: %catch.inner = catchpad within %cs.inner [i32 0] ; CHECK: %catch.inner = catchpad within %cs.inner call void @llvm.foo(i32 1) catchret from %catch.inner to label %exit exn.dispatch: %cs = catchswitch within none [label %pad1, label %pad2] unwind to caller ; CHECK-NOT: catchswitch within ; CHECK-NOT: catchpad pad1: catchpad within %cs [i32 1] unreachable pad2: catchpad within %cs [i32 2] unreachable exit: ret void } ; Same as @test2, but exn.dispatch catchswitch has an unwind dest that ; preds need to be reidrected to ; CHECK-LABEL: define void @test3() define void @test3() personality void ()* @ProcessCLRException { entry: invoke void @f() to label %via.cleanup unwind label %exn.dispatch ; CHECK: invoke void @f() ; CHECK-NEXT: to label %via.cleanup unwind label %cleanup via.cleanup: invoke void @f() to label %via.catchswitch unwind label %cleanup.inner cleanup.inner: %cp.inner = cleanuppad within none [] call void @llvm.foo(i32 0) cleanupret from %cp.inner unwind label %exn.dispatch ; CHECK: cleanupret from %cp.inner unwind label %cleanup via.catchswitch: invoke void @f() to label %exit unwind label %dispatch.inner dispatch.inner: %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch ; CHECK: %cs.inner = catchswitch within none [label %pad.inner] unwind label %cleanup pad.inner: %catch.inner = catchpad within %cs.inner [i32 0] ; CHECK: %catch.inner = catchpad within %cs.inner call void @llvm.foo(i32 1) catchret from %catch.inner to label %exit exn.dispatch: %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup ; CHECK-NOT: catchswitch within ; CHECK-NOT: catchpad pad1: catchpad within %cs [i32 1] unreachable pad2: catchpad within %cs [i32 2] unreachable cleanup: %cp = cleanuppad within none [] call void @llvm.foo(i32 0) cleanupret from %cp unwind to caller exit: ret void }