1; Need to move users of allocas that were moved into the coroutine frame after 2; coro.begin. 3; RUN: opt < %s -O2 -enable-coroutines -S | FileCheck %s 4 5define nonnull i8* @f(i32 %n) { 6entry: 7 %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null); 8 %n.addr = alloca i32 9 store i32 %n, i32* %n.addr ; this needs to go after coro.begin 10 %0 = tail call i32 @llvm.coro.size.i32() 11 %call = tail call i8* @malloc(i32 %0) 12 %1 = tail call noalias nonnull i8* @llvm.coro.begin(token %id, i8* %call) 13 %2 = bitcast i32* %n.addr to i8* 14 call void @ctor(i8* %2) 15 br label %for.cond 16 17for.cond: 18 %3 = load i32, i32* %n.addr 19 %dec = add nsw i32 %3, -1 20 store i32 %dec, i32* %n.addr 21 call void @print(i32 %3) 22 %4 = call i8 @llvm.coro.suspend(token none, i1 false) 23 %conv = sext i8 %4 to i32 24 switch i32 %conv, label %coro_Suspend [ 25 i32 0, label %for.cond 26 i32 1, label %coro_Cleanup 27 ] 28 29coro_Cleanup: 30 %5 = call i8* @llvm.coro.free(token %id, i8* nonnull %1) 31 call void @free(i8* %5) 32 br label %coro_Suspend 33 34coro_Suspend: 35 call void @llvm.coro.end(i8* null, i1 false) 36 ret i8* %1 37} 38 39; CHECK-LABEL: @main 40define i32 @main() { 41entry: 42 %hdl = call i8* @f(i32 4) 43 call void @llvm.coro.resume(i8* %hdl) 44 call void @llvm.coro.resume(i8* %hdl) 45 call void @llvm.coro.destroy(i8* %hdl) 46 ret i32 0 47; CHECK: call void @ctor 48; CHECK-NEXT: call void @print(i32 4) 49; CHECK-NEXT: call void @print(i32 3) 50; CHECK-NEXT: call void @print(i32 2) 51; CHECK: ret i32 0 52} 53 54declare i8* @malloc(i32) 55declare void @free(i8*) 56declare void @print(i32) 57declare void @ctor(i8* nocapture readonly) 58 59declare token @llvm.coro.id(i32, i8*, i8*, i8*) 60declare i32 @llvm.coro.size.i32() 61declare i8* @llvm.coro.begin(token, i8*) 62declare i8 @llvm.coro.suspend(token, i1) 63declare i8* @llvm.coro.free(token, i8*) 64declare void @llvm.coro.end(i8*, i1) 65 66declare void @llvm.coro.resume(i8*) 67declare void @llvm.coro.destroy(i8*) 68