[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Coroutines / coro-retcon-frame.ll
blobfed3586c93cb49ae08417766b1feb64bd1434d53
1 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
3 target datalayout = "p:64:64:64"
5 declare void @prototype_f(i8*, i1)
7 declare noalias i8* @allocate(i32 %size)
8 declare void @deallocate(i8* %ptr)
9 declare void @init(i64 *%ptr)
10 declare void @use(i8* %ptr)
11 declare void @use_addr_val(i64 %val, {i64, i64}*%addr)
13 define { i8*, {i64, i64}* } @f(i8* %buffer) "coroutine.presplit"="1" {
14 entry:
15   %tmp = alloca { i64, i64 }, align 8
16   %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0
17   %proj.2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 1
18   store i64 0, i64* %proj.1, align 8
19   store i64 0, i64* %proj.2, align 8
20   %cast = bitcast { i64, i64 }* %tmp to i8*
21   %escape_addr = ptrtoint {i64, i64}* %tmp to i64
22   %id = call token @llvm.coro.id.retcon.once(i32 32, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype_f to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
23   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
24   %proj.2.2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 1
25   call void @init(i64 * %proj.1)
26   call void @init(i64 * %proj.2.2)
27   call void @use_addr_val(i64 %escape_addr, {i64, i64}* %tmp)
28   %abort = call i1 (...) @llvm.coro.suspend.retcon.i1({i64, i64}* %tmp)
29   br i1 %abort, label %end, label %resume
31 resume:
32   call void @use(i8* %cast)
33   br label %end
35 end:
36   call i1 @llvm.coro.end(i8* %hdl, i1 0)
37   unreachable
39 ; Make sure we don't lose writes to the frame.
40 ; CHECK-LABEL: define { i8*, { i64, i64 }* } @f(i8* %buffer) {
41 ; CHECK:  [[FRAMEPTR:%.*]] = bitcast i8* %buffer to %f.Frame*
42 ; CHECK:  [[TMP:%.*]] = getelementptr inbounds %f.Frame, %f.Frame* [[FRAMEPTR]], i32 0, i32 0
43 ; CHECK:  [[PROJ1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP]], i64 0, i32 0
44 ; CHECK:  [[PROJ2:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP]], i64 0, i32 1
45 ; CHECK:  store i64 0, i64* [[PROJ1]]
46 ; CHECK:  store i64 0, i64* [[PROJ2]]
47 ; CHECK:  [[ESCAPED_ADDR:%.*]] = ptrtoint { i64, i64 }* [[TMP]] to i64
48 ; CHECK:  call void @init(i64* [[PROJ1]])
49 ; CHECK:  call void @init(i64* [[PROJ2]])
50 ; CHECK:  call void @use_addr_val(i64 [[ESCAPED_ADDR]], { i64, i64 }* [[TMP]])
52 ; CHECK-LABEL: define internal void @f.resume.0(i8* {{.*}} %0, i1 %1) {
53 ; CHECK:  [[FRAMEPTR:%.*]] = bitcast i8* %0 to %f.Frame*
54 ; CHECK:  [[TMP:%.*]] = getelementptr inbounds %f.Frame, %f.Frame* [[FRAMEPTR]], i32 0, i32 0
55 ; CHECK: resume:
56 ; CHECK:  [[CAST:%.*]] = bitcast { i64, i64 }* [[TMP]] to i8*
57 ; CHECK:  call void @use(i8* [[CAST]])
59 declare token @llvm.coro.id.retcon.once(i32, i32, i8*, i8*, i8*, i8*)
60 declare i8* @llvm.coro.begin(token, i8*)
61 declare i1 @llvm.coro.suspend.retcon.i1(...)
62 declare i1 @llvm.coro.end(i8*, i1)