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(
10 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
12 ; CHECK-NEXT: br label [[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]]
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
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
36 define i32 @test_sroa_phi_gep_non_inbound(i1 %cond) {
37 ; CHECK-LABEL: @test_sroa_phi_gep_non_inbound(
39 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
41 ; CHECK-NEXT: br label [[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]]
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
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
65 define i32 @test_sroa_phi_gep_poison(i1 %cond) {
66 ; CHECK-LABEL: @test_sroa_phi_gep_poison(
68 ; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4
69 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]
71 ; CHECK-NEXT: br label [[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]]
79 %a = alloca %pair, align 4
80 br i1 %cond, label %if.then, label %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
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(
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:%.*]]
102 ; CHECK-NEXT: br label [[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]]
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
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
125 define i32 @test_sroa_phi_gep_arg_phi_inspt(i1 %cond) {
126 ; CHECK-LABEL: @test_sroa_phi_gep_arg_phi_inspt(
128 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
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]]
135 ; CHECK-NEXT: [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ 2, [[FOR]] ]
136 ; CHECK-NEXT: ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]
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
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
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
160 define i32 @test_sroa_phi_gep_phi_inspt(i1 %cond) {
161 ; CHECK-LABEL: @test_sroa_phi_gep_phi_inspt(
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:%.*]]
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]]
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]]
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
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
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
205 define i32 @test_sroa_gep_phi_gep(i1 %cond) {
206 ; CHECK-LABEL: @test_sroa_gep_phi_gep(
208 ; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
209 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]
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]]
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]]
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
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
236 %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]
237 %load = load i32, ptr %phi_end, align 4
241 define i32 @test_sroa_invoke_phi_gep(i1 %cond) personality ptr @__gxx_personality_v0 {
242 ; CHECK-LABEL: @test_sroa_invoke_phi_gep(
244 ; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4
245 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[CALL:%.*]], label [[END:%.*]]
247 ; CHECK-NEXT: [[B:%.*]] = invoke ptr @foo()
248 ; CHECK-NEXT: to label [[END]] unwind label [[INVOKE_CATCH:%.*]]
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
260 %a = alloca %pair, align 4
261 br i1 %cond, label %call, label %end
264 %b = invoke ptr @foo()
265 to label %end unwind label %invoke_catch
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
274 %res = landingpad { ptr, i32 }
279 define i32 @test_sroa_phi_gep_nonconst_idx(i1 %cond, i32 %idx) {
280 ; CHECK-LABEL: @test_sroa_phi_gep_nonconst_idx(
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:%.*]]
290 ; CHECK-NEXT: br label [[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]]
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
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
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(
319 ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8
320 ; CHECK-NEXT: br label [[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]]
326 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i64 1
327 ; CHECK-NEXT: unreachable
330 %alloca = alloca %pair, align 8
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
339 %gep = getelementptr inbounds %pair, ptr %phi, i64 1
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(
346 ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8
347 ; CHECK-NEXT: br label [[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]]
356 ; CHECK-NEXT: ret void
359 %alloca = alloca %pair, align 8
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
372 define i32 @test_sroa_gep_cast_phi_gep(i1 %cond) {
373 ; CHECK-LABEL: @test_sroa_gep_cast_phi_gep(
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:%.*]]
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]]
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]]
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
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
405 %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]
406 %load = load i32, ptr %phi_end, align 4
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
415 ; CHECK-NEXT: br label [[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:%.*]]
421 ; CHECK-NEXT: br label [[BB2:%.*]]
423 ; CHECK-NEXT: ret void
425 %a = alloca [3 x i32], align 1
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
443 define void @constant_value_phi(i1 %c1) {
444 ; CHECK-LABEL: @constant_value_phi(
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]]
450 ; CHECK-NEXT: unreachable
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
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(
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]]
477 ; CHECK-NEXT: br label [[BB_4]]
479 ; CHECK-NEXT: br label [[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]]
485 %a = alloca %pair, align 4
486 %b = alloca %pair, align 4
487 switch i32 %arg, label %bb.3 [
494 bb.2: ; preds = %bb.1, %bb.1
497 bb.3: ; preds = %bb.1
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
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: {{.*}}