[RS4GC] Fix rematerialization of bitcast of bitcast.
[oota-llvm.git] / test / Transforms / RewriteStatepointsForGC / liveness-basics.ll
1 ; 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 -spp-rematerialization-threshold=0 -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.
8 define i64 addrspace(1)* @test1(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
9 ; CHECK-LABEL: @test1
10 entry:
11   br i1 %cmp, label %taken, label %untaken
12
13 taken:
14 ; CHECK-LABEL: taken:
15 ; CHECK-NEXT: gc.statepoint
16 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
17 ; CHECK-NEXT: bitcast
18 ; CHECK-NEXT: br label %merge
19   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
20   br label %merge
21
22 untaken:
23 ; CHECK-LABEL: untaken:
24 ; CHECK-NEXT: gc.statepoint
25 ; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
26 ; CHECK-NEXT: bitcast
27 ; CHECK-NEXT: br label %merge
28   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
29   br label %merge
30
31 merge:
32 ; CHECK-LABEL: merge:
33 ; CHECK-NEXT: %.0 = phi i64 addrspace(1)* [ %obj.relocated.casted, %taken ], [ %obj.relocated1.casted, %untaken ]
34 ; 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
39 define i64 addrspace(1)* @test2(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" {
40 ; CHECK-LABEL: @test2
41 entry:
42 ; CHECK-LABEL: entry:
43 ; CHECK-NEXT:  gc.statepoint
44 ; CHECK-NEXT:  br
45   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
46   br i1 %cmp, label %taken, label %untaken
47
48 taken:
49 ; CHECK-LABEL: taken:
50 ; CHECK-NEXT:  %obj = load
51 ; CHECK-NEXT:  gc.statepoint
52 ; CHECK-NEXT:  gc.relocate
53 ; CHECK-NEXT: bitcast
54 ; CHECK-NEXT:  ret i64 addrspace(1)* %obj.relocated.casted
55
56   %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
57   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
58   ret i64 addrspace(1)* %obj
59
60 untaken:
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.
66 define i64 addrspace(1)* @test3(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" {
67 ; CHECK-LABEL: @test3
68 entry:
69   br i1 %cmp, label %taken, label %untaken
70
71 taken:
72 ; CHECK-LABEL: taken:
73 ; CHECK-NEXT: gc.statepoint
74 ; CHECK-NEXT: %obj = load
75 ; CHECK-NEXT: gc.statepoint
76 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
77 ; CHECK-NEXT: bitcast
78 ; CHECK-NEXT: br label %merge
79   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
80   %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
81   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
82   br label %merge
83
84 untaken:
85 ; CHECK-LABEL: taken:
86 ; CHECK-NEXT: gc.statepoint
87 ; CHECK-NEXT: br label %merge
88   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
89   br label %merge
90
91 merge:
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.
98 define i64 addrspace(1)* @test4(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
99 ; CHECK-LABEL: @test4
100 entry:
101 ; CHECK-LABEL: entry:
102 ; CHECK-NEXT:  %derived = getelementptr
103 ; CHECK-NEXT:  gc.statepoint
104 ; CHECK-NEXT:  %derived.relocated =
105 ; CHECK-NEXT:  bitcast 
106 ; CHECK-NEXT:  %obj.relocated =
107 ; CHECK-NEXT:  bitcast
108 ; CHECK-NEXT:  gc.statepoint
109 ; CHECK-NEXT:  %derived.relocated1 =
110 ; CHECK-NEXT:  bitcast 
111 ; Note: It's legal to relocate obj again, but not strictly needed
112 ; CHECK-NEXT:  %obj.relocated2 =
113 ; CHECK-NEXT:  bitcast
114 ; CHECK-NEXT:  ret i64 addrspace(1)* %derived.relocated1.casted
115
116   %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
117   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
118
119   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
120   ret i64 addrspace(1)* %derived
121 }
122
123 declare 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.
128 define i64 addrspace(1)* @test5(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" {
129 ; CHECK-LABEL: @test5
130 entry:
131   br i1 %cmp, label %taken, label %untaken
132
133 taken:
134 ; CHECK-LABEL: taken:
135 ; CHECK-NEXT: gc.statepoint
136 ; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
137 ; CHECK-NEXT: bitcast
138 ; CHECK-NEXT: br label %merge
139   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
140   br label %merge
141
142 untaken:
143 ; CHECK-LABEL: untaken:
144 ; CHECK-NEXT: br label %merge
145   br label %merge
146
147 merge:
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]
154   call void (...) @consume(i64 addrspace(1)* %obj2a)
155   br label %final
156 final:
157 ; CHECK-LABEL: final:
158 ; CHECK-NEXT: @consume
159 ; CHECK-NEXT: ret i64 addrspace(1)* %.0
160   call void (...) @consume(i64 addrspace(1)* %obj2a)
161   ret i64 addrspace(1)* %obj
162 }
163
164 declare void @foo()
165
166 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)