239 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s3 4target datalayout = "p:64:64:64"5 6declare {ptr, ptr, i32} @prototype_f(ptr, i1)7define {ptr, ptr, i32} @f(ptr %buffer, i32 %n) {8; CHECK-LABEL: @f(9; CHECK-NEXT: coro.return:10; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[BUFFER:%.*]], i64 811; CHECK-NEXT: store i32 [[N:%.*]], ptr [[N_VAL_SPILL_ADDR]], align 412; CHECK-NEXT: [[TMP0:%.*]] = tail call ptr @allocate(i32 [[N]])13; CHECK-NEXT: store ptr [[TMP0]], ptr [[BUFFER]], align 814; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr, ptr, i32 } { ptr @f.resume.0, ptr poison, i32 poison }, ptr [[TMP0]], 115; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, ptr, i32 } [[TMP1]], i32 [[N]], 216; CHECK-NEXT: ret { ptr, ptr, i32 } [[TMP2]]17;18entry:19 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_f, ptr @allocate, ptr @deallocate)20 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)21 br label %loop22 23loop:24 %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ]25 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %n.val, i32 8)26 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)27 %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %ptr, i32 %n.val)28 call void @llvm.coro.alloca.free(token %alloca)29 br i1 %unwind, label %cleanup, label %resume30 31resume:32 %inc = add i32 %n.val, 133 br label %loop34 35cleanup:36 call void @llvm.coro.end(ptr %hdl, i1 0, token none)37 unreachable38}39 40 41 42declare {ptr, i32} @prototype_g(ptr, i1)43define {ptr, i32} @g(ptr %buffer, i32 %n) {44; CHECK-LABEL: @g(45; CHECK-NEXT: coro.return:46; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 447; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i6448; CHECK-NEXT: [[TMP1:%.*]] = alloca i8, i64 [[TMP0]], align 849; CHECK-NEXT: tail call void @use(ptr nonnull [[TMP1]])50; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr, i32 } { ptr @g.resume.0, i32 poison }, i32 [[N]], 151; CHECK-NEXT: ret { ptr, i32 } [[TMP2]]52;53entry:54 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate)55 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)56 br label %loop57 58loop:59 %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ]60 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %n.val, i32 8)61 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)62 call void @use(ptr %ptr)63 call void @llvm.coro.alloca.free(token %alloca)64 %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %n.val)65 br i1 %unwind, label %cleanup, label %resume66 67resume:68 %inc = add i32 %n.val, 169 br label %loop70 71cleanup:72 call void @llvm.coro.end(ptr %hdl, i1 0, token none)73 unreachable74}75 76 77 78declare {ptr, i32} @prototype_h(ptr, i1)79define {ptr, i32} @h(ptr %buffer, i32 %n) {80; CHECK-LABEL: @h(81; CHECK-NEXT: coro.return:82; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 483; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @h.resume.0, i32 poison }, i32 [[N]], 184; CHECK-NEXT: ret { ptr, i32 } [[TMP0]]85;86entry:87 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_h, ptr @allocate, ptr @deallocate)88 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)89 br label %loop90 91loop:92 %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ]93 %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %n.val)94 br i1 %unwind, label %cleanup, label %resume95 96resume:97 %inc = add i32 %n.val, 198 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %inc, i32 8)99 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)100 call void @use(ptr %ptr)101 call void @llvm.coro.alloca.free(token %alloca)102 br label %loop103 104cleanup:105 call void @llvm.coro.end(ptr %hdl, i1 0, token none)106 unreachable107}108 109 110 111declare {ptr, i32} @prototype_i(ptr)112define {ptr, i32} @i(ptr %buffer, i32 %n) {113; CHECK-LABEL: @i(114; CHECK-NEXT: coro.return:115; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4116; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @i.resume.0, i32 poison }, i32 [[N]], 1117; CHECK-NEXT: ret { ptr, i32 } [[TMP0]]118;119entry:120 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_i, ptr @allocate, ptr @deallocate)121 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)122 br label %loop123 124loop:125 %n.val = phi i32 [ %n, %entry ], [ %k, %loop2 ]126 call void (...) @llvm.coro.suspend.retcon.isVoid(i32 %n.val)127 %inc = add i32 %n.val, 1128 br label %loop2129 130loop2:131 %k = phi i32 [ %inc, %loop ], [ %k2, %loop2 ]132 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %k, i32 8)133 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)134 call void @use(ptr %ptr)135 call void @llvm.coro.alloca.free(token %alloca)136 %k2 = lshr i32 %k, 1137 %cmp = icmp ugt i32 %k, 128138 br i1 %cmp, label %loop2, label %loop139}140 141 142 143declare {ptr, i32} @prototype_j(ptr)144define {ptr, i32} @j(ptr %buffer, i32 %n) {145; CHECK-LABEL: @j(146; CHECK-NEXT: coro.return:147; CHECK-NEXT: store i32 [[N:%.*]], ptr [[BUFFER:%.*]], align 4148; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @j.resume.0, i32 poison }, i32 [[N]], 1149; CHECK-NEXT: ret { ptr, i32 } [[TMP0]]150;151entry:152 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_j, ptr @allocate, ptr @deallocate)153 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)154 br label %forward155 156back:157 ; We should encounter this 'get' before we encounter the 'alloc'.158 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)159 call void @use(ptr %ptr)160 call void @llvm.coro.alloca.free(token %alloca)161 %k = add i32 %n.val, 1162 %cmp = icmp ugt i32 %k, 128163 br i1 %cmp, label %forward, label %end164 165forward:166 %n.val = phi i32 [ %n, %entry ], [ %k, %back ]167 call void (...) @llvm.coro.suspend.retcon.isVoid(i32 %n.val)168 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %n.val, i32 8)169 %inc = add i32 %n.val, 1170 br label %back171 172end:173 call void @llvm.coro.end(ptr %hdl, i1 0, token none)174 unreachable175}176 177declare i32 @getSize()178define {ptr, i32} @k(ptr %buffer, i32 %n, i1 %cond) {179; CHECK-LABEL: @k(180; CHECK-NEXT: PostSpill:181; CHECK-NEXT: [[SIZE:%.*]] = tail call i32 @getSize()182; CHECK-NEXT: br i1 [[COND:%.*]], label [[ALLOCA_BLOCK:%.*]], label [[CORO_RETURN:%.*]]183; CHECK: coro.return:184; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { ptr, i32 } { ptr @k.resume.0, i32 poison }, i32 [[N:%.*]], 1185; CHECK-NEXT: ret { ptr, i32 } [[TMP0]]186; CHECK: alloca_block:187; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[SIZE]] to i64188; CHECK-NEXT: [[TMP2:%.*]] = alloca i8, i64 [[TMP1]], align 8189; CHECK-NEXT: tail call void @use(ptr nonnull [[TMP2]])190; CHECK-NEXT: br label [[CORO_RETURN]]191;192entry:193 %id = call token @llvm.coro.id.retcon(i32 1024, i32 8, ptr %buffer, ptr @prototype_g, ptr @allocate, ptr @deallocate)194 %hdl = call ptr @llvm.coro.begin(token %id, ptr null)195 br i1 %cond, label %alloca_block, label %non_alloca_block196 197suspend:198 %unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %n)199 br i1 %unwind, label %cleanup, label %resume200 201resume:202 br label %cleanup203 204alloca_block:205 %size = call i32 @getSize()206 ; This will get lowered to a dynamic alloca.207 ; Make sure code that runs after that lowering does not hoist the dynamic208 ; alloca into the entry block of the resume function.209 %alloca = call token @llvm.coro.alloca.alloc.i32(i32 %size, i32 8)210 %ptr = call ptr @llvm.coro.alloca.get(token %alloca)211 call void @use(ptr %ptr)212 call void @llvm.coro.alloca.free(token %alloca)213 br label %suspend214 215non_alloca_block:216 %ignore = call i32 @getSize()217 br label %suspend218 219cleanup:220 call void @llvm.coro.end(ptr %hdl, i1 0, token none)221 unreachable222}223 224declare token @llvm.coro.id.retcon(i32, i32, ptr, ptr, ptr, ptr)225declare ptr @llvm.coro.begin(token, ptr)226declare i1 @llvm.coro.suspend.retcon.i1(...)227declare void @llvm.coro.suspend.retcon.isVoid(...)228declare void @llvm.coro.end(ptr, i1, token)229declare ptr @llvm.coro.prepare.retcon(ptr)230declare token @llvm.coro.alloca.alloc.i32(i32, i32)231declare ptr @llvm.coro.alloca.get(token)232declare void @llvm.coro.alloca.free(token)233 234declare noalias ptr @allocate(i32 %size)235declare void @deallocate(ptr %ptr)236 237declare void @print(i32)238declare void @use(ptr)239