1- ; Testing elide performed its job for calls to coroutines marked safe.
1+ ; Coroutine calls marked with `coro_elide_safe` should be elided.
2+ ; Inside `caller`, we expect the `callee` coroutine to be elided.
3+ ; Inside `caller_conditional`, `callee` is only called on an unlikely
4+ ; path, hence we expect the `callee` coroutine NOT to be elided.
5+ ;
26; RUN: opt < %s -S -passes='cgscc(coro-annotation-elide)' | FileCheck %s
37
48%struct.Task = type { ptr }
@@ -57,7 +61,7 @@ define ptr @callee.noalloc(i8 %arg, ptr dereferenceable(32) align(8) %frame) {
5761; Function Attrs: presplitcoroutine
5862define ptr @caller () #0 {
5963entry:
60- %task = call ptr @callee (i8 0 ) # 1
64+ %task = call ptr @callee (i8 0 ) coro_elide_safe
6165 ret ptr %task
6266 ; CHECK: %[[TASK:.+]] = alloca %struct.Task, align 8
6367 ; CHECK-NEXT: %[[FRAME:.+]] = alloca [32 x i8], align 8
@@ -69,11 +73,29 @@ entry:
6973 ; CHECK-NEXT: ret ptr %[[TASK]]
7074}
7175
76+ ; CHECK-LABEL: define ptr @caller_conditional(i1 %cond)
77+ ; Function Attrs: presplitcoroutine
78+ define ptr @caller_conditional (i1 %cond ) #0 {
79+ entry:
80+ br i1 %cond , label %call , label %ret
81+
82+ call:
83+ ; CHECK-NOT: alloca
84+ ; CHECK-NOT: @llvm.coro.id({{.*}}, ptr @callee, {{.*}})
85+ ; CHECK: %task = call ptr @callee(i8 0)
86+ ; CHECK-NEXT: br label %ret
87+ %task = call ptr @callee (i8 0 ) coro_elide_safe
88+ br label %ret
89+
90+ ret:
91+ %retval = phi ptr [ %task , %call ], [ null , %entry ]
92+ ret ptr %retval
93+ }
94+
7295declare token @llvm.coro.id (i32 , ptr , ptr , ptr )
7396declare ptr @llvm.coro.begin (token, ptr )
7497declare ptr @llvm.coro.frame ()
7598declare ptr @llvm.coro.subfn.addr (ptr , i8 )
7699declare i1 @llvm.coro.alloc (token)
77100
78101attributes #0 = { presplitcoroutine }
79- attributes #1 = { coro_elide_safe }
0 commit comments