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 Worker 5*9880d681SAndroid Build Coastguard Workerdeclare void @f() 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Workerdeclare i32 @g() 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdeclare void @h(i32) 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdeclare i1 @i() 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.bar() nounwind 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 16*9880d681SAndroid Build Coastguard Workerdefine void @test1(i1 %B) personality i32 (...)* @__CxxFrameHandler3 { 17*9880d681SAndroid Build Coastguard Workerentry: 18*9880d681SAndroid Build Coastguard Worker ; Spill slot should be inserted here 19*9880d681SAndroid Build Coastguard Worker ; CHECK: [[Slot:%[^ ]+]] = alloca 20*9880d681SAndroid Build Coastguard Worker ; Can't store for %phi at these defs because the lifetimes overlap 21*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: store 22*9880d681SAndroid Build Coastguard Worker %x = call i32 @g() 23*9880d681SAndroid Build Coastguard Worker %y = call i32 @g() 24*9880d681SAndroid Build Coastguard Worker br i1 %B, label %left, label %right 25*9880d681SAndroid Build Coastguard Workerleft: 26*9880d681SAndroid Build Coastguard Worker ; CHECK: left: 27*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 %x, i32* [[Slot]] 28*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 29*9880d681SAndroid Build Coastguard Worker invoke void @f() 30*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %merge 31*9880d681SAndroid Build Coastguard Workerright: 32*9880d681SAndroid Build Coastguard Worker ; CHECK: right: 33*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 %y, i32* [[Slot]] 34*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 35*9880d681SAndroid Build Coastguard Worker invoke void @f() 36*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %merge 37*9880d681SAndroid Build Coastguard Workermerge: 38*9880d681SAndroid Build Coastguard Worker ; CHECK: merge: 39*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: = phi 40*9880d681SAndroid Build Coastguard Worker %phi = phi i32 [ %x, %left ], [ %y, %right ] 41*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch] unwind to caller 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workercatch: 44*9880d681SAndroid Build Coastguard Worker %cp = catchpad within %cs1 [] 45*9880d681SAndroid Build Coastguard Worker ; CHECK: catch: 46*9880d681SAndroid Build Coastguard Worker ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]] 47*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: call void @h(i32 [[Reload]]) 48*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi) [ "funclet"(token %cp) ] 49*9880d681SAndroid Build Coastguard Worker catchret from %cp to label %exit 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerexit: 52*9880d681SAndroid Build Coastguard Worker ret void 53*9880d681SAndroid Build Coastguard Worker} 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 56*9880d681SAndroid Build Coastguard Workerdefine void @test2(i1 %B) personality i32 (...)* @__CxxFrameHandler3 { 57*9880d681SAndroid Build Coastguard Workerentry: 58*9880d681SAndroid Build Coastguard Worker br i1 %B, label %left, label %right 59*9880d681SAndroid Build Coastguard Workerleft: 60*9880d681SAndroid Build Coastguard Worker ; Need two stores here because %x and %y interfere so they need 2 slots 61*9880d681SAndroid Build Coastguard Worker ; CHECK: left: 62*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 1, i32* [[Slot1:%[^ ]+]] 63*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 1, i32* [[Slot2:%[^ ]+]] 64*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 65*9880d681SAndroid Build Coastguard Worker invoke void @f() 66*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %merge.inner 67*9880d681SAndroid Build Coastguard Workerright: 68*9880d681SAndroid Build Coastguard Worker ; Need two stores here because %x and %y interfere so they need 2 slots 69*9880d681SAndroid Build Coastguard Worker ; CHECK: right: 70*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: store i32 2, i32* [[Slot1]] 71*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: store i32 2, i32* [[Slot2]] 72*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke void @f 73*9880d681SAndroid Build Coastguard Worker invoke void @f() 74*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %merge.inner 75*9880d681SAndroid Build Coastguard Workermerge.inner: 76*9880d681SAndroid Build Coastguard Worker ; CHECK: merge.inner: 77*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: = phi 78*9880d681SAndroid Build Coastguard Worker ; CHECK: catchswitch within none 79*9880d681SAndroid Build Coastguard Worker %x = phi i32 [ 1, %left ], [ 2, %right ] 80*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch.inner] unwind label %merge.outer 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workercatch.inner: 83*9880d681SAndroid Build Coastguard Worker %cpinner = catchpad within %cs1 [] 84*9880d681SAndroid Build Coastguard Worker ; Need just one store here because only %y is affected 85*9880d681SAndroid Build Coastguard Worker ; CHECK: catch.inner: 86*9880d681SAndroid Build Coastguard Worker %z = call i32 @g() [ "funclet"(token %cpinner) ] 87*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 %z 88*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 89*9880d681SAndroid Build Coastguard Worker invoke void @f() [ "funclet"(token %cpinner) ] 90*9880d681SAndroid Build Coastguard Worker to label %catchret.inner unwind label %merge.outer 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Workercatchret.inner: 93*9880d681SAndroid Build Coastguard Worker catchret from %cpinner to label %exit 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Workermerge.outer: 96*9880d681SAndroid Build Coastguard Worker %y = phi i32 [ %x, %merge.inner ], [ %z, %catch.inner ] 97*9880d681SAndroid Build Coastguard Worker ; CHECK: merge.outer: 98*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: = phi 99*9880d681SAndroid Build Coastguard Worker ; CHECK: catchswitch within none 100*9880d681SAndroid Build Coastguard Worker %cs2 = catchswitch within none [label %catch.outer] unwind to caller 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workercatch.outer: 103*9880d681SAndroid Build Coastguard Worker %cpouter = catchpad within %cs2 [] 104*9880d681SAndroid Build Coastguard Worker ; CHECK: catch.outer: 105*9880d681SAndroid Build Coastguard Worker ; CHECK: [[CatchPad:%[^ ]+]] = catchpad within %cs2 [] 106*9880d681SAndroid Build Coastguard Worker ; Need to load x and y from two different slots since they're both live 107*9880d681SAndroid Build Coastguard Worker ; and can have different values (if we came from catch.inner) 108*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: load i32, i32* [[Slot1]] 109*9880d681SAndroid Build Coastguard Worker ; CHECK-DAG: load i32, i32* [[Slot2]] 110*9880d681SAndroid Build Coastguard Worker ; CHECK: catchret from [[CatchPad]] to label 111*9880d681SAndroid Build Coastguard Worker call void @h(i32 %x) [ "funclet"(token %cpouter) ] 112*9880d681SAndroid Build Coastguard Worker call void @h(i32 %y) [ "funclet"(token %cpouter) ] 113*9880d681SAndroid Build Coastguard Worker catchret from %cpouter to label %exit 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerexit: 116*9880d681SAndroid Build Coastguard Worker ret void 117*9880d681SAndroid Build Coastguard Worker} 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; test4: don't need stores for %phi.inner, as its only use is to feed %phi.outer 120*9880d681SAndroid Build Coastguard Worker; %phi.outer needs stores in %left, %right, and %join 121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 122*9880d681SAndroid Build Coastguard Workerdefine void @test4(i1 %B) personality i32 (...)* @__CxxFrameHandler3 { 123*9880d681SAndroid Build Coastguard Workerentry: 124*9880d681SAndroid Build Coastguard Worker ; CHECK: entry: 125*9880d681SAndroid Build Coastguard Worker ; CHECK: [[Slot:%[^ ]+]] = alloca 126*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: br 127*9880d681SAndroid Build Coastguard Worker br i1 %B, label %left, label %right 128*9880d681SAndroid Build Coastguard Workerleft: 129*9880d681SAndroid Build Coastguard Worker ; CHECK: left: 130*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: store 131*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 %l, i32* [[Slot]] 132*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 133*9880d681SAndroid Build Coastguard Worker %l = call i32 @g() 134*9880d681SAndroid Build Coastguard Worker invoke void @f() 135*9880d681SAndroid Build Coastguard Worker to label %join unwind label %catchpad.inner 136*9880d681SAndroid Build Coastguard Workerright: 137*9880d681SAndroid Build Coastguard Worker ; CHECK: right: 138*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: store 139*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 %r, i32* [[Slot]] 140*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 141*9880d681SAndroid Build Coastguard Worker %r = call i32 @g() 142*9880d681SAndroid Build Coastguard Worker invoke void @f() 143*9880d681SAndroid Build Coastguard Worker to label %join unwind label %catchpad.inner 144*9880d681SAndroid Build Coastguard Workercatchpad.inner: 145*9880d681SAndroid Build Coastguard Worker ; CHECK: catchpad.inner: 146*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: catchswitch within none 147*9880d681SAndroid Build Coastguard Worker %phi.inner = phi i32 [ %l, %left ], [ %r, %right ] 148*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch.inner] unwind label %catchpad.outer 149*9880d681SAndroid Build Coastguard Workercatch.inner: 150*9880d681SAndroid Build Coastguard Worker %cp1 = catchpad within %cs1 [] 151*9880d681SAndroid Build Coastguard Worker catchret from %cp1 to label %join 152*9880d681SAndroid Build Coastguard Workerjoin: 153*9880d681SAndroid Build Coastguard Worker ; CHECK: join: 154*9880d681SAndroid Build Coastguard Worker ; CHECK-NOT: store 155*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 %j, i32* [[Slot]] 156*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 157*9880d681SAndroid Build Coastguard Worker %j = call i32 @g() 158*9880d681SAndroid Build Coastguard Worker invoke void @f() 159*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %catchpad.outer 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workercatchpad.outer: 162*9880d681SAndroid Build Coastguard Worker ; CHECK: catchpad.outer: 163*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: catchswitch within none 164*9880d681SAndroid Build Coastguard Worker %phi.outer = phi i32 [ %phi.inner, %catchpad.inner ], [ %j, %join ] 165*9880d681SAndroid Build Coastguard Worker %cs2 = catchswitch within none [label %catch.outer] unwind to caller 166*9880d681SAndroid Build Coastguard Workercatch.outer: 167*9880d681SAndroid Build Coastguard Worker ; CHECK: catch.outer: 168*9880d681SAndroid Build Coastguard Worker ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]] 169*9880d681SAndroid Build Coastguard Worker ; CHECK: call void @h(i32 [[Reload]]) 170*9880d681SAndroid Build Coastguard Worker %cp2 = catchpad within %cs2 [] 171*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi.outer) [ "funclet"(token %cp2) ] 172*9880d681SAndroid Build Coastguard Worker catchret from %cp2 to label %exit 173*9880d681SAndroid Build Coastguard Workerexit: 174*9880d681SAndroid Build Coastguard Worker ret void 175*9880d681SAndroid Build Coastguard Worker} 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 178*9880d681SAndroid Build Coastguard Workerdefine void @test5() personality i32 (...)* @__CxxFrameHandler3 { 179*9880d681SAndroid Build Coastguard Workerentry: 180*9880d681SAndroid Build Coastguard Worker ; need store for %phi.cleanup 181*9880d681SAndroid Build Coastguard Worker ; CHECK: entry: 182*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 1, i32* [[CleanupSlot:%[^ ]+]] 183*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 184*9880d681SAndroid Build Coastguard Worker invoke void @f() 185*9880d681SAndroid Build Coastguard Worker to label %invoke.cont unwind label %cleanup 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Workerinvoke.cont: 188*9880d681SAndroid Build Coastguard Worker ; need store for %phi.cleanup 189*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke.cont: 190*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 2, i32* [[CleanupSlot]] 191*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 192*9880d681SAndroid Build Coastguard Worker invoke void @f() 193*9880d681SAndroid Build Coastguard Worker to label %invoke.cont2 unwind label %cleanup 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Workercleanup: 196*9880d681SAndroid Build Coastguard Worker ; cleanup phi can be loaded at cleanup entry 197*9880d681SAndroid Build Coastguard Worker ; CHECK: cleanup: 198*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: cleanuppad within none [] 199*9880d681SAndroid Build Coastguard Worker ; CHECK: [[CleanupReload:%[^ ]+]] = load i32, i32* [[CleanupSlot]] 200*9880d681SAndroid Build Coastguard Worker %phi.cleanup = phi i32 [ 1, %entry ], [ 2, %invoke.cont ] 201*9880d681SAndroid Build Coastguard Worker %cp = cleanuppad within none [] 202*9880d681SAndroid Build Coastguard Worker %b = call i1 @i() [ "funclet"(token %cp) ] 203*9880d681SAndroid Build Coastguard Worker br i1 %b, label %left, label %right 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Workerleft: 206*9880d681SAndroid Build Coastguard Worker ; CHECK: left: 207*9880d681SAndroid Build Coastguard Worker ; CHECK: call void @h(i32 [[CleanupReload]] 208*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ] 209*9880d681SAndroid Build Coastguard Worker br label %merge 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Workerright: 212*9880d681SAndroid Build Coastguard Worker ; CHECK: right: 213*9880d681SAndroid Build Coastguard Worker ; CHECK: call void @h(i32 [[CleanupReload]] 214*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ] 215*9880d681SAndroid Build Coastguard Worker br label %merge 216*9880d681SAndroid Build Coastguard Worker 217*9880d681SAndroid Build Coastguard Workermerge: 218*9880d681SAndroid Build Coastguard Worker ; need store for %phi.catch 219*9880d681SAndroid Build Coastguard Worker ; CHECK: merge: 220*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 [[CleanupReload]], i32* [[CatchSlot:%[^ ]+]] 221*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: cleanupret 222*9880d681SAndroid Build Coastguard Worker cleanupret from %cp unwind label %catchswitch 223*9880d681SAndroid Build Coastguard Worker 224*9880d681SAndroid Build Coastguard Workerinvoke.cont2: 225*9880d681SAndroid Build Coastguard Worker ; need store for %phi.catch 226*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke.cont2: 227*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: store i32 3, i32* [[CatchSlot]] 228*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: invoke void @f 229*9880d681SAndroid Build Coastguard Worker invoke void @f() 230*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %catchswitch 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Workercatchswitch: 233*9880d681SAndroid Build Coastguard Worker ; CHECK: catchswitch: 234*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: catchswitch within none 235*9880d681SAndroid Build Coastguard Worker %phi.catch = phi i32 [ %phi.cleanup, %merge ], [ 3, %invoke.cont2 ] 236*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch] unwind to caller 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Workercatch: 239*9880d681SAndroid Build Coastguard Worker ; CHECK: catch: 240*9880d681SAndroid Build Coastguard Worker ; CHECK: catchpad within %cs1 241*9880d681SAndroid Build Coastguard Worker ; CHECK: [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]] 242*9880d681SAndroid Build Coastguard Worker ; CHECK: call void @h(i32 [[CatchReload]] 243*9880d681SAndroid Build Coastguard Worker %cp2 = catchpad within %cs1 [] 244*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi.catch) [ "funclet"(token %cp2) ] 245*9880d681SAndroid Build Coastguard Worker catchret from %cp2 to label %exit 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Workerexit: 248*9880d681SAndroid Build Coastguard Worker ret void 249*9880d681SAndroid Build Coastguard Worker} 250*9880d681SAndroid Build Coastguard Worker 251*9880d681SAndroid Build Coastguard Worker; We used to demote %x, but we don't need to anymore. 252*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6( 253*9880d681SAndroid Build Coastguard Workerdefine void @test6() personality i32 (...)* @__CxxFrameHandler3 { 254*9880d681SAndroid Build Coastguard Workerentry: 255*9880d681SAndroid Build Coastguard Worker ; CHECK: entry: 256*9880d681SAndroid Build Coastguard Worker ; CHECK: %x = invoke i32 @g() 257*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: to label %loop unwind label %to_caller 258*9880d681SAndroid Build Coastguard Worker %x = invoke i32 @g() 259*9880d681SAndroid Build Coastguard Worker to label %loop unwind label %to_caller 260*9880d681SAndroid Build Coastguard Workerto_caller: 261*9880d681SAndroid Build Coastguard Worker %cp1 = cleanuppad within none [] 262*9880d681SAndroid Build Coastguard Worker cleanupret from %cp1 unwind to caller 263*9880d681SAndroid Build Coastguard Workerloop: 264*9880d681SAndroid Build Coastguard Worker invoke void @f() 265*9880d681SAndroid Build Coastguard Worker to label %loop unwind label %cleanup 266*9880d681SAndroid Build Coastguard Workercleanup: 267*9880d681SAndroid Build Coastguard Worker ; CHECK: cleanup: 268*9880d681SAndroid Build Coastguard Worker ; CHECK: call void @h(i32 %x) 269*9880d681SAndroid Build Coastguard Worker %cp2 = cleanuppad within none [] 270*9880d681SAndroid Build Coastguard Worker call void @h(i32 %x) [ "funclet"(token %cp2) ] 271*9880d681SAndroid Build Coastguard Worker cleanupret from %cp2 unwind to caller 272*9880d681SAndroid Build Coastguard Worker} 273*9880d681SAndroid Build Coastguard Worker 274*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7( 275*9880d681SAndroid Build Coastguard Workerdefine void @test7() personality i32 (...)* @__CxxFrameHandler3 { 276*9880d681SAndroid Build Coastguard Workerentry: 277*9880d681SAndroid Build Coastguard Worker ; %x is an EH pad phi, so gets stored in pred here 278*9880d681SAndroid Build Coastguard Worker ; CHECK: entry: 279*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 1, i32* [[SlotX:%[^ ]+]] 280*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke void @f() 281*9880d681SAndroid Build Coastguard Worker invoke void @f() 282*9880d681SAndroid Build Coastguard Worker to label %invoke.cont unwind label %catchpad 283*9880d681SAndroid Build Coastguard Workerinvoke.cont: 284*9880d681SAndroid Build Coastguard Worker ; %x is an EH pad phi, so gets stored in pred here 285*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke.cont: 286*9880d681SAndroid Build Coastguard Worker ; CHECK: store i32 2, i32* [[SlotX]] 287*9880d681SAndroid Build Coastguard Worker ; CHECK: invoke void @f() 288*9880d681SAndroid Build Coastguard Worker invoke void @f() 289*9880d681SAndroid Build Coastguard Worker to label %exit unwind label %catchpad 290*9880d681SAndroid Build Coastguard Workercatchpad: 291*9880d681SAndroid Build Coastguard Worker ; %x phi should be eliminated 292*9880d681SAndroid Build Coastguard Worker ; CHECK: catchpad: 293*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: catchswitch within none 294*9880d681SAndroid Build Coastguard Worker %x = phi i32 [ 1, %entry ], [ 2, %invoke.cont ] 295*9880d681SAndroid Build Coastguard Worker %cs1 = catchswitch within none [label %catch] unwind to caller 296*9880d681SAndroid Build Coastguard Workercatch: 297*9880d681SAndroid Build Coastguard Worker ; CHECK: catch: 298*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 [] 299*9880d681SAndroid Build Coastguard Worker %cp = catchpad within %cs1 [] 300*9880d681SAndroid Build Coastguard Worker %b = call i1 @i() [ "funclet"(token %cp) ] 301*9880d681SAndroid Build Coastguard Worker br i1 %b, label %left, label %right 302*9880d681SAndroid Build Coastguard Workerleft: 303*9880d681SAndroid Build Coastguard Worker ; Edge from %left to %join needs to be split so that 304*9880d681SAndroid Build Coastguard Worker ; the load of %x can be inserted *after* the catchret 305*9880d681SAndroid Build Coastguard Worker ; CHECK: left: 306*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: catchret from %[[CatchPad]] to label %[[SplitLeft:[^ ]+]] 307*9880d681SAndroid Build Coastguard Worker catchret from %cp to label %join 308*9880d681SAndroid Build Coastguard Worker ; CHECK: [[SplitLeft]]: 309*9880d681SAndroid Build Coastguard Worker ; CHECK: [[LoadX:%[^ ]+]] = load i32, i32* [[SlotX]] 310*9880d681SAndroid Build Coastguard Worker ; CHECK: br label %join 311*9880d681SAndroid Build Coastguard Workerright: 312*9880d681SAndroid Build Coastguard Worker ; Edge from %right to %join needs to be split so that 313*9880d681SAndroid Build Coastguard Worker ; the load of %y can be inserted *after* the catchret 314*9880d681SAndroid Build Coastguard Worker ; CHECK: right: 315*9880d681SAndroid Build Coastguard Worker ; CHECK: %y = call i32 @g() 316*9880d681SAndroid Build Coastguard Worker ; CHECK: catchret from %[[CatchPad]] to label %join 317*9880d681SAndroid Build Coastguard Worker %y = call i32 @g() [ "funclet"(token %cp) ] 318*9880d681SAndroid Build Coastguard Worker catchret from %cp to label %join 319*9880d681SAndroid Build Coastguard Workerjoin: 320*9880d681SAndroid Build Coastguard Worker ; CHECK: join: 321*9880d681SAndroid Build Coastguard Worker ; CHECK: %phi = phi i32 [ [[LoadX]], %[[SplitLeft]] ], [ %y, %right ] 322*9880d681SAndroid Build Coastguard Worker %phi = phi i32 [ %x, %left ], [ %y, %right ] 323*9880d681SAndroid Build Coastguard Worker call void @h(i32 %phi) 324*9880d681SAndroid Build Coastguard Worker br label %exit 325*9880d681SAndroid Build Coastguard Workerexit: 326*9880d681SAndroid Build Coastguard Worker ret void 327*9880d681SAndroid Build Coastguard Worker} 328*9880d681SAndroid Build Coastguard Worker 329*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8( 330*9880d681SAndroid Build Coastguard Workerdefine void @test8() personality i32 (...)* @__CxxFrameHandler3 { entry: 331*9880d681SAndroid Build Coastguard Worker invoke void @f() 332*9880d681SAndroid Build Coastguard Worker to label %done unwind label %cleanup1 333*9880d681SAndroid Build Coastguard Worker invoke void @f() 334*9880d681SAndroid Build Coastguard Worker to label %done unwind label %cleanup2 335*9880d681SAndroid Build Coastguard Worker 336*9880d681SAndroid Build Coastguard Workerdone: 337*9880d681SAndroid Build Coastguard Worker ret void 338*9880d681SAndroid Build Coastguard Worker 339*9880d681SAndroid Build Coastguard Workercleanup1: 340*9880d681SAndroid Build Coastguard Worker ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad within none [] 341*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: call void @llvm.bar() 342*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: cleanupret from [[CleanupPad1]] 343*9880d681SAndroid Build Coastguard Worker %cp0 = cleanuppad within none [] 344*9880d681SAndroid Build Coastguard Worker br label %cleanupexit 345*9880d681SAndroid Build Coastguard Worker 346*9880d681SAndroid Build Coastguard Workercleanup2: 347*9880d681SAndroid Build Coastguard Worker ; CHECK: cleanuppad within none [] 348*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: call void @llvm.bar() 349*9880d681SAndroid Build Coastguard Worker ; CHECK-NEXT: unreachable 350*9880d681SAndroid Build Coastguard Worker %cp1 = cleanuppad within none [] 351*9880d681SAndroid Build Coastguard Worker br label %cleanupexit 352*9880d681SAndroid Build Coastguard Worker 353*9880d681SAndroid Build Coastguard Workercleanupexit: 354*9880d681SAndroid Build Coastguard Worker call void @llvm.bar() 355*9880d681SAndroid Build Coastguard Worker cleanupret from %cp0 unwind label %cleanup2 356*9880d681SAndroid Build Coastguard Worker} 357