| ; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s |
| |
| declare i32 @__CxxFrameHandler3(...) |
| |
| declare i32 @__C_specific_handler(...) |
| |
| declare void @f() |
| |
| declare i32 @g() |
| |
| declare void @h(i32) |
| |
| ; CHECK-LABEL: @test1( |
| define void @test1(i1 %bool) personality i32 (...)* @__C_specific_handler { |
| entry: |
| invoke void @f() |
| to label %invoke.cont unwind label %left |
| |
| invoke.cont: |
| invoke void @f() |
| to label %exit unwind label %inner |
| |
| left: |
| %0 = cleanuppad within none [] |
| br i1 %bool, label %shared, label %cleanupret |
| |
| cleanupret: |
| cleanupret from %0 unwind label %right |
| |
| right: |
| %1 = cleanuppad within none [] |
| br label %shared |
| |
| shared: |
| %x = call i32 @g() |
| invoke void @f() |
| to label %shared.cont unwind label %inner |
| |
| shared.cont: |
| unreachable |
| |
| inner: |
| %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ] |
| %i = cleanuppad within none [] |
| call void @h(i32 %phi) |
| unreachable |
| |
| ; CHECK: %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ], [ %x.for.left, %shared.for.left ] |
| ; CHECK: %i = cleanuppad within none [] |
| ; CHECK: call void @h(i32 %phi) |
| |
| exit: |
| unreachable |
| } |
| |
| ; CHECK-LABEL: @test2( |
| define void @test2(i1 %bool) personality i32 (...)* @__C_specific_handler { |
| entry: |
| invoke void @f() |
| to label %shared.cont unwind label %left |
| |
| left: |
| %0 = cleanuppad within none [] |
| br i1 %bool, label %shared, label %cleanupret |
| |
| cleanupret: |
| cleanupret from %0 unwind label %right |
| |
| right: |
| %1 = cleanuppad within none [] |
| br label %shared |
| |
| shared: |
| %x = call i32 @g() |
| invoke void @f() |
| to label %shared.cont unwind label %inner |
| |
| shared.cont: |
| unreachable |
| |
| inner: |
| %i = cleanuppad within none [] |
| call void @h(i32 %x) |
| unreachable |
| |
| ; CHECK: %x1 = phi i32 [ %x.for.left, %shared.for.left ], [ %x, %shared ] |
| ; CHECK: %i = cleanuppad within none [] |
| ; CHECK: call void @h(i32 %x1) |
| |
| exit: |
| unreachable |
| } |
| |
| ; CHECK-LABEL: @test4( |
| define void @test4(i1 %x) personality i32 (...)* @__CxxFrameHandler3 { |
| entry: |
| invoke void @f() |
| to label %invoke.cont1 unwind label %left |
| |
| invoke.cont1: |
| invoke void @f() |
| to label %exit unwind label %right |
| |
| left: |
| %0 = cleanuppad within none [] |
| br label %shared |
| |
| right: |
| %1 = cleanuppad within none [] |
| br i1 %x, label %shared, label %right.other |
| |
| right.other: |
| br label %shared |
| |
| shared: |
| %phi = phi i32 [ 1, %left ], [ 0, %right ], [ -1, %right.other ] |
| call void @h(i32 %phi) |
| unreachable |
| |
| ; CHECK: %phi = phi i32 [ 0, %right ], [ -1, %right.other ] |
| ; CHECK: call void @h(i32 %phi) |
| |
| ; CHECK: %phi.for.left = phi i32 [ 1, %left ] |
| ; CHECK: call void @h(i32 %phi.for.left) |
| |
| exit: |
| unreachable |
| } |
| |
| declare void @__std_terminate() |