1; Second example from Doc/Coroutines.rst (custom alloc and free functions) 2; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s 3; RUN: opt < %s -passes='default<O2>' -enable-coroutines -S | FileCheck %s 4 5define i8* @f(i32 %n) { 6entry: 7 %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) 8 %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id) 9 br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin 10dyn.alloc: 11 %size = call i32 @llvm.coro.size.i32() 12 %alloc = call i8* @CustomAlloc(i32 %size) 13 br label %coro.begin 14coro.begin: 15 %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] 16 %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi) 17 br label %loop 18loop: 19 %n.val = phi i32 [ %n, %coro.begin ], [ %inc, %loop ] 20 %inc = add nsw i32 %n.val, 1 21 call void @print(i32 %n.val) 22 %0 = call i8 @llvm.coro.suspend(token none, i1 false) 23 switch i8 %0, label %suspend [i8 0, label %loop 24 i8 1, label %cleanup] 25cleanup: 26 %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) 27 %need.dyn.free = icmp ne i8* %mem, null 28 br i1 %need.dyn.free, label %dyn.free, label %suspend 29dyn.free: 30 call void @CustomFree(i8* %mem) 31 br label %suspend 32suspend: 33 call i1 @llvm.coro.end(i8* %hdl, i1 false) 34 ret i8* %hdl 35} 36 37; CHECK-LABEL: @main 38define i32 @main() { 39entry: 40 %hdl = call i8* @f(i32 4) 41 call void @llvm.coro.resume(i8* %hdl) 42 call void @llvm.coro.resume(i8* %hdl) 43 %to = icmp eq i8* %hdl, null 44 br i1 %to, label %return, label %destroy 45destroy: 46 call void @llvm.coro.destroy(i8* %hdl) 47 br label %return 48return: 49 ret i32 0 50; CHECK-NOT: call i8* @CustomAlloc 51; CHECK: call void @print(i32 4) 52; CHECK-NEXT: call void @print(i32 5) 53; CHECK-NEXT: call void @print(i32 6) 54; CHECK-NEXT: ret i32 0 55} 56 57declare i8* @CustomAlloc(i32) 58declare void @CustomFree(i8*) 59declare void @print(i32) 60 61declare token @llvm.coro.id(i32, i8*, i8*, i8*) 62declare i1 @llvm.coro.alloc(token) 63declare i32 @llvm.coro.size.i32() 64declare i8* @llvm.coro.begin(token, i8*) 65declare i8 @llvm.coro.suspend(token, i1) 66declare i8* @llvm.coro.free(token, i8*) 67declare i1 @llvm.coro.end(i8*, i1) 68 69declare void @llvm.coro.resume(i8*) 70declare void @llvm.coro.destroy(i8*) 71