blob: a4b427c7f79a2d648b04ced7b91f9a7b5c785d1c [file] [log] [blame]
Philip Reames8106a262015-04-10 22:58:39 +00001; A collection of liveness test cases to ensure we're reporting the
2; correct live values at statepoints
3; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
4
5
6; Tests to make sure we consider %obj live in both the taken and untaken
7; predeccessor of merge.
8define i64 addrspace(1)* @test1(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
9; CHECK-LABEL: @test1
10entry:
11 br i1 %cmp, label %taken, label %untaken
12
13taken:
14; CHECK-LABEL: taken:
15; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +000016; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
17; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +000018; CHECK-NEXT: br label %merge
Pat Gavlincc0431d2015-05-08 18:07:42 +000019 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000020 br label %merge
21
22untaken:
23; CHECK-LABEL: untaken:
24; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +000025; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
26; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +000027; CHECK-NEXT: br label %merge
Pat Gavlincc0431d2015-05-08 18:07:42 +000028 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000029 br label %merge
30
31merge:
32; CHECK-LABEL: merge:
Sanjoy Das89c54912015-05-11 18:49:34 +000033; CHECK-NEXT: %.0 = phi i64 addrspace(1)* [ %obj.relocated.casted, %taken ], [ %obj.relocated1.casted, %untaken ]
Philip Reames8106a262015-04-10 22:58:39 +000034; CHECK-NEXT: ret i64 addrspace(1)* %.0
35 ret i64 addrspace(1)* %obj
36}
37
38; A local kill should not effect liveness in predecessor block
39define i64 addrspace(1)* @test2(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" {
40; CHECK-LABEL: @test2
41entry:
42; CHECK-LABEL: entry:
43; CHECK-NEXT: gc.statepoint
44; CHECK-NEXT: br
Pat Gavlincc0431d2015-05-08 18:07:42 +000045 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000046 br i1 %cmp, label %taken, label %untaken
47
48taken:
49; CHECK-LABEL: taken:
50; CHECK-NEXT: %obj = load
51; CHECK-NEXT: gc.statepoint
52; CHECK-NEXT: gc.relocate
Sanjoy Das89c54912015-05-11 18:49:34 +000053; CHECK-NEXT: bitcast
54; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
Philip Reames8106a262015-04-10 22:58:39 +000055
56 %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
Pat Gavlincc0431d2015-05-08 18:07:42 +000057 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000058 ret i64 addrspace(1)* %obj
59
60untaken:
61 ret i64 addrspace(1)* null
62}
63
64; A local kill should effect values live from a successor phi. Also, we
65; should only propagate liveness from a phi to the appropriate predecessors.
66define i64 addrspace(1)* @test3(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" {
67; CHECK-LABEL: @test3
68entry:
69 br i1 %cmp, label %taken, label %untaken
70
71taken:
72; CHECK-LABEL: taken:
73; CHECK-NEXT: gc.statepoint
74; CHECK-NEXT: %obj = load
75; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +000076; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
77; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +000078; CHECK-NEXT: br label %merge
Pat Gavlincc0431d2015-05-08 18:07:42 +000079 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000080 %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
Pat Gavlincc0431d2015-05-08 18:07:42 +000081 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000082 br label %merge
83
84untaken:
85; CHECK-LABEL: taken:
86; CHECK-NEXT: gc.statepoint
87; CHECK-NEXT: br label %merge
Pat Gavlincc0431d2015-05-08 18:07:42 +000088 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +000089 br label %merge
90
91merge:
92 %phi = phi i64 addrspace(1)* [ %obj, %taken ], [ null, %untaken ]
93 ret i64 addrspace(1)* %phi
94}
95
96; A base pointer must be live if it is needed at a later statepoint,
97; even if the base pointer is otherwise unused.
98define i64 addrspace(1)* @test4(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
99; CHECK-LABEL: @test4
100entry:
101; CHECK-LABEL: entry:
102; CHECK-NEXT: %derived = getelementptr
103; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +0000104; CHECK-NEXT: %derived.relocated =
105; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +0000106; CHECK-NEXT: %obj.relocated =
Sanjoy Das89c54912015-05-11 18:49:34 +0000107; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +0000108; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +0000109; CHECK-NEXT: %derived.relocated1 =
110; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +0000111; Note: It's legal to relocate obj again, but not strictly needed
112; CHECK-NEXT: %obj.relocated2 =
Sanjoy Das89c54912015-05-11 18:49:34 +0000113; CHECK-NEXT: bitcast
114; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1.casted
Philip Reames8106a262015-04-10 22:58:39 +0000115;
116 %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
Pat Gavlincc0431d2015-05-08 18:07:42 +0000117 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +0000118
Pat Gavlincc0431d2015-05-08 18:07:42 +0000119 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +0000120 ret i64 addrspace(1)* %derived
121}
122
123declare void @consume(...) readonly
124
125; Make sure that a phi def visited during iteration is considered a kill.
126; Also, liveness after base pointer analysis can change based on new uses,
127; not just new defs.
128define i64 addrspace(1)* @test5(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
129; CHECK-LABEL: @test5
130entry:
131 br i1 %cmp, label %taken, label %untaken
132
133taken:
134; CHECK-LABEL: taken:
135; CHECK-NEXT: gc.statepoint
Sanjoy Das89c54912015-05-11 18:49:34 +0000136; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
137; CHECK-NEXT: bitcast
Philip Reames8106a262015-04-10 22:58:39 +0000138; CHECK-NEXT: br label %merge
Pat Gavlincc0431d2015-05-08 18:07:42 +0000139 call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
Philip Reames8106a262015-04-10 22:58:39 +0000140 br label %merge
141
142untaken:
143; CHECK-LABEL: untaken:
144; CHECK-NEXT: br label %merge
145 br label %merge
146
147merge:
148; CHECK-LABEL: merge:
149; CHECK-NEXT: %.0 = phi i64 addrspace(1)*
150; CHECK-NEXT: %obj2a = phi
151; CHECK-NEXT: @consume
152; CHECK-NEXT: br label %final
153 %obj2a = phi i64 addrspace(1)* [ %obj, %taken ], [null, %untaken]
David Blaikie23af6482015-04-16 23:24:18 +0000154 call void (...) @consume(i64 addrspace(1)* %obj2a)
Philip Reames8106a262015-04-10 22:58:39 +0000155 br label %final
156final:
157; CHECK-LABEL: final:
158; CHECK-NEXT: @consume
159; CHECK-NEXT: ret i64 addrspace(1)* %.0
David Blaikie23af6482015-04-16 23:24:18 +0000160 call void (...) @consume(i64 addrspace(1)* %obj2a)
Philip Reames8106a262015-04-10 22:58:39 +0000161 ret i64 addrspace(1)* %obj
162}
163
164declare void @foo()
165
166declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
167