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