Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / SROA / phi-gep.ll
bloba8c3331d6281c5dd1a21938d88f89370ce1ed03b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes='sroa<preserve-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
3 ; RUN: opt -S -passes='sroa<modify-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
5 %pair = type { i32, i32 }
7 define i32 @test_sroa_phi_gep(i1 %cond) {
8 ; CHECK-LABEL: @test_sroa_phi_gep(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
11 ; CHECK:       if.then:
12 ; CHECK-NEXT:    br label [[END]]
13 ; CHECK:       end:
14 ; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]
15 ; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]
17 entry:
18   %a = alloca %pair, align 4
19   %b = alloca %pair, align 4
20   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
21   %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1
22   store i32 1, ptr %gep_a, align 4
23   store i32 2, ptr %gep_b, align 4
24   br i1 %cond, label %if.then, label %end
26 if.then:
27   br label %end
29 end:
30   %phi = phi ptr [ %a, %entry], [ %b, %if.then ]
31   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
32   %load = load i32, ptr %gep, align 4
33   ret i32 %load
36 define i32 @test_sroa_phi_gep_non_inbound(i1 %cond) {
37 ; CHECK-LABEL: @test_sroa_phi_gep_non_inbound(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
40 ; CHECK:       if.then:
41 ; CHECK-NEXT:    br label [[END]]
42 ; CHECK:       end:
43 ; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]
44 ; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]
46 entry:
47   %a = alloca %pair, align 4
48   %b = alloca %pair, align 4
49   %gep_a = getelementptr %pair, ptr %a, i32 0, i32 1
50   %gep_b = getelementptr %pair, ptr %b, i32 0, i32 1
51   store i32 1, ptr %gep_a, align 4
52   store i32 2, ptr %gep_b, align 4
53   br i1 %cond, label %if.then, label %end
55 if.then:
56   br label %end
58 end:
59   %phi = phi ptr [ %a, %entry], [ %b, %if.then ]
60   %gep = getelementptr %pair, ptr %phi, i32 0, i32 1
61   %load = load i32, ptr %gep, align 4
62   ret i32 %load
65 define i32 @test_sroa_phi_gep_poison(i1 %cond) {
66 ; CHECK-LABEL: @test_sroa_phi_gep_poison(
67 ; CHECK-NEXT:  entry:
68 ; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4
69 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
70 ; CHECK:       if.then:
71 ; CHECK-NEXT:    br label [[END]]
72 ; CHECK:       end:
73 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ poison, [[IF_THEN]] ]
74 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1
75 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
76 ; CHECK-NEXT:    ret i32 [[LOAD]]
78 entry:
79   %a = alloca %pair, align 4
80   br i1 %cond, label %if.then, label %end
82 if.then:
83   br label %end
85 end:
86   %phi = phi ptr [ %a, %entry], [ poison, %if.then ]
87   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
88   %load = load i32, ptr %gep, align 4
89   ret i32 %load
92 @g = global %pair zeroinitializer, align 4
94 define i32 @test_sroa_phi_gep_global(i1 %cond) {
95 ; CHECK-LABEL: @test_sroa_phi_gep_global(
96 ; CHECK-NEXT:  entry:
97 ; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4
98 ; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1
99 ; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4
100 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
101 ; CHECK:       if.then:
102 ; CHECK-NEXT:    br label [[END]]
103 ; CHECK:       end:
104 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ @g, [[IF_THEN]] ]
105 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1
106 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
107 ; CHECK-NEXT:    ret i32 [[LOAD]]
109 entry:
110   %a = alloca %pair, align 4
111   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
112   store i32 1, ptr %gep_a, align 4
113   br i1 %cond, label %if.then, label %end
115 if.then:
116   br label %end
118 end:
119   %phi = phi ptr [ %a, %entry], [ @g, %if.then ]
120   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
121   %load = load i32, ptr %gep, align 4
122   ret i32 %load
125 define i32 @test_sroa_phi_gep_arg_phi_inspt(i1 %cond) {
126 ; CHECK-LABEL: @test_sroa_phi_gep_arg_phi_inspt(
127 ; CHECK-NEXT:  entry:
128 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
129 ; CHECK:       for:
130 ; CHECK-NEXT:    [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]
131 ; CHECK-NEXT:    [[I]] = add i32 [[PHI_INSPT]], 1
132 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10
133 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]
134 ; CHECK:       end:
135 ; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ 2, [[FOR]] ]
136 ; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]
138 entry:
139   %a = alloca %pair, align 4
140   %b = alloca %pair, align 4
141   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
142   %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1
143   store i32 1, ptr %gep_a, align 4
144   store i32 2, ptr %gep_b, align 4
145   br i1 %cond, label %for, label %end
147 for:
148   %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ]
149   %i = add i32 %phi_inspt, 1
150   %loop.cond = icmp ult i32 %i, 10
151   br i1 %loop.cond, label %for, label %end
153 end:
154   %phi = phi ptr [ %a, %entry], [ %b, %for ]
155   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
156   %load = load i32, ptr %gep, align 4
157   ret i32 %load
160 define i32 @test_sroa_phi_gep_phi_inspt(i1 %cond) {
161 ; CHECK-LABEL: @test_sroa_phi_gep_phi_inspt(
162 ; CHECK-NEXT:  entry:
163 ; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4
164 ; CHECK-NEXT:    [[B:%.*]] = alloca [[PAIR]], align 4
165 ; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1
166 ; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], ptr [[B]], i32 0, i32 1
167 ; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4
168 ; CHECK-NEXT:    store i32 2, ptr [[GEP_B]], align 4
169 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
170 ; CHECK:       for:
171 ; CHECK-NEXT:    [[PHI_IN:%.*]] = phi ptr [ null, [[ENTRY:%.*]] ], [ [[B]], [[FOR]] ]
172 ; CHECK-NEXT:    [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I:%.*]], [[FOR]] ]
173 ; CHECK-NEXT:    [[I]] = add i32 [[PHI_INSPT]], 1
174 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10
175 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]
176 ; CHECK:       end:
177 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY]] ], [ [[PHI_IN]], [[FOR]] ]
178 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1
179 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
180 ; CHECK-NEXT:    ret i32 [[LOAD]]
182 entry:
183   %a = alloca %pair, align 4
184   %b = alloca %pair, align 4
185   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
186   %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1
187   store i32 1, ptr %gep_a, align 4
188   store i32 2, ptr %gep_b, align 4
189   br i1 %cond, label %for, label %end
191 for:
192   %phi_in = phi ptr [ null, %entry ], [ %b, %for ]
193   %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ]
194   %i = add i32 %phi_inspt, 1
195   %loop.cond = icmp ult i32 %i, 10
196   br i1 %loop.cond, label %for, label %end
198 end:
199   %phi = phi ptr [ %a, %entry], [ %phi_in, %for ]
200   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
201   %load = load i32, ptr %gep, align 4
202   ret i32 %load
205 define i32 @test_sroa_gep_phi_gep(i1 %cond) {
206 ; CHECK-LABEL: @test_sroa_gep_phi_gep(
207 ; CHECK-NEXT:  entry:
208 ; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4
209 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
210 ; CHECK:       for:
211 ; CHECK-NEXT:    [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]
212 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[GEP_FOR:%.*]], [[FOR]] ]
213 ; CHECK-NEXT:    [[I]] = add i32 [[PHI_I]], 1
214 ; CHECK-NEXT:    [[GEP_FOR]] = getelementptr inbounds i32, ptr [[PHI]], i32 0
215 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10
216 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]
217 ; CHECK:       end:
218 ; CHECK-NEXT:    [[PHI_END:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ]
219 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PHI_END]], align 4
220 ; CHECK-NEXT:    ret i32 [[LOAD]]
222 entry:
223   %a = alloca %pair, align 4
224   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
225   br i1 %cond, label %for, label %end
227 for:
228   %phi_i = phi i32 [ 0, %entry ], [ %i, %for ]
229   %phi = phi ptr [ %gep_a, %entry], [ %gep_for, %for ]
230   %i = add i32 %phi_i, 1
231   %gep_for = getelementptr inbounds i32, i32* %phi, i32 0
232   %loop.cond = icmp ult i32 %i, 10
233   br i1 %loop.cond, label %for, label %end
235 end:
236   %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]
237   %load = load i32, ptr %phi_end, align 4
238   ret i32 %load
241 define i32 @test_sroa_invoke_phi_gep(i1 %cond) personality ptr @__gxx_personality_v0 {
242 ; CHECK-LABEL: @test_sroa_invoke_phi_gep(
243 ; CHECK-NEXT:  entry:
244 ; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4
245 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[CALL:%.*]], label [[END:%.*]]
246 ; CHECK:       call:
247 ; CHECK-NEXT:    [[B:%.*]] = invoke ptr @foo()
248 ; CHECK-NEXT:    to label [[END]] unwind label [[INVOKE_CATCH:%.*]]
249 ; CHECK:       end:
250 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[CALL]] ]
251 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1
252 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
253 ; CHECK-NEXT:    ret i32 [[LOAD]]
254 ; CHECK:       invoke_catch:
255 ; CHECK-NEXT:    [[RES:%.*]] = landingpad { ptr, i32 }
256 ; CHECK-NEXT:    catch ptr null
257 ; CHECK-NEXT:    ret i32 0
259 entry:
260   %a = alloca %pair, align 4
261   br i1 %cond, label %call, label %end
263 call:
264   %b = invoke ptr @foo()
265   to label %end unwind label %invoke_catch
267 end:
268   %phi = phi ptr [ %a, %entry], [ %b, %call ]
269   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
270   %load = load i32, ptr %gep, align 4
271   ret i32 %load
273 invoke_catch:
274   %res = landingpad { ptr, i32 }
275   catch ptr null
276   ret i32 0
279 define i32 @test_sroa_phi_gep_nonconst_idx(i1 %cond, i32 %idx) {
280 ; CHECK-LABEL: @test_sroa_phi_gep_nonconst_idx(
281 ; CHECK-NEXT:  entry:
282 ; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4
283 ; CHECK-NEXT:    [[B:%.*]] = alloca [[PAIR]], align 4
284 ; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1
285 ; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], ptr [[B]], i32 0, i32 1
286 ; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4
287 ; CHECK-NEXT:    store i32 2, ptr [[GEP_B]], align 4
288 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
289 ; CHECK:       if.then:
290 ; CHECK-NEXT:    br label [[END]]
291 ; CHECK:       end:
292 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
293 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 [[IDX:%.*]], i32 1
294 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
295 ; CHECK-NEXT:    ret i32 [[LOAD]]
297 entry:
298   %a = alloca %pair, align 4
299   %b = alloca %pair, align 4
300   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
301   %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1
302   store i32 1, ptr %gep_a, align 4
303   store i32 2, ptr %gep_b, align 4
304   br i1 %cond, label %if.then, label %end
306 if.then:
307   br label %end
309 end:
310   %phi = phi ptr [ %a, %entry], [ %b, %if.then ]
311   %gep = getelementptr inbounds %pair, ptr %phi, i32 %idx, i32 1
312   %load = load i32, ptr %gep, align 4
313   ret i32 %load
316 define void @test_sroa_gep_phi_select_other_block(i1 %c1, i1 %c2, ptr %ptr) {
317 ; CHECK-LABEL: @test_sroa_gep_phi_select_other_block(
318 ; CHECK-NEXT:  entry:
319 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8
320 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
321 ; CHECK:       while.body:
322 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ]
323 ; CHECK-NEXT:    [[SELECT]] = select i1 [[C1:%.*]], ptr [[PHI]], ptr [[PTR:%.*]]
324 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[WHILE_BODY]]
325 ; CHECK:       exit:
326 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i64 1
327 ; CHECK-NEXT:    unreachable
329 entry:
330   %alloca = alloca %pair, align 8
331   br label %while.body
333 while.body:
334   %phi = phi ptr [ %alloca, %entry ], [ %select, %while.body ]
335   %select = select i1 %c1, ptr %phi, ptr %ptr
336   br i1 %c2, label %exit, label %while.body
338 exit:
339   %gep = getelementptr inbounds %pair, ptr %phi, i64 1
340   unreachable
343 define void @test_sroa_gep_phi_select_same_block(i1 %c1, i1 %c2, ptr %ptr) {
344 ; CHECK-LABEL: @test_sroa_gep_phi_select_same_block(
345 ; CHECK-NEXT:  entry:
346 ; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8
347 ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
348 ; CHECK:       while.body:
349 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ]
350 ; CHECK-NEXT:    [[SELECT]] = select i1 [[C1:%.*]], ptr [[PHI]], ptr [[PTR:%.*]]
351 ; CHECK-NEXT:    [[PHI_SROA_GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i64 1
352 ; CHECK-NEXT:    [[PTR_SROA_GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PTR]], i64 1
353 ; CHECK-NEXT:    [[SELECT_SROA_SEL:%.*]] = select i1 [[C1]], ptr [[PHI_SROA_GEP]], ptr [[PTR_SROA_GEP]]
354 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[WHILE_BODY]]
355 ; CHECK:       exit:
356 ; CHECK-NEXT:    ret void
358 entry:
359   %alloca = alloca %pair, align 8
360   br label %while.body
362 while.body:
363   %phi = phi ptr [ %alloca, %entry ], [ %select, %while.body ]
364   %select = select i1 %c1, ptr %phi, ptr %ptr
365   %gep = getelementptr inbounds %pair, ptr %select, i64 1
366   br i1 %c2, label %exit, label %while.body
368 exit:
369   ret void
372 define i32 @test_sroa_gep_cast_phi_gep(i1 %cond) {
373 ; CHECK-LABEL: @test_sroa_gep_cast_phi_gep(
374 ; CHECK-NEXT:  entry:
375 ; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4
376 ; CHECK-NEXT:    store i32 1065353216, ptr [[A_SROA_0]], align 4
377 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
378 ; CHECK:       for:
379 ; CHECK-NEXT:    [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]
380 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[GEP_FOR:%.*]], [[FOR]] ]
381 ; CHECK-NEXT:    [[I]] = add i32 [[PHI_I]], 1
382 ; CHECK-NEXT:    [[GEP_FOR]] = getelementptr inbounds float, ptr [[PHI]], i32 0
383 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10
384 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]
385 ; CHECK:       end:
386 ; CHECK-NEXT:    [[PHI_END:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ]
387 ; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PHI_END]], align 4
388 ; CHECK-NEXT:    ret i32 [[LOAD]]
390 entry:
391   %a = alloca %pair, align 4
392   %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1
393   store float 1.0, ptr %gep_a, align 4
394   br i1 %cond, label %for, label %end
396 for:
397   %phi_i = phi i32 [ 0, %entry ], [ %i, %for ]
398   %phi = phi ptr [ %gep_a, %entry], [ %gep_for, %for ]
399   %i = add i32 %phi_i, 1
400   %gep_for = getelementptr inbounds float, float* %phi, i32 0
401   %loop.cond = icmp ult i32 %i, 10
402   br i1 %loop.cond, label %for, label %end
404 end:
405   %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]
406   %load = load i32, ptr %phi_end, align 4
407   ret i32 %load
410 define void @unreachable_term(i1 %c1) {
411 ; CHECK-LABEL: @unreachable_term(
412 ; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4
413 ; CHECK-NEXT:    unreachable
414 ; CHECK:       bb1:
415 ; CHECK-NEXT:    br label [[BB1_I:%.*]]
416 ; CHECK:       bb1.i:
417 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[BB1:%.*]] ], [ null, [[BB1_I]] ]
418 ; CHECK-NEXT:    store i32 0, ptr [[PHI]], align 1
419 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1_I]], label [[EXIT:%.*]]
420 ; CHECK:       exit:
421 ; CHECK-NEXT:    br label [[BB2:%.*]]
422 ; CHECK:       bb2:
423 ; CHECK-NEXT:    ret void
425   %a = alloca [3 x i32], align 1
426   unreachable
428 bb1:
429   br label %bb1.i
431 bb1.i:
432   %phi = phi ptr [ %a, %bb1 ], [ null, %bb1.i ]
433   store i32 0, ptr %phi, align 1
434   br i1 %c1, label %bb1.i, label %exit
436 exit:
437   br label %bb2
439 bb2:
440   ret void
443 define void @constant_value_phi(i1 %c1) {
444 ; CHECK-LABEL: @constant_value_phi(
445 ; CHECK-NEXT:  entry:
446 ; CHECK-NEXT:    br label [[LAND_LHS_TRUE_I:%.*]]
447 ; CHECK:       land.lhs.true.i:
448 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[COND_END_I:%.*]], label [[COND_END_I]]
449 ; CHECK:       cond.end.i:
450 ; CHECK-NEXT:    unreachable
452 entry:
453   %s1 = alloca [3 x i16]
454   %s = alloca [3 x i16]
455   br label %land.lhs.true.i
457 land.lhs.true.i:                                  ; preds = %entry
458   br i1 %c1, label %cond.end.i, label %cond.end.i
460 cond.end.i:                                       ; preds = %land.lhs.true.i, %land.lhs.true.i
461   %.pre-phi1 = phi ptr [ %s1, %land.lhs.true.i ], [ %s1, %land.lhs.true.i ]
462   call void @llvm.memcpy.p0.p0.i64(ptr %.pre-phi1, ptr %s, i64 3, i1 false)
463   %load = load i16, ptr %s
464   unreachable
467 define i32 @test_sroa_phi_gep_multiple_values_from_same_block(i32 %arg) {
468 ; CHECK-LABEL: @test_sroa_phi_gep_multiple_values_from_same_block(
469 ; CHECK-NEXT:  bb.1:
470 ; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[BB_3:%.*]] [
471 ; CHECK-NEXT:    i32 1, label [[BB_2:%.*]]
472 ; CHECK-NEXT:    i32 2, label [[BB_2]]
473 ; CHECK-NEXT:    i32 3, label [[BB_4:%.*]]
474 ; CHECK-NEXT:    i32 4, label [[BB_4]]
475 ; CHECK-NEXT:    ]
476 ; CHECK:       bb.2:
477 ; CHECK-NEXT:    br label [[BB_4]]
478 ; CHECK:       bb.3:
479 ; CHECK-NEXT:    br label [[BB_4]]
480 ; CHECK:       bb.4:
481 ; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[BB_3]] ], [ undef, [[BB_2]] ], [ undef, [[BB_1:%.*]] ], [ undef, [[BB_1]] ]
482 ; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]
484 bb.1:
485   %a = alloca %pair, align 4
486   %b = alloca %pair, align 4
487   switch i32 %arg, label %bb.3 [
488   i32 1, label %bb.2
489   i32 2, label %bb.2
490   i32 3, label %bb.4
491   i32 4, label %bb.4
492   ]
494 bb.2:                                                ; preds = %bb.1, %bb.1
495   br label %bb.4
497 bb.3:                                                ; preds = %bb.1
498   br label %bb.4
500 bb.4:                                                ; preds = %bb.1, %bb.1, %bb.3, %bb.2
501   %phi = phi ptr [ %a, %bb.3 ], [ %a, %bb.2 ], [ %b, %bb.1 ], [ %b, %bb.1 ]
502   %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1
503   %load = load i32, ptr %gep, align 4
504   ret i32 %load
507 declare ptr @foo()
509 declare i32 @__gxx_personality_v0(...)
511 declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
512 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
513 ; CHECK-MODIFY-CFG: {{.*}}
514 ; CHECK-PRESERVE-CFG: {{.*}}