1; Check that we can handle edge splits leading into a landingpad 2; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; CHECK-LABEL: define internal fastcc void @h.resume( 8define void @h(i1 %cond, i32 %x, i32 %y) presplitcoroutine personality i32 0 { 9entry: 10 %id = call token @llvm.coro.id(i32 16, ptr null, ptr null, ptr null) 11 %size = tail call i64 @llvm.coro.size.i64() 12 %alloc = call ptr @malloc(i64 %size) 13 %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc) 14 %sp = call i8 @llvm.coro.suspend(token none, i1 false) 15 switch i8 %sp, label %coro.ret [ 16 i8 0, label %resume 17 i8 1, label %cleanup 18 ] 19 20resume: 21 br i1 %cond, label %invoke1, label %invoke2 22 23invoke1: 24 invoke void @may_throw1() 25 to label %coro.ret unwind label %pad.with.phi 26invoke2: 27 invoke void @may_throw2() 28 to label %coro.ret unwind label %pad.with.phi 29 30; Verify that we created cleanuppads on every edge and inserted a reload of the spilled value 31 32; CHECK: pad.with.phi.from.invoke2: 33; CHECK: %0 = cleanuppad within none [] 34; CHECK: %y.reload.addr = getelementptr inbounds %h.Frame, ptr %hdl, i32 0, i32 3 35; CHECK: %y.reload = load i32, ptr %y.reload.addr 36; CHECK: cleanupret from %0 unwind label %pad.with.phi 37 38; CHECK: pad.with.phi.from.invoke1: 39; CHECK: %1 = cleanuppad within none [] 40; CHECK: %x.reload.addr = getelementptr inbounds %h.Frame, ptr %hdl, i32 0, i32 2 41; CHECK: %x.reload = load i32, ptr %x.reload.addr 42; CHECK: cleanupret from %1 unwind label %pad.with.phi 43 44; CHECK: pad.with.phi: 45; CHECK: %val = phi i32 [ %x.reload, %pad.with.phi.from.invoke1 ], [ %y.reload, %pad.with.phi.from.invoke2 ] 46; CHECK: %switch = catchswitch within none [label %catch] unwind to caller 47pad.with.phi: 48 %val = phi i32 [ %x, %invoke1 ], [ %y, %invoke2 ] 49 %switch = catchswitch within none [label %catch] unwind to caller 50 51catch: ; preds = %catch.dispatch 52 %pad = catchpad within %switch [ptr null, i32 64, ptr null] 53 call void @use_val(i32 %val) 54 catchret from %pad to label %coro.ret 55 56cleanup: ; preds = %invoke.cont15, %if.else, %if.then, %ehcleanup21, %init.suspend 57 %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) 58 call void @free(ptr %mem) 59 br label %coro.ret 60 61coro.ret: 62 call i1 @llvm.coro.end(ptr null, i1 false, token none) 63 ret void 64} 65 66; Function Attrs: argmemonly nounwind readonly 67declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) 68declare noalias ptr @malloc(i64) 69declare i64 @llvm.coro.size.i64() 70declare ptr @llvm.coro.begin(token, ptr writeonly) 71 72; Function Attrs: nounwind 73declare token @llvm.coro.save(ptr) 74declare i8 @llvm.coro.suspend(token, i1) 75 76; Function Attrs: argmemonly nounwind 77declare void @may_throw1() 78declare void @may_throw2() 79 80declare ptr @__cxa_begin_catch(ptr) 81 82declare void @use_val(i32) 83declare void @__cxa_end_catch() 84 85; Function Attrs: nounwind 86declare i1 @llvm.coro.end(ptr, i1, token) 87declare void @free(ptr) 88declare ptr @llvm.coro.free(token, ptr nocapture readonly) 89