xref: /llvm-project/llvm/test/Transforms/SROA/phi-and-select.ll (revision 6dba99e14f7e508a5028036b753fa7f84e846307)
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
4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
5
6define i32 @test1() {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 1
10; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[EXIT:%.*]]
11; CHECK:       then:
12; CHECK-NEXT:    br label [[EXIT]]
13; CHECK:       exit:
14; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
15; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]
16;
17entry:
18  %a = alloca [2 x i32]
19
20  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
21  store i32 0, ptr %a
22  store i32 1, ptr %a1
23  %v0 = load i32, ptr %a
24  %v1 = load i32, ptr %a1
25
26  %cond = icmp sle i32 %v0, %v1
27  br i1 %cond, label %then, label %exit
28
29then:
30  br label %exit
31
32exit:
33  %phi = phi ptr [ %a1, %then ], [ %a, %entry ]
34
35  %result = load i32, ptr %phi
36  ret i32 %result
37}
38
39define i32 @test2() {
40; CHECK-LABEL: @test2(
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 1
43; CHECK-NEXT:    [[RESULT_SROA_SPECULATED:%.*]] = select i1 [[COND]], i32 1, i32 0
44; CHECK-NEXT:    ret i32 [[RESULT_SROA_SPECULATED]]
45;
46entry:
47  %a = alloca [2 x i32]
48
49  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
50  store i32 0, ptr %a
51  store i32 1, ptr %a1
52  %v0 = load i32, ptr %a
53  %v1 = load i32, ptr %a1
54
55  %cond = icmp sle i32 %v0, %v1
56  %select = select i1 %cond, ptr %a1, ptr %a
57
58  %result = load i32, ptr %select
59  ret i32 %result
60}
61
62define float @test2_bitcast() {
63; CHECK-LABEL: @test2_bitcast(
64; CHECK-NEXT:  entry:
65; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 1
66; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 1 to float
67; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 0 to float
68; CHECK-NEXT:    [[RESULT_SROA_SPECULATED:%.*]] = select i1 [[COND]], float [[TMP0]], float [[TMP1]]
69; CHECK-NEXT:    ret float [[RESULT_SROA_SPECULATED]]
70;
71entry:
72  %a = alloca [2 x i32]
73  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
74  store i32 0, ptr %a
75  store i32 1, ptr %a1
76  %v0 = load i32, ptr %a
77  %v1 = load i32, ptr %a1
78  %cond = icmp sle i32 %v0, %v1
79  %select = select i1 %cond, ptr %a1, ptr %a
80  %result = load float, ptr %select
81  ret float %result
82}
83
84define i32 @test2_addrspacecast() {
85; CHECK-LABEL: @test2_addrspacecast(
86; CHECK-NEXT:  entry:
87; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4
88; CHECK-NEXT:    [[A_SROA_3:%.*]] = alloca i32, align 4
89; CHECK-NEXT:    store i32 0, ptr [[A_SROA_0]], align 4
90; CHECK-NEXT:    store i32 1, ptr [[A_SROA_3]], align 4
91; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 4
92; CHECK-NEXT:    [[A_SROA_3_0_A_SROA_3_4_V1:%.*]] = load i32, ptr [[A_SROA_3]], align 4
93; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 [[A_SROA_0_0_A_SROA_0_0_V0]], [[A_SROA_3_0_A_SROA_3_4_V1]]
94; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], ptr [[A_SROA_3]], ptr [[A_SROA_0]]
95; CHECK-NEXT:    [[SELECT_ASC:%.*]] = addrspacecast ptr [[SELECT]] to ptr addrspace(1)
96; CHECK-NEXT:    [[RESULT:%.*]] = load i32, ptr addrspace(1) [[SELECT_ASC]], align 4
97; CHECK-NEXT:    ret i32 [[RESULT]]
98;
99entry:
100  %a = alloca [2 x i32]
101  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
102  store i32 0, ptr %a
103  store i32 1, ptr %a1
104  %v0 = load i32, ptr %a
105  %v1 = load i32, ptr %a1
106  %cond = icmp sle i32 %v0, %v1
107  %select = select i1 %cond, ptr %a1, ptr %a
108  %select.asc = addrspacecast ptr %select to ptr addrspace(1)
109  %result = load i32, ptr addrspace(1) %select.asc
110  ret i32 %result
111}
112
113define i32 @test3(i32 %x) {
114; CHECK-LABEL: @test3(
115; CHECK-NEXT:  entry:
116; CHECK-NEXT:    switch i32 [[X:%.*]], label [[BB0:%.*]] [
117; CHECK-NEXT:      i32 1, label [[BB1:%.*]]
118; CHECK-NEXT:      i32 2, label [[BB2:%.*]]
119; CHECK-NEXT:      i32 3, label [[BB3:%.*]]
120; CHECK-NEXT:      i32 4, label [[BB4:%.*]]
121; CHECK-NEXT:      i32 5, label [[BB5:%.*]]
122; CHECK-NEXT:      i32 6, label [[BB6:%.*]]
123; CHECK-NEXT:      i32 7, label [[BB7:%.*]]
124; CHECK-NEXT:    ]
125; CHECK:       bb0:
126; CHECK-NEXT:    br label [[EXIT:%.*]]
127; CHECK:       bb1:
128; CHECK-NEXT:    br label [[EXIT]]
129; CHECK:       bb2:
130; CHECK-NEXT:    br label [[EXIT]]
131; CHECK:       bb3:
132; CHECK-NEXT:    br label [[EXIT]]
133; CHECK:       bb4:
134; CHECK-NEXT:    br label [[EXIT]]
135; CHECK:       bb5:
136; CHECK-NEXT:    br label [[EXIT]]
137; CHECK:       bb6:
138; CHECK-NEXT:    br label [[EXIT]]
139; CHECK:       bb7:
140; CHECK-NEXT:    br label [[EXIT]]
141; CHECK:       exit:
142; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[BB0]] ], [ 0, [[BB1]] ], [ 0, [[BB2]] ], [ 1, [[BB3]] ], [ 1, [[BB4]] ], [ 0, [[BB5]] ], [ 0, [[BB6]] ], [ 1, [[BB7]] ]
143; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]
144;
145entry:
146  %a = alloca [2 x i32]
147
148  ; Note that we build redundant GEPs here to ensure that having different GEPs
149  ; into the same alloca partation continues to work with PHI speculation. This
150  ; was the underlying cause of PR13926.
151  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
152  %a1b = getelementptr [2 x i32], ptr %a, i64 0, i32 1
153  store i32 0, ptr %a
154  store i32 1, ptr %a1
155
156  switch i32 %x, label %bb0 [ i32 1, label %bb1
157  i32 2, label %bb2
158  i32 3, label %bb3
159  i32 4, label %bb4
160  i32 5, label %bb5
161  i32 6, label %bb6
162  i32 7, label %bb7 ]
163
164bb0:
165  br label %exit
166bb1:
167  br label %exit
168bb2:
169  br label %exit
170bb3:
171  br label %exit
172bb4:
173  br label %exit
174bb5:
175  br label %exit
176bb6:
177  br label %exit
178bb7:
179  br label %exit
180
181exit:
182  %phi = phi ptr [ %a1, %bb0 ], [ %a, %bb1 ], [ %a, %bb2 ], [ %a1, %bb3 ],
183  [ %a1b, %bb4 ], [ %a, %bb5 ], [ %a, %bb6 ], [ %a1b, %bb7 ]
184
185  %result = load i32, ptr %phi
186  ret i32 %result
187}
188
189define i32 @test4() {
190; CHECK-LABEL: @test4(
191; CHECK-NEXT:  entry:
192; CHECK-NEXT:    ret i32 0
193;
194entry:
195  %a = alloca [2 x i32]
196
197  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
198  store i32 0, ptr %a
199  store i32 1, ptr %a1
200  %v0 = load i32, ptr %a
201  %v1 = load i32, ptr %a1
202
203  %cond = icmp sle i32 %v0, %v1
204  %select = select i1 %cond, ptr %a, ptr %a
205
206  %result = load i32, ptr %select
207  ret i32 %result
208}
209
210define i32 @test5(ptr %b) {
211; CHECK-LABEL: @test5(
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    ret i32 1
214;
215entry:
216  %a = alloca [2 x i32]
217
218  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
219  store i32 1, ptr %a1
220
221  %select = select i1 true, ptr %a1, ptr %b
222
223  %result = load i32, ptr %select
224
225  ret i32 %result
226}
227
228declare void @f(ptr, ptr)
229
230define i32 @test6(ptr %b) {
231; CHECK-LABEL: @test6(
232; CHECK-NEXT:  entry:
233; CHECK-NEXT:    [[SELECT2:%.*]] = select i1 false, ptr poison, ptr [[B:%.*]]
234; CHECK-NEXT:    [[SELECT3:%.*]] = select i1 false, ptr poison, ptr [[B]]
235; CHECK-NEXT:    call void @f(ptr [[SELECT2]], ptr [[SELECT3]])
236; CHECK-NEXT:    ret i32 1
237;
238entry:
239  %a = alloca [2 x i32]
240  %c = alloca i32
241
242  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1
243  store i32 1, ptr %a1
244
245  %select = select i1 true, ptr %a1, ptr %b
246  %select2 = select i1 false, ptr %a1, ptr %b
247  %select3 = select i1 false, ptr %c, ptr %b
248
249  ; Note, this would potentially escape the alloca pointer except for the
250  ; constant folding of the select.
251  call void @f(ptr %select2, ptr %select3)
252
253
254  %result = load i32, ptr %select
255
256  %dead = load i32, ptr %c
257
258  ret i32 %result
259}
260
261define i32 @test7(i1 %c1) {
262; CHECK-LABEL: @test7(
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    br i1 [[C1:%.*]], label [[GOOD:%.*]], label [[BAD:%.*]]
265; CHECK:       good:
266; CHECK-NEXT:    br label [[EXIT:%.*]]
267; CHECK:       bad:
268; CHECK-NEXT:    [[P_SROA_SPECULATE_LOAD_BAD:%.*]] = load i32, ptr poison, align 4
269; CHECK-NEXT:    br label [[EXIT]]
270; CHECK:       exit:
271; CHECK-NEXT:    [[P_SROA_SPECULATED:%.*]] = phi i32 [ 0, [[GOOD]] ], [ [[P_SROA_SPECULATE_LOAD_BAD]], [[BAD]] ]
272; CHECK-NEXT:    ret i32 [[P_SROA_SPECULATED]]
273;
274entry:
275  %X = alloca i32
276  br i1 %c1, label %good, label %bad
277
278good:
279  store i32 0, ptr %X
280  br label %exit
281
282bad:
283  %Y2 = getelementptr i32, ptr %X, i64 1
284  store i32 0, ptr %Y2
285  br label %exit
286
287exit:
288  %P = phi ptr [ %X, %good ], [ %Y2, %bad ]
289  %Z2 = load i32, ptr %P
290  ret i32 %Z2
291}
292
293define i32 @test8(i32 %b, ptr %ptr) {
294; Ensure that we rewrite allocas to the used type when that use is hidden by
295; a PHI that can be speculated.
296;
297; CHECK-LABEL: @test8(
298; CHECK-NEXT:  entry:
299; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
300; CHECK-NEXT:    br i1 [[TEST]], label [[THEN:%.*]], label [[ELSE:%.*]]
301; CHECK:       then:
302; CHECK-NEXT:    [[PHI_SROA_SPECULATE_LOAD_THEN:%.*]] = load i32, ptr [[PTR:%.*]], align 4
303; CHECK-NEXT:    br label [[EXIT:%.*]]
304; CHECK:       else:
305; CHECK-NEXT:    br label [[EXIT]]
306; CHECK:       exit:
307; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[ELSE]] ], [ [[PHI_SROA_SPECULATE_LOAD_THEN]], [[THEN]] ]
308; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]
309;
310entry:
311  %f = alloca float
312  %test = icmp ne i32 %b, 0
313  br i1 %test, label %then, label %else
314
315then:
316  br label %exit
317
318else:
319  br label %exit
320
321exit:
322  %phi = phi ptr [ %f, %else ], [ %ptr, %then ]
323  %loaded = load i32, ptr %phi, align 4
324  ret i32 %loaded
325}
326
327define i32 @test9(i32 %b, ptr %ptr) {
328; Same as @test8 but for a select rather than a PHI node.
329;
330; CHECK-LABEL: @test9(
331; CHECK-NEXT:  entry:
332; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
333; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
334; CHECK-NEXT:    [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i32, ptr [[PTR]], align 4
335; CHECK-NEXT:    [[LOADED_SROA_SPECULATED:%.*]] = select i1 [[TEST]], i32 undef, i32 [[LOADED_SROA_SPECULATE_LOAD_FALSE]]
336; CHECK-NEXT:    ret i32 [[LOADED_SROA_SPECULATED]]
337;
338entry:
339  %f = alloca float
340  store i32 0, ptr %ptr
341  %test = icmp ne i32 %b, 0
342  %select = select i1 %test, ptr %f, ptr %ptr
343  %loaded = load i32, ptr %select, align 4
344  ret i32 %loaded
345}
346
347; We should not unconditionally load with sanitizers.
348define i32 @test9_asan(i32 %b, ptr %ptr) sanitize_address {
349; Same as @test8 but for a select rather than a PHI node.
350;
351; CHECK-PRESERVE-CFG-LABEL: @test9_asan(
352; CHECK-PRESERVE-CFG-NEXT:  entry:
353; CHECK-PRESERVE-CFG-NEXT:    [[F:%.*]] = alloca float, align 4
354; CHECK-PRESERVE-CFG-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
355; CHECK-PRESERVE-CFG-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
356; CHECK-PRESERVE-CFG-NEXT:    [[SELECT:%.*]] = select i1 [[TEST]], ptr [[F]], ptr [[PTR]]
357; CHECK-PRESERVE-CFG-NEXT:    [[LOADED:%.*]] = load i32, ptr [[SELECT]], align 4
358; CHECK-PRESERVE-CFG-NEXT:    ret i32 [[LOADED]]
359;
360; CHECK-MODIFY-CFG-LABEL: @test9_asan(
361; CHECK-MODIFY-CFG-NEXT:  entry:
362; CHECK-MODIFY-CFG-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
363; CHECK-MODIFY-CFG-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
364; CHECK-MODIFY-CFG-NEXT:    [[LOADED_ELSE_VAL:%.*]] = load i32, ptr [[PTR]], align 4
365; CHECK-MODIFY-CFG-NEXT:    br i1 [[TEST]], label [[ENTRY_THEN:%.*]], label [[ENTRY_CONT:%.*]]
366; CHECK-MODIFY-CFG:       entry.then:
367; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT]]
368; CHECK-MODIFY-CFG:       entry.cont:
369; CHECK-MODIFY-CFG-NEXT:    [[LOADED:%.*]] = phi i32 [ undef, [[ENTRY_THEN]] ], [ [[LOADED_ELSE_VAL]], [[ENTRY:%.*]] ]
370; CHECK-MODIFY-CFG-NEXT:    ret i32 [[LOADED]]
371;
372entry:
373  %f = alloca float
374  store i32 0, ptr %ptr
375  %test = icmp ne i32 %b, 0
376  %select = select i1 %test, ptr %f, ptr %ptr
377  %loaded = load i32, ptr %select, align 4
378  ret i32 %loaded
379}
380
381define float @test10(i32 %b, ptr %ptr) {
382; Don't try to promote allocas which are not elligible for it even after
383; rewriting due to the necessity of inserting bitcasts when speculating a PHI
384; node.
385;
386; CHECK-LABEL: @test10(
387; CHECK-NEXT:  entry:
388; CHECK-NEXT:    [[F:%.*]] = alloca double, align 8
389; CHECK-NEXT:    store double 0.000000e+00, ptr [[F]], align 8
390; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
391; CHECK-NEXT:    br i1 [[TEST]], label [[THEN:%.*]], label [[ELSE:%.*]]
392; CHECK:       then:
393; CHECK-NEXT:    [[PHI_SROA_SPECULATE_LOAD_THEN:%.*]] = load float, ptr [[PTR:%.*]], align 4
394; CHECK-NEXT:    br label [[EXIT:%.*]]
395; CHECK:       else:
396; CHECK-NEXT:    [[F_0_PHI_SROA_SPECULATE_LOAD_ELSE:%.*]] = load float, ptr [[F]], align 8
397; CHECK-NEXT:    br label [[EXIT]]
398; CHECK:       exit:
399; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi float [ [[F_0_PHI_SROA_SPECULATE_LOAD_ELSE]], [[ELSE]] ], [ [[PHI_SROA_SPECULATE_LOAD_THEN]], [[THEN]] ]
400; CHECK-NEXT:    ret float [[PHI_SROA_SPECULATED]]
401;
402entry:
403  %f = alloca double
404  store double 0.0, ptr %f
405  %test = icmp ne i32 %b, 0
406  br i1 %test, label %then, label %else
407
408then:
409  br label %exit
410
411else:
412  br label %exit
413
414exit:
415  %phi = phi ptr [ %f, %else ], [ %ptr, %then ]
416  %loaded = load float, ptr %phi, align 4
417  ret float %loaded
418}
419
420define float @test11(i32 %b, ptr %ptr) {
421; Same as @test10 but for a select rather than a PHI node.
422;
423; CHECK-LABEL: @test11(
424; CHECK-NEXT:  entry:
425; CHECK-NEXT:    [[F:%.*]] = alloca double, align 8
426; CHECK-NEXT:    store double 0.000000e+00, ptr [[F]], align 8
427; CHECK-NEXT:    store float 0.000000e+00, ptr [[PTR:%.*]], align 4
428; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0
429; CHECK-NEXT:    [[F_0_LOADED_SROA_SPECULATE_LOAD_TRUE:%.*]] = load float, ptr [[F]], align 8
430; CHECK-NEXT:    [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load float, ptr [[PTR]], align 4
431; CHECK-NEXT:    [[LOADED_SROA_SPECULATED:%.*]] = select i1 [[TEST]], float [[F_0_LOADED_SROA_SPECULATE_LOAD_TRUE]], float [[LOADED_SROA_SPECULATE_LOAD_FALSE]]
432; CHECK-NEXT:    ret float [[LOADED_SROA_SPECULATED]]
433;
434entry:
435  %f = alloca double
436  store double 0.0, ptr %f
437  store float 0.0, ptr %ptr
438  %test = icmp ne i32 %b, 0
439  %select = select i1 %test, ptr %f, ptr %ptr
440  %loaded = load float, ptr %select, align 4
441  ret float %loaded
442}
443
444define i32 @test12(i32 %x, ptr %p, i1 %c1) {
445; Ensure we don't crash or fail to nuke dead selects of allocas if no load is
446; never found.
447;
448; CHECK-LABEL: @test12(
449; CHECK-NEXT:  entry:
450; CHECK-NEXT:    ret i32 [[X:%.*]]
451;
452entry:
453  %a = alloca i32
454  store i32 %x, ptr %a
455  %dead = select i1 %c1, ptr %a, ptr %p
456  %load = load i32, ptr %a
457  ret i32 %load
458}
459
460define i32 @test13(i32 %x, ptr %p, i1 %c1) {
461; Ensure we don't crash or fail to nuke dead phis of allocas if no load is ever
462; found.
463;
464; CHECK-LABEL: @test13(
465; CHECK-NEXT:  entry:
466; CHECK-NEXT:    br label [[LOOP:%.*]]
467; CHECK:       loop:
468; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
469; CHECK:       exit:
470; CHECK-NEXT:    ret i32 [[X:%.*]]
471;
472entry:
473  %a = alloca i32
474  store i32 %x, ptr %a
475  br label %loop
476
477loop:
478  %phi = phi ptr [ %p, %entry ], [ %a, %loop ]
479  br i1 %c1, label %loop, label %exit
480
481exit:
482  %load = load i32, ptr %a
483  ret i32 %load
484}
485
486define i32 @test14(i1 %b1, i1 %b2, ptr %ptr) {
487; Check for problems when there are both selects and phis and one is
488; speculatable toward promotion but the other is not. That should block all of
489; the speculation.
490;
491; CHECK-LABEL: @test14(
492; CHECK-NEXT:  entry:
493; CHECK-NEXT:    [[F:%.*]] = alloca i32, align 4
494; CHECK-NEXT:    [[G:%.*]] = alloca i32, align 4
495; CHECK-NEXT:    store i32 0, ptr [[F]], align 4
496; CHECK-NEXT:    store i32 0, ptr [[G]], align 4
497; CHECK-NEXT:    [[F_SELECT:%.*]] = select i1 [[B1:%.*]], ptr [[F]], ptr [[PTR:%.*]]
498; CHECK-NEXT:    br i1 [[B2:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
499; CHECK:       then:
500; CHECK-NEXT:    br label [[EXIT:%.*]]
501; CHECK:       else:
502; CHECK-NEXT:    br label [[EXIT]]
503; CHECK:       exit:
504; CHECK-NEXT:    [[F_PHI:%.*]] = phi ptr [ [[F]], [[THEN]] ], [ [[F_SELECT]], [[ELSE]] ]
505; CHECK-NEXT:    [[G_PHI:%.*]] = phi ptr [ [[G]], [[THEN]] ], [ [[PTR]], [[ELSE]] ]
506; CHECK-NEXT:    [[F_LOADED:%.*]] = load i32, ptr [[F_PHI]], align 4
507; CHECK-NEXT:    [[G_SELECT:%.*]] = select i1 [[B1]], ptr [[G]], ptr [[G_PHI]]
508; CHECK-NEXT:    [[G_LOADED:%.*]] = load i32, ptr [[G_SELECT]], align 4
509; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[F_LOADED]], [[G_LOADED]]
510; CHECK-NEXT:    ret i32 [[RESULT]]
511;
512entry:
513  %f = alloca i32
514  %g = alloca i32
515  store i32 0, ptr %f
516  store i32 0, ptr %g
517  %f.select = select i1 %b1, ptr %f, ptr %ptr
518  br i1 %b2, label %then, label %else
519
520then:
521  br label %exit
522
523else:
524  br label %exit
525
526exit:
527  %f.phi = phi ptr [ %f, %then ], [ %f.select, %else ]
528  %g.phi = phi ptr [ %g, %then ], [ %ptr, %else ]
529  %f.loaded = load i32, ptr %f.phi
530  %g.select = select i1 %b1, ptr %g, ptr %g.phi
531  %g.loaded = load i32, ptr %g.select
532  %result = add i32 %f.loaded, %g.loaded
533  ret i32 %result
534}
535
536define void @PR13905(i1 %c1, i1 %c2, i1 %c3) {
537; Check a pattern where we have a chain of dead phi nodes to ensure they are
538; deleted and promotion can proceed.
539;
540; CHECK-LABEL: @PR13905(
541; CHECK-NEXT:  entry:
542; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOOP1:%.*]], label [[EXIT:%.*]]
543; CHECK:       loop1:
544; CHECK-NEXT:    br i1 [[C2:%.*]], label [[LOOP1]], label [[LOOP2:%.*]]
545; CHECK:       loop2:
546; CHECK-NEXT:    br i1 [[C3:%.*]], label [[LOOP1]], label [[EXIT]]
547; CHECK:       exit:
548; CHECK-NEXT:    [[PHI2:%.*]] = phi ptr [ poison, [[LOOP2]] ], [ null, [[ENTRY:%.*]] ]
549; CHECK-NEXT:    ret void
550;
551entry:
552  %h = alloca i32
553  store i32 0, ptr %h
554  br i1 %c1, label %loop1, label %exit
555
556loop1:
557  %phi1 = phi ptr [ null, %entry ], [ %h, %loop1 ], [ %h, %loop2 ]
558  br i1 %c2, label %loop1, label %loop2
559
560loop2:
561  br i1 %c3, label %loop1, label %exit
562
563exit:
564  %phi2 = phi ptr [ %phi1, %loop2 ], [ null, %entry ]
565  ret void
566}
567
568define i32 @PR13906(i1 %c1, i1 %c2) {
569; Another pattern which can lead to crashes due to failing to clear out dead
570; PHI nodes or select nodes. This triggers subtly differently from the above
571; cases because the PHI node is (recursively) alive, but the select is dead.
572;
573; CHECK-LABEL: @PR13906(
574; CHECK-NEXT:  entry:
575; CHECK-NEXT:    br label [[FOR_COND:%.*]]
576; CHECK:       for.cond:
577; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[FOR_COND]]
578; CHECK:       if.then:
579; CHECK-NEXT:    br label [[FOR_COND]]
580;
581entry:
582  %c = alloca i32
583  store i32 0, ptr %c
584  br label %for.cond
585
586for.cond:
587  %d.0 = phi ptr [ poison, %entry ], [ %c, %if.then ], [ %d.0, %for.cond ]
588  br i1 %c1, label %if.then, label %for.cond
589
590if.then:
591  %tmpcast.d.0 = select i1 %c2, ptr %c, ptr %d.0
592  br label %for.cond
593}
594
595define i64 @PR14132(i1 %flag) {
596; Here we form a PHI-node by promoting the pointer alloca first, and then in
597; order to promote the other two allocas, we speculate the load of the
598; now-phi-node-pointer. In doing so we end up loading a 64-bit value from an i8
599; alloca. While this is a bit dubious, we were asserting on trying to
600; rewrite it. The trick is that the code using the value may carefully take
601; steps to only use the not-undef bits, and so we need to at least loosely
602; support this..
603; CHECK-LABEL: @PR14132(
604; CHECK-NEXT:  entry:
605; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
606; CHECK:       if.then:
607; CHECK-NEXT:    [[B_0_LOAD_EXT:%.*]] = zext i8 1 to i64
608; CHECK-NEXT:    br label [[IF_END]]
609; CHECK:       if.end:
610; CHECK-NEXT:    [[PTR_0_SROA_SPECULATED:%.*]] = phi i64 [ [[B_0_LOAD_EXT]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
611; CHECK-NEXT:    ret i64 [[PTR_0_SROA_SPECULATED]]
612;
613entry:
614  %a = alloca i64, align 8
615  %b = alloca i8, align 8
616  %ptr = alloca ptr, align 8
617
618  store i64 0, ptr %a, align 8
619  store i8 1, ptr %b, align 8
620  store ptr %a, ptr %ptr, align 8
621  br i1 %flag, label %if.then, label %if.end
622
623if.then:
624  store ptr %b, ptr %ptr, align 8
625  br label %if.end
626
627if.end:
628  %tmp = load ptr, ptr %ptr, align 8
629  %result = load i64, ptr %tmp, align 8
630
631  ret i64 %result
632}
633
634define float @PR16687(i64 %x, i1 %flag) {
635; Check that even when we try to speculate the same phi twice (in two slices)
636; on an otherwise promotable construct, we don't get ahead of ourselves and try
637; to promote one of the slices prior to speculating it.
638; CHECK-LABEL: @PR16687(
639; CHECK-NEXT:  entry:
640; CHECK-NEXT:    [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[X:%.*]] to i32
641; CHECK-NEXT:    [[A_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[X]], 32
642; CHECK-NEXT:    [[A_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A_SROA_2_0_EXTRACT_SHIFT]] to i32
643; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
644; CHECK:       then:
645; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 [[A_SROA_0_0_EXTRACT_TRUNC]] to float
646; CHECK-NEXT:    br label [[END:%.*]]
647; CHECK:       else:
648; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 [[A_SROA_2_0_EXTRACT_TRUNC]] to float
649; CHECK-NEXT:    br label [[END]]
650; CHECK:       end:
651; CHECK-NEXT:    [[A_PHI_F_SROA_SPECULATED:%.*]] = phi float [ [[TMP0]], [[THEN]] ], [ [[TMP1]], [[ELSE]] ]
652; CHECK-NEXT:    ret float [[A_PHI_F_SROA_SPECULATED]]
653;
654entry:
655  %a = alloca i64, align 8
656  store i64 %x, ptr %a
657  br i1 %flag, label %then, label %else
658
659then:
660  br label %end
661
662else:
663  %a.raw.4 = getelementptr i8, ptr %a, i64 4
664  br label %end
665
666end:
667  %a.phi.f = phi ptr [ %a, %then ], [ %a.raw.4, %else ]
668  %f = load float, ptr %a.phi.f
669  ret float %f
670}
671
672; Verifies we fixed PR20425. We should be able to promote all alloca's to
673; registers in this test.
674;
675; %0 = slice
676; %1 = slice
677; %2 = phi(%0, %1) // == slice
678define float @simplify_phi_nodes_that_equal_slice(i1 %cond, ptr %temp) {
679; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice(
680; CHECK-NEXT:  entry:
681; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
682; CHECK:       then:
683; CHECK-NEXT:    br label [[MERGE:%.*]]
684; CHECK:       else:
685; CHECK-NEXT:    br label [[MERGE]]
686; CHECK:       merge:
687; CHECK-NEXT:    [[ARR_SROA_0_0:%.*]] = phi float [ 1.000000e+00, [[THEN]] ], [ 2.000000e+00, [[ELSE]] ]
688; CHECK-NEXT:    store float 0.000000e+00, ptr [[TEMP:%.*]], align 4
689; CHECK-NEXT:    ret float [[ARR_SROA_0_0]]
690;
691entry:
692  %arr = alloca [4 x float], align 4
693  br i1 %cond, label %then, label %else
694
695then:
696  %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3
697  store float 1.000000e+00, ptr %0, align 4
698  br label %merge
699
700else:
701  %1 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3
702  store float 2.000000e+00, ptr %1, align 4
703  br label %merge
704
705merge:
706  %2 = phi ptr [ %0, %then ], [ %1, %else ]
707  store float 0.000000e+00, ptr %temp, align 4
708  %3 = load float, ptr %2, align 4
709  ret float %3
710}
711
712; A slightly complicated example for PR20425.
713;
714; %0 = slice
715; %1 = phi(%0) // == slice
716; %2 = slice
717; %3 = phi(%1, %2) // == slice
718define float @simplify_phi_nodes_that_equal_slice_2(i1 %cond, ptr %temp) {
719; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice_2(
720; CHECK-NEXT:  entry:
721; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
722; CHECK:       then:
723; CHECK-NEXT:    br label [[THEN2:%.*]]
724; CHECK:       then2:
725; CHECK-NEXT:    br label [[MERGE:%.*]]
726; CHECK:       else:
727; CHECK-NEXT:    br label [[MERGE]]
728; CHECK:       merge:
729; CHECK-NEXT:    [[ARR_SROA_0_0:%.*]] = phi float [ 2.000000e+00, [[THEN2]] ], [ 3.000000e+00, [[ELSE]] ]
730; CHECK-NEXT:    store float 0.000000e+00, ptr [[TEMP:%.*]], align 4
731; CHECK-NEXT:    ret float [[ARR_SROA_0_0]]
732;
733entry:
734  %arr = alloca [4 x float], align 4
735  br i1 %cond, label %then, label %else
736
737then:
738  %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3
739  store float 1.000000e+00, ptr %0, align 4
740  br label %then2
741
742then2:
743  %1 = phi ptr [ %0, %then ]
744  store float 2.000000e+00, ptr %1, align 4
745  br label %merge
746
747else:
748  %2 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3
749  store float 3.000000e+00, ptr %2, align 4
750  br label %merge
751
752merge:
753  %3 = phi ptr [ %1, %then2 ], [ %2, %else ]
754  store float 0.000000e+00, ptr %temp, align 4
755  %4 = load float, ptr %3, align 4
756  ret float %4
757}
758
759%struct.S = type { i32 }
760
761; Verifies we fixed PR20822. We have a foldable PHI feeding a speculatable PHI
762; which requires the rewriting of the speculated PHI to handle insertion
763; when the incoming pointer is itself from a PHI node. We would previously
764; insert a bitcast instruction *before* a PHI, producing an invalid module;
765; make sure we insert *after* the first non-PHI instruction.
766define void @PR20822(i1 %c1, i1 %c2, ptr %ptr) {
767; CHECK-LABEL: @PR20822(
768; CHECK-NEXT:  entry:
769; CHECK-NEXT:    [[F_SROA_0:%.*]] = alloca i32, align 4
770; CHECK-NEXT:    [[F1_SROA_GEP:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[PTR:%.*]], i32 0, i32 0
771; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF_END:%.*]], label [[FOR_COND:%.*]]
772; CHECK:       for.cond:
773; CHECK-NEXT:    br label [[IF_END]]
774; CHECK:       if.end:
775; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ poison, [[FOR_COND]] ]
776; CHECK-NEXT:    br i1 [[C2:%.*]], label [[IF_THEN5:%.*]], label [[IF_THEN2:%.*]]
777; CHECK:       if.then2:
778; CHECK-NEXT:    br label [[IF_THEN5]]
779; CHECK:       if.then5:
780; CHECK-NEXT:    [[F1_SROA_PHI:%.*]] = phi ptr [ [[F1_SROA_GEP]], [[IF_THEN2]] ], [ [[F_SROA_0]], [[IF_END]] ]
781; CHECK-NEXT:    store i32 0, ptr [[F1_SROA_PHI]], align 4
782; CHECK-NEXT:    ret void
783;
784entry:
785  %f = alloca %struct.S, align 4
786  br i1 %c1, label %if.end, label %for.cond
787
788for.cond:                                         ; preds = %for.cond, %entry
789  br label %if.end
790
791if.end:                                           ; preds = %for.cond, %entry
792  %f2 = phi ptr [ %f, %entry ], [ %f, %for.cond ]
793  phi i32 [ poison, %entry ], [ poison, %for.cond ]
794  br i1 %c2, label %if.then5, label %if.then2
795
796if.then2:                                         ; preds = %if.end
797  br label %if.then5
798
799if.then5:                                         ; preds = %if.then2, %if.end
800  %f1 = phi ptr [ %ptr, %if.then2 ], [ %f2, %if.end ]
801  store %struct.S zeroinitializer, ptr %f1, align 4
802  ret void
803}
804
805define i32 @phi_align(ptr %z) {
806; CHECK-LABEL: @phi_align(
807; CHECK-NEXT:  entry:
808; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca [7 x i8], align 1
809; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3
810; CHECK-NEXT:    store i32 0, ptr [[A_SROA_0]], align 1
811; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3
812; CHECK-NEXT:    store i32 1, ptr [[A_SROA_0_3_A1X_SROA_IDX3]], align 1
813; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_1_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 1
814; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX4:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3
815; CHECK-NEXT:    [[A_SROA_0_3_A_SROA_0_4_V1:%.*]] = load i32, ptr [[A_SROA_0_3_A1X_SROA_IDX4]], align 1
816; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 [[A_SROA_0_0_A_SROA_0_1_V0]], [[A_SROA_0_3_A_SROA_0_4_V1]]
817; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[EXIT:%.*]]
818; CHECK:       then:
819; CHECK-NEXT:    br label [[EXIT]]
820; CHECK:       exit:
821; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0_3_A1X_SROA_IDX]], [[THEN]] ], [ [[Z:%.*]], [[ENTRY:%.*]] ]
822; CHECK-NEXT:    [[RESULT:%.*]] = load i32, ptr [[PHI]], align 1
823; CHECK-NEXT:    ret i32 [[RESULT]]
824;
825entry:
826  %a = alloca [8 x i8], align 8
827
828  %a0x = getelementptr [8 x i8], ptr %a, i64 0, i32 1
829  %a1x = getelementptr [8 x i8], ptr %a, i64 0, i32 4
830  store i32 0, ptr %a0x, align 1
831  store i32 1, ptr %a1x, align 4
832  %v0 = load i32, ptr %a0x, align 1
833  %v1 = load i32, ptr %a1x, align 4
834  %cond = icmp sle i32 %v0, %v1
835  br i1 %cond, label %then, label %exit
836
837then:
838  br label %exit
839
840exit:
841  %phi = phi ptr [ %a1x, %then ], [ %z, %entry ]
842  %result = load i32, ptr %phi, align 4
843  ret i32 %result
844}
845
846; Don't speculate a load based on an earlier volatile operation.
847define i8 @volatile_select(ptr %p, i1 %b) {
848; CHECK-PRESERVE-CFG-LABEL: @volatile_select(
849; CHECK-PRESERVE-CFG-NEXT:    [[P2:%.*]] = alloca i8, align 1
850; CHECK-PRESERVE-CFG-NEXT:    store i8 0, ptr [[P2]], align 1
851; CHECK-PRESERVE-CFG-NEXT:    store volatile i8 0, ptr [[P:%.*]], align 1
852; CHECK-PRESERVE-CFG-NEXT:    [[PX:%.*]] = select i1 [[B:%.*]], ptr [[P]], ptr [[P2]]
853; CHECK-PRESERVE-CFG-NEXT:    [[V2:%.*]] = load i8, ptr [[PX]], align 1
854; CHECK-PRESERVE-CFG-NEXT:    ret i8 [[V2]]
855;
856; CHECK-MODIFY-CFG-LABEL: @volatile_select(
857; CHECK-MODIFY-CFG-NEXT:    store volatile i8 0, ptr [[P:%.*]], align 1
858; CHECK-MODIFY-CFG-NEXT:    br i1 [[B:%.*]], label [[DOTTHEN:%.*]], label [[DOTCONT:%.*]]
859; CHECK-MODIFY-CFG:       .then:
860; CHECK-MODIFY-CFG-NEXT:    [[V2_THEN_VAL:%.*]] = load i8, ptr [[P]], align 1
861; CHECK-MODIFY-CFG-NEXT:    br label [[DOTCONT]]
862; CHECK-MODIFY-CFG:       .cont:
863; CHECK-MODIFY-CFG-NEXT:    [[V2:%.*]] = phi i8 [ [[V2_THEN_VAL]], [[DOTTHEN]] ], [ 0, [[TMP0:%.*]] ]
864; CHECK-MODIFY-CFG-NEXT:    ret i8 [[V2]]
865;
866  %p2 = alloca i8
867  store i8 0, ptr %p2
868  store volatile i8 0, ptr %p
869  %px = select i1 %b, ptr %p, ptr %p2
870  %v2 = load i8, ptr %px
871  ret i8 %v2
872}
873