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 @f.resume( 8define void @f(i1 %cond) 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 %unreach unwind label %pad.with.phi 26invoke2: 27 invoke void @may_throw2() 28 to label %unreach unwind label %pad.with.phi 29 30; Verify that we cloned landing pad on every edge and inserted a reload of the spilled value 31 32; CHECK: pad.with.phi.from.invoke2: 33; CHECK: %0 = landingpad { ptr, i32 } 34; CHECK: catch ptr null 35; CHECK: br label %pad.with.phi 36 37; CHECK: pad.with.phi.from.invoke1: 38; CHECK: %1 = landingpad { ptr, i32 } 39; CHECK: catch ptr null 40; CHECK: br label %pad.with.phi 41 42; CHECK: pad.with.phi: 43; CHECK: %val = phi i32 [ 0, %pad.with.phi.from.invoke1 ], [ 1, %pad.with.phi.from.invoke2 ] 44; CHECK: %lp = phi { ptr, i32 } [ %0, %pad.with.phi.from.invoke2 ], [ %1, %pad.with.phi.from.invoke1 ] 45; CHECK: %exn = extractvalue { ptr, i32 } %lp, 0 46; CHECK: call ptr @__cxa_begin_catch(ptr %exn) 47; CHECK: call void @use_val(i32 %val) 48; CHECK: call void @__cxa_end_catch() 49; CHECK: call void @free(ptr %hdl) 50; CHECK: ret void 51 52pad.with.phi: 53 %val = phi i32 [ 0, %invoke1 ], [ 1, %invoke2 ] 54 %lp = landingpad { ptr, i32 } 55 catch ptr null 56 %exn = extractvalue { ptr, i32 } %lp, 0 57 call ptr @__cxa_begin_catch(ptr %exn) 58 call void @use_val(i32 %val) 59 call void @__cxa_end_catch() 60 br label %cleanup 61 62cleanup: ; preds = %invoke.cont15, %if.else, %if.then, %ehcleanup21, %init.suspend 63 %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) 64 call void @free(ptr %mem) 65 br label %coro.ret 66 67coro.ret: 68 call i1 @llvm.coro.end(ptr null, i1 false, token none) 69 ret void 70 71unreach: 72 unreachable 73} 74 75; Function Attrs: argmemonly nounwind readonly 76declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) 77declare noalias ptr @malloc(i64) 78declare i64 @llvm.coro.size.i64() 79declare ptr @llvm.coro.begin(token, ptr writeonly) 80 81; Function Attrs: nounwind 82declare token @llvm.coro.save(ptr) 83declare i8 @llvm.coro.suspend(token, i1) 84 85; Function Attrs: argmemonly nounwind 86declare void @may_throw1() 87declare void @may_throw2() 88 89declare ptr @__cxa_begin_catch(ptr) 90 91declare void @use_val(i32) 92declare void @__cxa_end_catch() 93 94; Function Attrs: nounwind 95declare i1 @llvm.coro.end(ptr, i1, token) 96declare void @free(ptr) 97declare ptr @llvm.coro.free(token, ptr nocapture readonly) 98