xref: /llvm-project/llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll (revision f01a3a893c147c1594b9a3fbd817456b209dabbf)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
3
4
5declare void @use_obj16(ptr addrspace(1)) "gc-leaf-function"
6declare void @use_obj32(ptr addrspace(1)) "gc-leaf-function"
7declare void @use_obj64(ptr addrspace(1)) "gc-leaf-function"
8
9declare void @do_safepoint()
10
11define void @test_gep_const(ptr addrspace(1) %base) gc "statepoint-example" {
12; CHECK-LABEL: @test_gep_const(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
15; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
16; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
17; CHECK-NEXT:    [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15
18; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
19; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])
20; CHECK-NEXT:    ret void
21;
22entry:
23  %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15
24  call void @do_safepoint() [ "deopt"() ]
25  call void @use_obj32(ptr addrspace(1) %base)
26  call void @use_obj32(ptr addrspace(1) %ptr)
27  ret void
28}
29
30define void @test_gep_idx(ptr addrspace(1) %base, i32 %idx) gc "statepoint-example" {
31; CHECK-LABEL: @test_gep_idx(
32; CHECK-NEXT:  entry:
33; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 [[IDX:%.*]]
34; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
35; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
36; CHECK-NEXT:    [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 [[IDX]]
37; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
38; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])
39; CHECK-NEXT:    ret void
40;
41entry:
42  %ptr = getelementptr i32, ptr addrspace(1) %base, i32 %idx
43  call void @do_safepoint() [ "deopt"() ]
44  call void @use_obj32(ptr addrspace(1) %base)
45  call void @use_obj32(ptr addrspace(1) %ptr)
46  ret void
47}
48
49define void @test_bitcast(ptr addrspace(1) %base) gc "statepoint-example" {
50; CHECK-LABEL: @test_bitcast(
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE:%.*]]) ]
53; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
54; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
55; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[BASE_RELOCATED]])
56; CHECK-NEXT:    ret void
57;
58entry:
59  call void @do_safepoint() [ "deopt"() ]
60  call void @use_obj32(ptr addrspace(1) %base)
61  call void @use_obj64(ptr addrspace(1) %base)
62  ret void
63}
64
65define void @test_bitcast_bitcast(ptr addrspace(1) %base) gc "statepoint-example" {
66; CHECK-LABEL: @test_bitcast_bitcast(
67; CHECK-NEXT:  entry:
68; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE:%.*]]) ]
69; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
70; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
71; CHECK-NEXT:    call void @use_obj16(ptr addrspace(1) [[BASE_RELOCATED]])
72; CHECK-NEXT:    ret void
73;
74entry:
75  call void @do_safepoint() [ "deopt"() ]
76
77  call void @use_obj32(ptr addrspace(1) %base)
78  call void @use_obj16(ptr addrspace(1) %base)
79  ret void
80}
81
82define void @test_addrspacecast_addrspacecast(ptr addrspace(1) %base) gc "statepoint-example" {
83; CHECK-LABEL: @test_addrspacecast_addrspacecast(
84; CHECK-NEXT:  entry:
85; CHECK-NEXT:    [[PTR1:%.*]] = addrspacecast ptr addrspace(1) [[BASE:%.*]] to ptr
86; CHECK-NEXT:    [[PTR2:%.*]] = addrspacecast ptr [[PTR1]] to ptr addrspace(1)
87; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[PTR2]], ptr addrspace(1) [[BASE]]) ]
88; CHECK-NEXT:    [[PTR2_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
89; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
90; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
91; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR2_RELOCATED]])
92; CHECK-NEXT:    ret void
93;
94entry:
95  %ptr1 = addrspacecast ptr addrspace(1) %base to ptr
96  %ptr2 = addrspacecast ptr %ptr1 to ptr addrspace(1)
97  call void @do_safepoint() [ "deopt"() ]
98
99  call void @use_obj32(ptr addrspace(1) %base)
100  call void @use_obj32(ptr addrspace(1) %ptr2)
101  ret void
102}
103
104define void @test_bitcast_gep(ptr addrspace(1) %base) gc "statepoint-example" {
105; CHECK-LABEL: @test_bitcast_gep(
106; CHECK-NEXT:  entry:
107; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
108; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
109; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
110; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15
111; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[BASE_RELOCATED]])
112; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])
113; CHECK-NEXT:    ret void
114;
115entry:
116  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
117  call void @do_safepoint() [ "deopt"() ]
118
119  call void @use_obj32(ptr addrspace(1) %base)
120  call void @use_obj64(ptr addrspace(1) %ptr.gep)
121  ret void
122}
123
124define void @test_intersecting_chains(ptr addrspace(1) %base, i32 %idx) gc "statepoint-example" {
125; CHECK-LABEL: @test_intersecting_chains(
126; CHECK-NEXT:  entry:
127; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
128; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
129; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
130; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15
131; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])
132; CHECK-NEXT:    call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])
133; CHECK-NEXT:    ret void
134;
135entry:
136  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
137  call void @do_safepoint() [ "deopt"() ]
138
139  call void @use_obj64(ptr addrspace(1) %ptr.gep)
140  call void @use_obj16(ptr addrspace(1) %ptr.gep)
141  ret void
142}
143
144define void @test_cost_threshold(ptr addrspace(1) %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {
145; CHECK-LABEL: @test_cost_threshold(
146; CHECK-NEXT:  entry:
147; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
148; CHECK-NEXT:    [[PTR_GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP]], i32 [[IDX1:%.*]]
149; CHECK-NEXT:    [[PTR_GEP3:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP2]], i32 [[IDX2:%.*]]
150; CHECK-NEXT:    [[PTR_GEP4:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP3]], i32 [[IDX3:%.*]]
151; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[PTR_GEP4]], ptr addrspace(1) [[BASE]]) ]
152; CHECK-NEXT:    [[PTR_GEP4_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
153; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
154; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP4_RELOCATED]])
155; CHECK-NEXT:    ret void
156;
157entry:
158  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
159  %ptr.gep2 = getelementptr i32, ptr addrspace(1) %ptr.gep, i32 %idx1
160  %ptr.gep3 = getelementptr i32, ptr addrspace(1) %ptr.gep2, i32 %idx2
161  %ptr.gep4 = getelementptr i32, ptr addrspace(1) %ptr.gep3, i32 %idx3
162  call void @do_safepoint() [ "deopt"() ]
163
164  call void @use_obj64(ptr addrspace(1) %ptr.gep4)
165  ret void
166}
167
168define void @test_two_derived(ptr addrspace(1) %base) gc "statepoint-example" {
169; CHECK-LABEL: @test_two_derived(
170; CHECK-NEXT:  entry:
171; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
172; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE]], i32 12
173; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
174; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
175; CHECK-NEXT:    [[PTR_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15
176; CHECK-NEXT:    [[PTR2_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 12
177; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])
178; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR2_REMAT]])
179; CHECK-NEXT:    ret void
180;
181entry:
182  %ptr = getelementptr i32, ptr addrspace(1) %base, i32 15
183  %ptr2 = getelementptr i32, ptr addrspace(1) %base, i32 12
184  call void @do_safepoint() [ "deopt"() ]
185
186  call void @use_obj32(ptr addrspace(1) %ptr)
187  call void @use_obj32(ptr addrspace(1) %ptr2)
188  ret void
189}
190
191define void @test_gep_smallint_array(ptr addrspace(1) %base) gc "statepoint-example" {
192; CHECK-LABEL: @test_gep_smallint_array(
193; CHECK-NEXT:  entry:
194; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [3 x i32], ptr addrspace(1) [[BASE:%.*]], i32 0, i32 2
195; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
196; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
197; CHECK-NEXT:    [[PTR_REMAT:%.*]] = getelementptr [3 x i32], ptr addrspace(1) [[BASE_RELOCATED]], i32 0, i32 2
198; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_REMAT]])
199; CHECK-NEXT:    ret void
200;
201entry:
202  %ptr = getelementptr [3 x i32], ptr addrspace(1) %base, i32 0, i32 2
203  call void @do_safepoint() [ "deopt"() ]
204
205  call void @use_obj32(ptr addrspace(1) %ptr)
206  ret void
207}
208
209declare i32 @fake_personality_function()
210
211define void @test_invoke(ptr addrspace(1) %base) gc "statepoint-example" personality ptr @fake_personality_function {
212; CHECK-LABEL: @test_invoke(
213; CHECK-NEXT:  entry:
214; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
215; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASE]]) ]
216; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
217; CHECK:       normal:
218; CHECK-NEXT:    [[BASE_RELOCATED2:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
219; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED2]], i32 15
220; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])
221; CHECK-NEXT:    call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])
222; CHECK-NEXT:    ret void
223; CHECK:       exception:
224; CHECK-NEXT:    [[LANDING_PAD4:%.*]] = landingpad token
225; CHECK-NEXT:    cleanup
226; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[LANDING_PAD4]], i32 0, i32 0)
227; CHECK-NEXT:    [[PTR_GEP_REMAT1:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE_RELOCATED]], i32 15
228; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT1]])
229; CHECK-NEXT:    call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT1]])
230; CHECK-NEXT:    ret void
231;
232entry:
233  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
234  invoke void @do_safepoint() [ "deopt"() ]
235  to label %normal unwind label %exception
236
237normal:
238  call void @use_obj64(ptr addrspace(1) %ptr.gep)
239  call void @use_obj16(ptr addrspace(1) %ptr.gep)
240  ret void
241
242exception:
243  %landing_pad4 = landingpad token
244  cleanup
245  call void @use_obj64(ptr addrspace(1) %ptr.gep)
246  call void @use_obj16(ptr addrspace(1) %ptr.gep)
247  ret void
248}
249
250define void @test_loop(ptr addrspace(1) %base) gc "statepoint-example" {
251; CHECK-LABEL: @test_loop(
252; CHECK-NEXT:  entry:
253; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
254; CHECK-NEXT:    br label [[LOOP:%.*]]
255; CHECK:       loop:
256; CHECK-NEXT:    [[DOT0:%.*]] = phi ptr addrspace(1) [ [[BASE]], [[ENTRY:%.*]] ], [ [[BASE_RELOCATED:%.*]], [[LOOP]] ]
257; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[DOT0]], i32 15
258; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_GEP_REMAT]])
259; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[DOT0]]) ]
260; CHECK-NEXT:    [[BASE_RELOCATED]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
261; CHECK-NEXT:    br label [[LOOP]]
262;
263entry:
264  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
265  br label %loop
266
267loop:                                             ; preds = %loop, %entry
268  call void @use_obj32(ptr addrspace(1) %ptr.gep)
269  call void @do_safepoint() [ "deopt"() ]
270  br label %loop
271}
272
273define void @test_too_long(ptr addrspace(1) %base) gc "statepoint-example" {
274; CHECK-LABEL: @test_too_long(
275; CHECK-NEXT:  entry:
276; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASE:%.*]], i32 15
277; CHECK-NEXT:    [[PTR_GEP1:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP]], i32 15
278; CHECK-NEXT:    [[PTR_GEP2:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP1]], i32 15
279; CHECK-NEXT:    [[PTR_GEP3:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP2]], i32 15
280; CHECK-NEXT:    [[PTR_GEP4:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP3]], i32 15
281; CHECK-NEXT:    [[PTR_GEP5:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP4]], i32 15
282; CHECK-NEXT:    [[PTR_GEP6:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP5]], i32 15
283; CHECK-NEXT:    [[PTR_GEP7:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP6]], i32 15
284; CHECK-NEXT:    [[PTR_GEP8:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP7]], i32 15
285; CHECK-NEXT:    [[PTR_GEP9:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP8]], i32 15
286; CHECK-NEXT:    [[PTR_GEP10:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP9]], i32 15
287; CHECK-NEXT:    [[PTR_GEP11:%.*]] = getelementptr i32, ptr addrspace(1) [[PTR_GEP10]], i32 15
288; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[PTR_GEP11]], ptr addrspace(1) [[BASE]]) ]
289; CHECK-NEXT:    [[PTR_GEP11_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
290; CHECK-NEXT:    [[BASE_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
291; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_GEP11_RELOCATED]])
292; CHECK-NEXT:    ret void
293;
294entry:
295  %ptr.gep = getelementptr i32, ptr addrspace(1) %base, i32 15
296  %ptr.gep1 = getelementptr i32, ptr addrspace(1) %ptr.gep, i32 15
297  %ptr.gep2 = getelementptr i32, ptr addrspace(1) %ptr.gep1, i32 15
298  %ptr.gep3 = getelementptr i32, ptr addrspace(1) %ptr.gep2, i32 15
299  %ptr.gep4 = getelementptr i32, ptr addrspace(1) %ptr.gep3, i32 15
300  %ptr.gep5 = getelementptr i32, ptr addrspace(1) %ptr.gep4, i32 15
301  %ptr.gep6 = getelementptr i32, ptr addrspace(1) %ptr.gep5, i32 15
302  %ptr.gep7 = getelementptr i32, ptr addrspace(1) %ptr.gep6, i32 15
303  %ptr.gep8 = getelementptr i32, ptr addrspace(1) %ptr.gep7, i32 15
304  %ptr.gep9 = getelementptr i32, ptr addrspace(1) %ptr.gep8, i32 15
305  %ptr.gep10 = getelementptr i32, ptr addrspace(1) %ptr.gep9, i32 15
306  %ptr.gep11 = getelementptr i32, ptr addrspace(1) %ptr.gep10, i32 15
307  call void @do_safepoint() [ "deopt"() ]
308  call void @use_obj32(ptr addrspace(1) %ptr.gep11)
309  ret void
310}
311
312
313declare ptr addrspace(1) @new_instance() nounwind "gc-leaf-function"
314
315; remat the gep in presence of base pointer which is a phi node.
316; FIXME: We should remove the extra basephi.base as well.
317define void @contains_basephi(i1 %cond) gc "statepoint-example" {
318; CHECK-LABEL: @contains_basephi(
319; CHECK-NEXT:  entry:
320; CHECK-NEXT:    [[BASE1:%.*]] = call ptr addrspace(1) @new_instance()
321; CHECK-NEXT:    [[BASE2:%.*]] = call ptr addrspace(1) @new_instance()
322; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
323; CHECK:       here:
324; CHECK-NEXT:    br label [[MERGE:%.*]]
325; CHECK:       there:
326; CHECK-NEXT:    br label [[MERGE]]
327; CHECK:       merge:
328; CHECK-NEXT:    [[BASEPHI:%.*]] = phi ptr addrspace(1) [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]
329; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI]], i32 15
330; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASEPHI]]) ]
331; CHECK-NEXT:    [[BASEPHI_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
332; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI_RELOCATED]], i32 15
333; CHECK-NEXT:    call void @use_obj32(ptr addrspace(1) [[PTR_GEP_REMAT]])
334; CHECK-NEXT:    ret void
335;
336entry:
337  %base1 = call ptr addrspace(1) @new_instance()
338  %base2 = call ptr addrspace(1) @new_instance()
339  br i1 %cond, label %here, label %there
340
341here:
342  br label %merge
343
344there:
345  br label %merge
346
347merge:
348
349
350
351  %basephi = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ]
352  %ptr.gep = getelementptr i32, ptr addrspace(1) %basephi, i32 15
353  call void @do_safepoint() ["deopt"() ]
354  call void @use_obj32(ptr addrspace(1) %ptr.gep)
355  ret void
356}
357
358
359define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" {
360; CHECK-LABEL: @test_intersecting_chains_with_phi(
361; CHECK-NEXT:  entry:
362; CHECK-NEXT:    [[BASE1:%.*]] = call ptr addrspace(1) @new_instance()
363; CHECK-NEXT:    [[BASE2:%.*]] = call ptr addrspace(1) @new_instance()
364; CHECK-NEXT:    br i1 [[COND:%.*]], label [[HERE:%.*]], label [[THERE:%.*]]
365; CHECK:       here:
366; CHECK-NEXT:    br label [[MERGE:%.*]]
367; CHECK:       there:
368; CHECK-NEXT:    br label [[MERGE]]
369; CHECK:       merge:
370; CHECK-NEXT:    [[BASEPHI:%.*]] = phi ptr addrspace(1) [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]
371; CHECK-NEXT:    [[PTR_GEP:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI]], i32 15
372; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(ptr addrspace(1) [[BASEPHI]]) ]
373; CHECK-NEXT:    [[BASEPHI_RELOCATED:%.*]] = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
374; CHECK-NEXT:    [[PTR_GEP_REMAT:%.*]] = getelementptr i32, ptr addrspace(1) [[BASEPHI_RELOCATED]], i32 15
375; CHECK-NEXT:    call void @use_obj64(ptr addrspace(1) [[PTR_GEP_REMAT]])
376; CHECK-NEXT:    call void @use_obj16(ptr addrspace(1) [[PTR_GEP_REMAT]])
377; CHECK-NEXT:    ret void
378;
379entry:
380  %base1 = call ptr addrspace(1) @new_instance()
381  %base2 = call ptr addrspace(1) @new_instance()
382  br i1 %cond, label %here, label %there
383
384here:
385  br label %merge
386
387there:
388  br label %merge
389
390merge:
391  %basephi = phi ptr addrspace(1) [ %base1, %here ], [ %base2, %there ]
392  %ptr.gep = getelementptr i32, ptr addrspace(1) %basephi, i32 15
393  call void @do_safepoint() [ "deopt"() ]
394  call void @use_obj64(ptr addrspace(1) %ptr.gep)
395  call void @use_obj16(ptr addrspace(1) %ptr.gep)
396  ret void
397}
398