1*9880d681SAndroid Build Coastguard Worker; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workerdeclare i32 @__CxxFrameHandler3(...) 4*9880d681SAndroid Build Coastguard Workerdeclare i32 @__C_specific_handler(...) 5*9880d681SAndroid Build Coastguard Workerdeclare void @ProcessCLRException(...) 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workerdeclare void @f() 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.foo(i32) nounwind 10*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.bar() nounwind 11*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.qux() nounwind 12*9880d681SAndroid Build Coastguard Workerdeclare i1 @llvm.baz() nounwind 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerdefine void @test1() personality i32 (...)* @__CxxFrameHandler3 { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker ; %x def colors: {entry} subset of use colors; must spill 17*9880d681SAndroid Build Coastguard Worker %x = call i32 @llvm.qux() 18*9880d681SAndroid Build Coastguard Worker invoke void @f() 19*9880d681SAndroid Build Coastguard Worker to label %noreturn unwind label %catch.switch 20*9880d681SAndroid Build Coastguard Workercatch.switch: 21*9880d681SAndroid Build Coastguard Worker %cs = catchswitch within none [label %catch] unwind to caller 22*9880d681SAndroid Build Coastguard Workercatch: 23*9880d681SAndroid Build Coastguard Worker %cp = catchpad within %cs [] 24*9880d681SAndroid Build Coastguard Worker br label %noreturn 25*9880d681SAndroid Build Coastguard Workernoreturn: 26*9880d681SAndroid Build Coastguard Worker ; %x use colors: {entry, cleanup} 27*9880d681SAndroid Build Coastguard Worker call void @llvm.foo(i32 %x) 28*9880d681SAndroid Build Coastguard Worker unreachable 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker; Need two copies of the call to @h, one under entry and one under catch. 31*9880d681SAndroid Build Coastguard Worker; Currently we generate a load for each, though we shouldn't need one 32*9880d681SAndroid Build Coastguard Worker; for the use in entry's copy. 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test1( 34*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 35*9880d681SAndroid Build Coastguard Worker; CHECK: %x = call i32 @llvm.qux() 36*9880d681SAndroid Build Coastguard Worker; CHECK: invoke void @f() 37*9880d681SAndroid Build Coastguard Worker; CHECK: to label %[[EntryCopy:[^ ]+]] unwind label %catch 38*9880d681SAndroid Build Coastguard Worker; CHECK: catch.switch: 39*9880d681SAndroid Build Coastguard Worker; CHECK: %cs = catchswitch within none [label %catch] unwind to caller 40*9880d681SAndroid Build Coastguard Worker; CHECK: catch: 41*9880d681SAndroid Build Coastguard Worker; CHECK: catchpad within %cs [] 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.foo(i32 %x) 43*9880d681SAndroid Build Coastguard Worker; CHECK: [[EntryCopy]]: 44*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.foo(i32 %x) 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdefine void @test2() personality i32 (...)* @__CxxFrameHandler3 { 48*9880d681SAndroid Build Coastguard Workerentry: 49*9880d681SAndroid Build Coastguard Worker invoke void @f() 50*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %cleanup 51*9880d681SAndroid Build Coastguard Workercleanup: 52*9880d681SAndroid Build Coastguard Worker cleanuppad within none [] 53*9880d681SAndroid Build Coastguard Worker br label %exit 54*9880d681SAndroid Build Coastguard Workerexit: 55*9880d681SAndroid Build Coastguard Worker call void @llvm.bar() 56*9880d681SAndroid Build Coastguard Worker ret void 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker; Need two copies of %exit's call to @f -- the subsequent ret is only 59*9880d681SAndroid Build Coastguard Worker; valid when coming from %entry, but on the path from %cleanup, this 60*9880d681SAndroid Build Coastguard Worker; might be a valid call to @f which might dynamically not return. 61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2( 62*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 63*9880d681SAndroid Build Coastguard Worker; CHECK: invoke void @f() 64*9880d681SAndroid Build Coastguard Worker; CHECK: to label %[[exit:[^ ]+]] unwind label %cleanup 65*9880d681SAndroid Build Coastguard Worker; CHECK: cleanup: 66*9880d681SAndroid Build Coastguard Worker; CHECK: cleanuppad within none [] 67*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.bar() 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 69*9880d681SAndroid Build Coastguard Worker; CHECK: [[exit]]: 70*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.bar() 71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerdefine void @test3() personality i32 (...)* @__CxxFrameHandler3 { 75*9880d681SAndroid Build Coastguard Workerentry: 76*9880d681SAndroid Build Coastguard Worker invoke void @f() 77*9880d681SAndroid Build Coastguard Worker to label %invoke.cont unwind label %catch.switch 78*9880d681SAndroid Build Coastguard Workerinvoke.cont: 79*9880d681SAndroid Build Coastguard Worker invoke void @f() 80*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %cleanup 81*9880d681SAndroid Build Coastguard Workercatch.switch: 82*9880d681SAndroid Build Coastguard Worker %cs = catchswitch within none [label %catch] unwind to caller 83*9880d681SAndroid Build Coastguard Workercatch: 84*9880d681SAndroid Build Coastguard Worker catchpad within %cs [] 85*9880d681SAndroid Build Coastguard Worker br label %shared 86*9880d681SAndroid Build Coastguard Workercleanup: 87*9880d681SAndroid Build Coastguard Worker cleanuppad within none [] 88*9880d681SAndroid Build Coastguard Worker br label %shared 89*9880d681SAndroid Build Coastguard Workershared: 90*9880d681SAndroid Build Coastguard Worker call void @llvm.bar() 91*9880d681SAndroid Build Coastguard Worker br label %exit 92*9880d681SAndroid Build Coastguard Workerexit: 93*9880d681SAndroid Build Coastguard Worker ret void 94*9880d681SAndroid Build Coastguard Worker} 95*9880d681SAndroid Build Coastguard Worker; Need two copies of %shared's call to @f (similar to @test2 but 96*9880d681SAndroid Build Coastguard Worker; the two regions here are siblings, not parent-child). 97*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test3( 98*9880d681SAndroid Build Coastguard Worker; CHECK: invoke void @f() 99*9880d681SAndroid Build Coastguard Worker; CHECK: invoke void @f() 100*9880d681SAndroid Build Coastguard Worker; CHECK: to label %[[exit:[^ ]+]] unwind 101*9880d681SAndroid Build Coastguard Worker; CHECK: catch: 102*9880d681SAndroid Build Coastguard Worker; CHECK: catchpad within %cs [] 103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.bar() 104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 105*9880d681SAndroid Build Coastguard Worker; CHECK: cleanup: 106*9880d681SAndroid Build Coastguard Worker; CHECK: cleanuppad within none [] 107*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.bar() 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 109*9880d681SAndroid Build Coastguard Worker; CHECK: [[exit]]: 110*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Workerdefine void @test4() personality i32 (...)* @__CxxFrameHandler3 { 114*9880d681SAndroid Build Coastguard Workerentry: 115*9880d681SAndroid Build Coastguard Worker invoke void @f() 116*9880d681SAndroid Build Coastguard Worker to label %shared unwind label %catch.switch 117*9880d681SAndroid Build Coastguard Workercatch.switch: 118*9880d681SAndroid Build Coastguard Worker %cs = catchswitch within none [label %catch] unwind to caller 119*9880d681SAndroid Build Coastguard Workercatch: 120*9880d681SAndroid Build Coastguard Worker catchpad within %cs [] 121*9880d681SAndroid Build Coastguard Worker br label %shared 122*9880d681SAndroid Build Coastguard Workershared: 123*9880d681SAndroid Build Coastguard Worker %x = call i32 @llvm.qux() 124*9880d681SAndroid Build Coastguard Worker %i = call i32 @llvm.qux() 125*9880d681SAndroid Build Coastguard Worker %zero.trip = icmp eq i32 %i, 0 126*9880d681SAndroid Build Coastguard Worker br i1 %zero.trip, label %exit, label %loop 127*9880d681SAndroid Build Coastguard Workerloop: 128*9880d681SAndroid Build Coastguard Worker %i.loop = phi i32 [ %i, %shared ], [ %i.dec, %loop.tail ] 129*9880d681SAndroid Build Coastguard Worker %b = call i1 @llvm.baz() 130*9880d681SAndroid Build Coastguard Worker br i1 %b, label %left, label %right 131*9880d681SAndroid Build Coastguard Workerleft: 132*9880d681SAndroid Build Coastguard Worker %y = call i32 @llvm.qux() 133*9880d681SAndroid Build Coastguard Worker br label %loop.tail 134*9880d681SAndroid Build Coastguard Workerright: 135*9880d681SAndroid Build Coastguard Worker call void @llvm.foo(i32 %x) 136*9880d681SAndroid Build Coastguard Worker br label %loop.tail 137*9880d681SAndroid Build Coastguard Workerloop.tail: 138*9880d681SAndroid Build Coastguard Worker %i.dec = sub i32 %i.loop, 1 139*9880d681SAndroid Build Coastguard Worker %done = icmp eq i32 %i.dec, 0 140*9880d681SAndroid Build Coastguard Worker br i1 %done, label %exit, label %loop 141*9880d681SAndroid Build Coastguard Workerexit: 142*9880d681SAndroid Build Coastguard Worker call void @llvm.foo(i32 %x) 143*9880d681SAndroid Build Coastguard Worker unreachable 144*9880d681SAndroid Build Coastguard Worker} 145*9880d681SAndroid Build Coastguard Worker; Make sure we can clone regions that have internal control 146*9880d681SAndroid Build Coastguard Worker; flow and SSA values. Here we need two copies of everything 147*9880d681SAndroid Build Coastguard Worker; from %shared to %exit. 148*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test4( 149*9880d681SAndroid Build Coastguard Worker; CHECK: entry: 150*9880d681SAndroid Build Coastguard Worker; CHECK: to label %[[shared_E:[^ ]+]] unwind label %catch.switch 151*9880d681SAndroid Build Coastguard Worker; CHECK: catch: 152*9880d681SAndroid Build Coastguard Worker; CHECK: catchpad within %cs [] 153*9880d681SAndroid Build Coastguard Worker; CHECK: [[x_C:%[^ ]+]] = call i32 @llvm.qux() 154*9880d681SAndroid Build Coastguard Worker; CHECK: [[i_C:%[^ ]+]] = call i32 @llvm.qux() 155*9880d681SAndroid Build Coastguard Worker; CHECK: [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0 156*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[zt_C]], label %[[exit_C:[^ ]+]], label %[[loop_C:[^ ]+]] 157*9880d681SAndroid Build Coastguard Worker; CHECK: [[shared_E]]: 158*9880d681SAndroid Build Coastguard Worker; CHECK: [[x_E:%[^ ]+]] = call i32 @llvm.qux() 159*9880d681SAndroid Build Coastguard Worker; CHECK: [[i_E:%[^ ]+]] = call i32 @llvm.qux() 160*9880d681SAndroid Build Coastguard Worker; CHECK: [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0 161*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]] 162*9880d681SAndroid Build Coastguard Worker; CHECK: [[loop_C]]: 163*9880d681SAndroid Build Coastguard Worker; CHECK: [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ] 164*9880d681SAndroid Build Coastguard Worker; CHECK: [[b_C:%[^ ]+]] = call i1 @llvm.baz() 165*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]] 166*9880d681SAndroid Build Coastguard Worker; CHECK: [[loop_E]]: 167*9880d681SAndroid Build Coastguard Worker; CHECK: [[iloop_E:%[^ ]+]] = phi i32 [ [[i_E]], %[[shared_E]] ], [ [[idec_E:%[^ ]+]], %[[looptail_E:[^ ]+]] ] 168*9880d681SAndroid Build Coastguard Worker; CHECK: [[b_E:%[^ ]+]] = call i1 @llvm.baz() 169*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]] 170*9880d681SAndroid Build Coastguard Worker; CHECK: [[left_C]]: 171*9880d681SAndroid Build Coastguard Worker; CHECK: [[y_C:%[^ ]+]] = call i32 @llvm.qux() 172*9880d681SAndroid Build Coastguard Worker; CHECK: br label %[[looptail_C]] 173*9880d681SAndroid Build Coastguard Worker; CHECK: [[left_E]]: 174*9880d681SAndroid Build Coastguard Worker; CHECK: [[y_E:%[^ ]+]] = call i32 @llvm.qux() 175*9880d681SAndroid Build Coastguard Worker; CHECK: br label %[[looptail_E]] 176*9880d681SAndroid Build Coastguard Worker; CHECK: [[right_C]]: 177*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.foo(i32 [[x_C]]) 178*9880d681SAndroid Build Coastguard Worker; CHECK: br label %[[looptail_C]] 179*9880d681SAndroid Build Coastguard Worker; CHECK: [[right_E]]: 180*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.foo(i32 [[x_E]]) 181*9880d681SAndroid Build Coastguard Worker; CHECK: br label %[[looptail_E]] 182*9880d681SAndroid Build Coastguard Worker; CHECK: [[looptail_C]]: 183*9880d681SAndroid Build Coastguard Worker; CHECK: [[idec_C]] = sub i32 [[iloop_C]], 1 184*9880d681SAndroid Build Coastguard Worker; CHECK: [[done_C:%[^ ]+]] = icmp eq i32 [[idec_C]], 0 185*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[done_C]], label %[[exit_C]], label %[[loop_C]] 186*9880d681SAndroid Build Coastguard Worker; CHECK: [[looptail_E]]: 187*9880d681SAndroid Build Coastguard Worker; CHECK: [[idec_E]] = sub i32 [[iloop_E]], 1 188*9880d681SAndroid Build Coastguard Worker; CHECK: [[done_E:%[^ ]+]] = icmp eq i32 [[idec_E]], 0 189*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 [[done_E]], label %[[exit_E]], label %[[loop_E]] 190*9880d681SAndroid Build Coastguard Worker; CHECK: [[exit_C]]: 191*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.foo(i32 [[x_C]]) 192*9880d681SAndroid Build Coastguard Worker; CHECK: unreachable 193*9880d681SAndroid Build Coastguard Worker; CHECK: [[exit_E]]: 194*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.foo(i32 [[x_E]]) 195*9880d681SAndroid Build Coastguard Worker; CHECK: unreachable 196*9880d681SAndroid Build Coastguard Worker 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerdefine void @test5() personality i32 (...)* @__C_specific_handler { 199*9880d681SAndroid Build Coastguard Workerentry: 200*9880d681SAndroid Build Coastguard Worker invoke void @f() 201*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %outer 202*9880d681SAndroid Build Coastguard Workerouter: 203*9880d681SAndroid Build Coastguard Worker %o = cleanuppad within none [] 204*9880d681SAndroid Build Coastguard Worker %x = call i32 @llvm.qux() 205*9880d681SAndroid Build Coastguard Worker invoke void @f() [ "funclet"(token %o) ] 206*9880d681SAndroid Build Coastguard Worker to label %outer.ret unwind label %catch.switch 207*9880d681SAndroid Build Coastguard Workercatch.switch: 208*9880d681SAndroid Build Coastguard Worker %cs = catchswitch within %o [label %inner] unwind to caller 209*9880d681SAndroid Build Coastguard Workerinner: 210*9880d681SAndroid Build Coastguard Worker %i = catchpad within %cs [] 211*9880d681SAndroid Build Coastguard Worker catchret from %i to label %outer.post-inner 212*9880d681SAndroid Build Coastguard Workerouter.post-inner: 213*9880d681SAndroid Build Coastguard Worker call void @llvm.foo(i32 %x) 214*9880d681SAndroid Build Coastguard Worker br label %outer.ret 215*9880d681SAndroid Build Coastguard Workerouter.ret: 216*9880d681SAndroid Build Coastguard Worker cleanupret from %o unwind to caller 217*9880d681SAndroid Build Coastguard Workerexit: 218*9880d681SAndroid Build Coastguard Worker ret void 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker; Simple nested case (catch-inside-cleanup). Nothing needs 221*9880d681SAndroid Build Coastguard Worker; to be cloned. The def and use of %x are both in %outer 222*9880d681SAndroid Build Coastguard Worker; and so don't need to be spilled. 223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test5( 224*9880d681SAndroid Build Coastguard Worker; CHECK: outer: 225*9880d681SAndroid Build Coastguard Worker; CHECK: %x = call i32 @llvm.qux() 226*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: invoke void @f() 227*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: to label %outer.ret unwind label %catch.switch 228*9880d681SAndroid Build Coastguard Worker; CHECK: inner: 229*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %i = catchpad within %cs [] 230*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catchret from %i to label %outer.post-inner 231*9880d681SAndroid Build Coastguard Worker; CHECK: outer.post-inner: 232*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.foo(i32 %x) 233*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %outer.ret 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Worker 236*9880d681SAndroid Build Coastguard Workerdefine void @test10() personality i32 (...)* @__CxxFrameHandler3 { 237*9880d681SAndroid Build Coastguard Workerentry: 238*9880d681SAndroid Build Coastguard Worker invoke void @f() 239*9880d681SAndroid Build Coastguard Worker to label %unreachable unwind label %inner 240*9880d681SAndroid Build Coastguard Workerinner: 241*9880d681SAndroid Build Coastguard Worker %cleanup = cleanuppad within none [] 242*9880d681SAndroid Build Coastguard Worker ; make sure we don't overlook this cleanupret and try to process 243*9880d681SAndroid Build Coastguard Worker ; successor %outer as a child of inner. 244*9880d681SAndroid Build Coastguard Worker cleanupret from %cleanup unwind label %outer 245*9880d681SAndroid Build Coastguard Workerouter: 246*9880d681SAndroid Build Coastguard Worker %cs = catchswitch within none [label %catch.body] unwind to caller 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Workercatch.body: 249*9880d681SAndroid Build Coastguard Worker %catch = catchpad within %cs [] 250*9880d681SAndroid Build Coastguard Worker catchret from %catch to label %exit 251*9880d681SAndroid Build Coastguard Workerexit: 252*9880d681SAndroid Build Coastguard Worker ret void 253*9880d681SAndroid Build Coastguard Workerunreachable: 254*9880d681SAndroid Build Coastguard Worker unreachable 255*9880d681SAndroid Build Coastguard Worker} 256*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test10( 257*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 258*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: invoke 259*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: to label %unreachable unwind label %inner 260*9880d681SAndroid Build Coastguard Worker; CHECK: inner: 261*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %cleanup = cleanuppad within none [] 262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cleanupret from %cleanup unwind label %outer 263*9880d681SAndroid Build Coastguard Worker; CHECK: outer: 264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %cs = catchswitch within none [label %catch.body] unwind to caller 265*9880d681SAndroid Build Coastguard Worker; CHECK: catch.body: 266*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %catch = catchpad within %cs [] 267*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: catchret from %catch to label %exit 268*9880d681SAndroid Build Coastguard Worker; CHECK: exit: 269*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Workerdefine void @test11() personality i32 (...)* @__C_specific_handler { 272*9880d681SAndroid Build Coastguard Workerentry: 273*9880d681SAndroid Build Coastguard Worker invoke void @f() 274*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %cleanup.outer 275*9880d681SAndroid Build Coastguard Workercleanup.outer: 276*9880d681SAndroid Build Coastguard Worker %outer = cleanuppad within none [] 277*9880d681SAndroid Build Coastguard Worker invoke void @f() [ "funclet"(token %outer) ] 278*9880d681SAndroid Build Coastguard Worker to label %outer.cont unwind label %cleanup.inner 279*9880d681SAndroid Build Coastguard Workerouter.cont: 280*9880d681SAndroid Build Coastguard Worker br label %merge 281*9880d681SAndroid Build Coastguard Workercleanup.inner: 282*9880d681SAndroid Build Coastguard Worker %inner = cleanuppad within %outer [] 283*9880d681SAndroid Build Coastguard Worker br label %merge 284*9880d681SAndroid Build Coastguard Workermerge: 285*9880d681SAndroid Build Coastguard Worker call void @llvm.bar() 286*9880d681SAndroid Build Coastguard Worker unreachable 287*9880d681SAndroid Build Coastguard Workerexit: 288*9880d681SAndroid Build Coastguard Worker ret void 289*9880d681SAndroid Build Coastguard Worker} 290*9880d681SAndroid Build Coastguard Worker; merge.end will get cloned for outer and inner, but is implausible 291*9880d681SAndroid Build Coastguard Worker; from inner, so the call @f() in inner's copy of merge should be 292*9880d681SAndroid Build Coastguard Worker; rewritten to call @f() 293*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test11() 294*9880d681SAndroid Build Coastguard Worker; CHECK: %inner = cleanuppad within %outer [] 295*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.bar() 296*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 297*9880d681SAndroid Build Coastguard Worker 298*9880d681SAndroid Build Coastguard Workerdefine void @test12() personality i32 (...)* @__CxxFrameHandler3 !dbg !5 { 299*9880d681SAndroid Build Coastguard Workerentry: 300*9880d681SAndroid Build Coastguard Worker invoke void @f() 301*9880d681SAndroid Build Coastguard Worker to label %cont unwind label %left, !dbg !8 302*9880d681SAndroid Build Coastguard Workercont: 303*9880d681SAndroid Build Coastguard Worker invoke void @f() 304*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %right 305*9880d681SAndroid Build Coastguard Workerleft: 306*9880d681SAndroid Build Coastguard Worker cleanuppad within none [] 307*9880d681SAndroid Build Coastguard Worker br label %join 308*9880d681SAndroid Build Coastguard Workerright: 309*9880d681SAndroid Build Coastguard Worker cleanuppad within none [] 310*9880d681SAndroid Build Coastguard Worker br label %join 311*9880d681SAndroid Build Coastguard Workerjoin: 312*9880d681SAndroid Build Coastguard Worker ; This call will get cloned; make sure we can handle cloning 313*9880d681SAndroid Build Coastguard Worker ; instructions with debug metadata attached. 314*9880d681SAndroid Build Coastguard Worker call void @llvm.bar(), !dbg !9 315*9880d681SAndroid Build Coastguard Worker unreachable 316*9880d681SAndroid Build Coastguard Workerexit: 317*9880d681SAndroid Build Coastguard Worker ret void 318*9880d681SAndroid Build Coastguard Worker} 319*9880d681SAndroid Build Coastguard Worker 320*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test13() 321*9880d681SAndroid Build Coastguard Worker; CHECK: ret void 322*9880d681SAndroid Build Coastguard Workerdefine void @test13() personality i32 (...)* @__CxxFrameHandler3 { 323*9880d681SAndroid Build Coastguard Workerentry: 324*9880d681SAndroid Build Coastguard Worker ret void 325*9880d681SAndroid Build Coastguard Worker 326*9880d681SAndroid Build Coastguard Workerunreachable: 327*9880d681SAndroid Build Coastguard Worker cleanuppad within none [] 328*9880d681SAndroid Build Coastguard Worker unreachable 329*9880d681SAndroid Build Coastguard Worker} 330*9880d681SAndroid Build Coastguard Worker 331*9880d681SAndroid Build Coastguard Workerdefine void @test14() personality void (...)* @ProcessCLRException { 332*9880d681SAndroid Build Coastguard Workerentry: 333*9880d681SAndroid Build Coastguard Worker invoke void @f() 334*9880d681SAndroid Build Coastguard Worker to label %cont unwind label %cleanup 335*9880d681SAndroid Build Coastguard Workercont: 336*9880d681SAndroid Build Coastguard Worker invoke void @f() 337*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %switch.outer 338*9880d681SAndroid Build Coastguard Workercleanup: 339*9880d681SAndroid Build Coastguard Worker %cleanpad = cleanuppad within none [] 340*9880d681SAndroid Build Coastguard Worker invoke void @f() [ "funclet" (token %cleanpad) ] 341*9880d681SAndroid Build Coastguard Worker to label %cleanret unwind label %switch.inner 342*9880d681SAndroid Build Coastguard Workerswitch.inner: 343*9880d681SAndroid Build Coastguard Worker %cs.inner = catchswitch within %cleanpad [label %pad.inner] unwind to caller 344*9880d681SAndroid Build Coastguard Workerpad.inner: 345*9880d681SAndroid Build Coastguard Worker %cp.inner = catchpad within %cs.inner [i32 1] 346*9880d681SAndroid Build Coastguard Worker catchret from %cp.inner to label %join 347*9880d681SAndroid Build Coastguard Workercleanret: 348*9880d681SAndroid Build Coastguard Worker cleanupret from %cleanpad unwind to caller 349*9880d681SAndroid Build Coastguard Workerswitch.outer: 350*9880d681SAndroid Build Coastguard Worker %cs.outer = catchswitch within none [label %pad.outer] unwind to caller 351*9880d681SAndroid Build Coastguard Workerpad.outer: 352*9880d681SAndroid Build Coastguard Worker %cp.outer = catchpad within %cs.outer [i32 2] 353*9880d681SAndroid Build Coastguard Worker catchret from %cp.outer to label %join 354*9880d681SAndroid Build Coastguard Workerjoin: 355*9880d681SAndroid Build Coastguard Worker %phi = phi i32 [ 1, %pad.inner ], [ 2, %pad.outer ] 356*9880d681SAndroid Build Coastguard Worker call void @llvm.foo(i32 %phi) 357*9880d681SAndroid Build Coastguard Worker unreachable 358*9880d681SAndroid Build Coastguard Workerexit: 359*9880d681SAndroid Build Coastguard Worker ret void 360*9880d681SAndroid Build Coastguard Worker} 361*9880d681SAndroid Build Coastguard Worker; Both catchrets target %join, but the catchret from %cp.inner 362*9880d681SAndroid Build Coastguard Worker; returns to %cleanpad and the catchret from %cp.outer returns to the 363*9880d681SAndroid Build Coastguard Worker; main function, so %join needs to get cloned and one of the cleanuprets 364*9880d681SAndroid Build Coastguard Worker; needs to be updated to target the clone 365*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test14() 366*9880d681SAndroid Build Coastguard Worker; CHECK: catchret from %cp.inner to label %[[Clone1:.+]] 367*9880d681SAndroid Build Coastguard Worker; CHECK: catchret from %cp.outer to label %[[Clone2:.+]] 368*9880d681SAndroid Build Coastguard Worker; CHECK: [[Clone1]]: 369*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.foo(i32 1) 370*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 371*9880d681SAndroid Build Coastguard Worker; CHECK: [[Clone2]]: 372*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.foo(i32 2) 373*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable 374*9880d681SAndroid Build Coastguard Worker 375*9880d681SAndroid Build Coastguard Worker;; Debug info (from test12) 376*9880d681SAndroid Build Coastguard Worker 377*9880d681SAndroid Build Coastguard Worker; Make sure the DISubprogram doesn't get cloned 378*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: !llvm.module.flags 379*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !DISubprogram 380*9880d681SAndroid Build Coastguard Worker; CHECK: !{{[0-9]+}} = distinct !DISubprogram(name: "test12" 381*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !DISubprogram 382*9880d681SAndroid Build Coastguard Worker!llvm.module.flags = !{!0} 383*9880d681SAndroid Build Coastguard Worker!llvm.dbg.cu = !{!1} 384*9880d681SAndroid Build Coastguard Worker 385*9880d681SAndroid Build Coastguard Worker!0 = !{i32 2, !"Debug Info Version", i32 3} 386*9880d681SAndroid Build Coastguard Worker!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3) 387*9880d681SAndroid Build Coastguard Worker!2 = !DIFile(filename: "test.cpp", directory: ".") 388*9880d681SAndroid Build Coastguard Worker!3 = !{} 389*9880d681SAndroid Build Coastguard Worker!5 = distinct !DISubprogram(name: "test12", scope: !2, file: !2, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !1, variables: !3) 390*9880d681SAndroid Build Coastguard Worker!6 = !DISubroutineType(types: !7) 391*9880d681SAndroid Build Coastguard Worker!7 = !{null} 392*9880d681SAndroid Build Coastguard Worker!8 = !DILocation(line: 1, scope: !5) 393*9880d681SAndroid Build Coastguard Worker!9 = !DILocation(line: 2, scope: !5) 394