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