89 lines · plain
1; Tests that coro-split removes cleanup code after coro.end in resume functions2; and retains it in the start function.3; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s4 5define ptr @f(i1 %val) presplitcoroutine personality i32 3 {6entry:7 %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)8 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)9 call void @print(i32 0)10 br i1 %val, label %resume, label %susp11 12susp:13 %0 = call i8 @llvm.coro.suspend(token none, i1 false)14 switch i8 %0, label %suspend [i8 0, label %resume15 i8 1, label %suspend]16resume:17 invoke void @print(i32 1) to label %suspend unwind label %lpad18 19suspend:20 call void @llvm.coro.end(ptr %hdl, i1 0, token none)21 call void @print(i32 0) ; should not be present in f.resume22 ret ptr %hdl23 24lpad:25 %lpval = landingpad { ptr, i32 }26 cleanup27 28 call void @print(i32 2)29 call void @llvm.coro.end(ptr null, i1 true, token none)30 %in.ramp = call i1 @llvm.coro.is_in_ramp()31 br i1 %in.ramp, label %cleanup.cont, label %eh.resume32 33cleanup.cont:34 call void @print(i32 3) ; should not be present in f.resume35 br label %eh.resume36 37eh.resume:38 resume { ptr, i32 } %lpval39}40 41; Verify that start function contains both print calls the one before and after coro.end42; CHECK-LABEL: define ptr @f(43; CHECK: invoke void @print(i32 1)44; CHECK: to label %AfterCoroEnd unwind label %lpad45 46; CHECK: AfterCoroEnd:47; CHECK: call void @print(i32 0)48; CHECK: ret ptr %hdl49 50; CHECK: lpad:51; CHECK-NEXT: %lpval = landingpad { ptr, i32 }52; CHECK-NEXT: cleanup53; CHECK-NEXT: call void @print(i32 2)54; CHECK-NEXT: call void @print(i32 3)55; CHECK-NEXT: resume { ptr, i32 } %lpval56 57; VERIFY Resume Parts58 59; Verify that resume function does not contains both print calls appearing after coro.end60; CHECK-LABEL: define internal fastcc void @f.resume61; CHECK: invoke void @print(i32 1)62; CHECK: to label %CoroEnd unwind label %lpad63 64; CHECK: CoroEnd:65; CHECK-NEXT: ret void66 67; CHECK: lpad:68; CHECK-NEXT: %lpval = landingpad { ptr, i32 }69; CHECK-NEXT: cleanup70; CHECK-NEXT: call void @print(i32 2)71; Checks that the coroutine would be marked as done if it exits in unwinding path.72; CHECK-NEXT: store ptr null, ptr %hdl, align 873; CHECK-NEXT: resume { ptr, i32 } %lpval74 75declare ptr @llvm.coro.free(token, ptr)76declare i32 @llvm.coro.size.i32()77declare i8 @llvm.coro.suspend(token, i1)78declare void @llvm.coro.resume(ptr)79declare void @llvm.coro.destroy(ptr)80 81declare token @llvm.coro.id(i32, ptr, ptr, ptr)82declare ptr @llvm.coro.alloc(token)83declare ptr @llvm.coro.begin(token, ptr)84declare void @llvm.coro.end(ptr, i1, token)85 86declare noalias ptr @malloc(i32)87declare void @print(i32)88declare void @free(ptr)89