xref: /llvm-project/llvm/test/Transforms/GVN/PRE/pre-load-through-select.ll (revision 1aece0e5edf8d4fef1b5e226825a245dce5c382e)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='require<domtree>,loop(loop-simplifycfg),gvn' -S %s | FileCheck %s
3
4define i32 @test_pointer_phi_select_simp_1(ptr %a, ptr %b, i1 %cond)  {
5; CHECK-LABEL: @test_pointer_phi_select_simp_1(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
8; CHECK:       then:
9; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
10; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
11; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
12; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
13; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
14; CHECK-NEXT:    br label [[EXIT:%.*]]
15; CHECK:       else:
16; CHECK-NEXT:    [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4
17; CHECK-NEXT:    br label [[EXIT]]
18; CHECK:       exit:
19; CHECK-NEXT:    [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ]
20; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
21; CHECK-NEXT:    ret i32 [[RES_2]]
22;
23entry:
24  br i1 %cond, label %then, label %else
25
26then:
27  %l.1 = load i32, ptr %a, align 4
28  %l.2 = load i32, ptr %b, align 4
29  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
30  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
31  br label %exit
32
33else:
34  br label %exit
35
36exit:
37  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
38  %res.2 = load i32, ptr %p, align 4
39  ret i32 %res.2
40}
41
42define i32 @test_pointer_phi_select_simp_non_local(ptr %a, ptr %b, ptr %c)  {
43; CHECK-LABEL: @test_pointer_phi_select_simp_non_local(
44; CHECK-NEXT:  entry:
45; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
46; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[L_1]], 0
47; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[ELSE:%.*]]
48; CHECK:       then:
49; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
50; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
51; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
52; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
53; CHECK-NEXT:    br label [[EXIT:%.*]]
54; CHECK:       else:
55; CHECK-NEXT:    [[RES_2_PRE:%.*]] = load i32, ptr [[C:%.*]], align 4
56; CHECK-NEXT:    br label [[EXIT]]
57; CHECK:       exit:
58; CHECK-NEXT:    [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ]
59; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[C]], [[ELSE]] ]
60; CHECK-NEXT:    ret i32 [[RES_2]]
61;
62entry:
63  %l.1 = load i32, ptr %a, align 4
64  %cond = icmp sgt i32 %l.1, 0
65  br i1 %cond, label %then, label %else
66
67then:
68  %l.2 = load i32, ptr %b, align 4
69  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
70  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
71  br label %exit
72
73else:
74  br label %exit
75
76exit:
77  %p = phi ptr [ %min.select, %then ], [ %c, %else ]
78  %res.2 = load i32, ptr %p, align 4
79  ret i32 %res.2
80}
81
82define i32 @test_pointer_phi_select_simp_non_local_mismatched_type(ptr %a, ptr %b, ptr %c)  {
83; CHECK-LABEL: @test_pointer_phi_select_simp_non_local_mismatched_type(
84; CHECK-NEXT:  entry:
85; CHECK-NEXT:    [[L_1:%.*]] = load float, ptr [[A:%.*]], align 4
86; CHECK-NEXT:    [[CONV:%.*]] = fptosi float [[L_1]] to i32
87; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[CONV]], 0
88; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[ELSE:%.*]]
89; CHECK:       then:
90; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
91; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[CONV]], [[L_2]]
92; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
93; CHECK-NEXT:    br label [[EXIT:%.*]]
94; CHECK:       else:
95; CHECK-NEXT:    br label [[EXIT]]
96; CHECK:       exit:
97; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[C:%.*]], [[ELSE]] ]
98; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
99; CHECK-NEXT:    ret i32 [[RES_2]]
100;
101entry:
102  %l.1 = load float, ptr %a, align 4
103  %conv = fptosi float %l.1 to i32
104  %cond = icmp sgt i32 %conv, 0
105  br i1 %cond, label %then, label %else
106
107then:
108  %l.2 = load i32, ptr %b, align 4
109  %cmp.i.i.i = icmp ult i32 %conv, %l.2
110  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
111  br label %exit
112
113else:
114  br label %exit
115
116exit:
117  %p = phi ptr [ %min.select, %then ], [ %c, %else ]
118  %res.2 = load i32, ptr %p, align 4
119  ret i32 %res.2
120}
121
122define i32 @test_pointer_phi_select_simp_no_load_for_select_op_1(ptr %a, ptr %b, ptr %c, i1 %cond)  {
123; CHECK-LABEL: @test_pointer_phi_select_simp_no_load_for_select_op_1(
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
126; CHECK:       then:
127; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[C:%.*]], align 4
128; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
129; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
130; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A:%.*]], ptr [[B]]
131; CHECK-NEXT:    br label [[EXIT:%.*]]
132; CHECK:       else:
133; CHECK-NEXT:    br label [[EXIT]]
134; CHECK:       exit:
135; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
136; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
137; CHECK-NEXT:    ret i32 [[RES_2]]
138;
139entry:
140  br i1 %cond, label %then, label %else
141
142then:
143  %l.1 = load i32, ptr %c, align 4
144  %l.2 = load i32, ptr %b, align 4
145  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
146  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
147  br label %exit
148
149else:
150  br label %exit
151
152exit:
153  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
154  %res.2 = load i32, ptr %p, align 4
155  ret i32 %res.2
156}
157
158define i32 @test_pointer_phi_select_simp_no_load_for_select_op_2(ptr %a, ptr %b, ptr %c, i1 %cond)  {
159; CHECK-LABEL: @test_pointer_phi_select_simp_no_load_for_select_op_2(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
162; CHECK:       then:
163; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
164; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[C:%.*]], align 4
165; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
166; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B:%.*]]
167; CHECK-NEXT:    br label [[EXIT:%.*]]
168; CHECK:       else:
169; CHECK-NEXT:    br label [[EXIT]]
170; CHECK:       exit:
171; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
172; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
173; CHECK-NEXT:    ret i32 [[RES_2]]
174;
175entry:
176  br i1 %cond, label %then, label %else
177
178then:
179  %l.1 = load i32, ptr %a, align 4
180  %l.2 = load i32, ptr %c, align 4
181  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
182  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
183  br label %exit
184
185else:
186  br label %exit
187
188exit:
189  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
190  %res.2 = load i32, ptr %p, align 4
191  ret i32 %res.2
192}
193
194define i32 @test_pointer_phi_select_simp_store_noclobber(ptr %a, ptr %b, ptr noalias %c, i1 %cond)  {
195; CHECK-LABEL: @test_pointer_phi_select_simp_store_noclobber(
196; CHECK-NEXT:  entry:
197; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
198; CHECK:       then:
199; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
200; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
201; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
202; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
203; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
204; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
205; CHECK-NEXT:    br label [[EXIT:%.*]]
206; CHECK:       else:
207; CHECK-NEXT:    [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4
208; CHECK-NEXT:    br label [[EXIT]]
209; CHECK:       exit:
210; CHECK-NEXT:    [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ]
211; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
212; CHECK-NEXT:    ret i32 [[RES_2]]
213;
214entry:
215  br i1 %cond, label %then, label %else
216
217then:
218  %l.1 = load i32, ptr %a, align 4
219  %l.2 = load i32, ptr %b, align 4
220  store i32 99, ptr %c
221  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
222  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
223  br label %exit
224
225else:
226  br label %exit
227
228exit:
229  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
230  %res.2 = load i32, ptr %p, align 4
231  ret i32 %res.2
232}
233
234define i32 @test_pointer_phi_select_simp_store_clobber_1(ptr %a, ptr %b, ptr %c, i1 %cond)  {
235; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_1(
236; CHECK-NEXT:  entry:
237; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
238; CHECK:       then:
239; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
240; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
241; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
242; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
243; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
244; CHECK-NEXT:    br label [[EXIT:%.*]]
245; CHECK:       else:
246; CHECK-NEXT:    br label [[EXIT]]
247; CHECK:       exit:
248; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
249; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
250; CHECK-NEXT:    ret i32 [[RES_2]]
251;
252entry:
253  br i1 %cond, label %then, label %else
254
255then:
256  %l.1 = load i32, ptr %a, align 4
257  %l.2 = load i32, ptr %b, align 4
258  store i32 99, ptr %c
259  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
260  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
261  br label %exit
262
263else:
264  br label %exit
265
266exit:
267  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
268  %res.2 = load i32, ptr %p, align 4
269  ret i32 %res.2
270}
271
272define i32 @test_pointer_phi_select_simp_store_clobber_2(ptr %a, ptr %b, ptr %c, i1 %cond)  {
273; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_2(
274; CHECK-NEXT:  entry:
275; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
276; CHECK:       then:
277; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
278; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
279; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
280; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
281; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
282; CHECK-NEXT:    br label [[EXIT:%.*]]
283; CHECK:       else:
284; CHECK-NEXT:    br label [[EXIT]]
285; CHECK:       exit:
286; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
287; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
288; CHECK-NEXT:    ret i32 [[RES_2]]
289;
290entry:
291  br i1 %cond, label %then, label %else
292
293then:
294  %l.1 = load i32, ptr %a, align 4
295  store i32 99, ptr %c
296  %l.2 = load i32, ptr %b, align 4
297  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
298  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
299  br label %exit
300
301else:
302  br label %exit
303
304exit:
305  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
306  %res.2 = load i32, ptr %p, align 4
307  ret i32 %res.2
308}
309
310define i32 @test_pointer_phi_select_simp_store_clobber_3(ptr %a, ptr %b, ptr %c, i1 %cond)  {
311; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_3(
312; CHECK-NEXT:  entry:
313; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
314; CHECK:       then:
315; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
316; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
317; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
318; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
319; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
320; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
321; CHECK-NEXT:    br label [[EXIT:%.*]]
322; CHECK:       else:
323; CHECK-NEXT:    [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4
324; CHECK-NEXT:    br label [[EXIT]]
325; CHECK:       exit:
326; CHECK-NEXT:    [[RES_2:%.*]] = phi i32 [ [[TMP0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ]
327; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
328; CHECK-NEXT:    ret i32 [[RES_2]]
329;
330entry:
331  br i1 %cond, label %then, label %else
332
333then:
334  store i32 99, ptr %c
335  %l.1 = load i32, ptr %a, align 4
336  %l.2 = load i32, ptr %b, align 4
337  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
338  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
339  br label %exit
340
341else:
342  br label %exit
343
344exit:
345  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
346  %res.2 = load i32, ptr %p, align 4
347  ret i32 %res.2
348}
349
350define i32 @test_pointer_phi_select_simp_store_clobber_4(ptr %a, ptr %b, ptr %c, i1 %cond)  {
351; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_4(
352; CHECK-NEXT:  entry:
353; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
354; CHECK:       then:
355; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
356; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
357; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
358; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
359; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
360; CHECK-NEXT:    br label [[EXIT:%.*]]
361; CHECK:       else:
362; CHECK-NEXT:    br label [[EXIT]]
363; CHECK:       exit:
364; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
365; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
366; CHECK-NEXT:    ret i32 [[RES_2]]
367;
368entry:
369  br i1 %cond, label %then, label %else
370
371then:
372  %l.1 = load i32, ptr %a, align 4
373  %l.2 = load i32, ptr %b, align 4
374  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
375  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
376  store i32 99, ptr %c
377  br label %exit
378
379else:
380  br label %exit
381
382exit:
383  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
384  %res.2 = load i32, ptr %p, align 4
385  ret i32 %res.2
386}
387
388define i32 @test_pointer_phi_select_simp_store_clobber_5(ptr %a, ptr %b, ptr %c, i1 %cond)  {
389; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_5(
390; CHECK-NEXT:  entry:
391; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
392; CHECK:       then:
393; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
394; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
395; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
396; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
397; CHECK-NEXT:    br label [[EXIT:%.*]]
398; CHECK:       else:
399; CHECK-NEXT:    br label [[EXIT]]
400; CHECK:       exit:
401; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
402; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
403; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
404; CHECK-NEXT:    ret i32 [[RES_2]]
405;
406entry:
407  br i1 %cond, label %then, label %else
408
409then:
410  %l.1 = load i32, ptr %a, align 4
411  %l.2 = load i32, ptr %b, align 4
412  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
413  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
414  br label %exit
415
416else:
417  br label %exit
418
419exit:
420  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
421  store i32 99, ptr %c
422  %res.2 = load i32, ptr %p, align 4
423  ret i32 %res.2
424}
425
426define i32 @test_pointer_phi_select_simp_store_clobber_6(ptr %a, ptr %b, ptr %c, i1 %cond)  {
427; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_6(
428; CHECK-NEXT:  entry:
429; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
430; CHECK:       then:
431; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
432; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
433; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
434; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
435; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
436; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
437; CHECK-NEXT:    br label [[EXIT:%.*]]
438; CHECK:       else:
439; CHECK-NEXT:    [[RES_2_PRE:%.*]] = load i32, ptr [[A]], align 4
440; CHECK-NEXT:    br label [[EXIT]]
441; CHECK:       exit:
442; CHECK-NEXT:    [[RES_2:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ [[RES_2_PRE]], [[ELSE]] ]
443; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
444; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ]
445; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
446; CHECK-NEXT:    ret i32 [[RES_2]]
447;
448entry:
449  br i1 %cond, label %then, label %else
450
451then:
452  %l.1 = load i32, ptr %a, align 4
453  %l.2 = load i32, ptr %b, align 4
454  store i32 99, ptr %c
455  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
456  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
457  %res.0 = load i32, ptr %min.select, align 4
458  br label %exit
459
460else:
461  br label %exit
462
463exit:
464  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
465  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
466  %res.2 = load i32, ptr %p, align 4
467  %add = add i32 %res.2, %v
468  ret i32 %res.2
469}
470
471define i32 @test_pointer_phi_select_simp_store_clobber_7(ptr %a, ptr %b, ptr %c, i1 %cond)  {
472; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_7(
473; CHECK-NEXT:  entry:
474; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
475; CHECK:       then:
476; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
477; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
478; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
479; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
480; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
481; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[A]], align 4
482; CHECK-NEXT:    br label [[EXIT:%.*]]
483; CHECK:       else:
484; CHECK-NEXT:    br label [[EXIT]]
485; CHECK:       exit:
486; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
487; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ]
488; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
489; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
490; CHECK-NEXT:    ret i32 [[RES_2]]
491;
492entry:
493  br i1 %cond, label %then, label %else
494
495then:
496  %l.1 = load i32, ptr %a, align 4
497  %l.2 = load i32, ptr %b, align 4
498  store i32 99, ptr %c
499  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
500  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
501  %res.0 = load i32, ptr %a, align 4
502  br label %exit
503
504else:
505  br label %exit
506
507exit:
508  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
509  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
510  %res.2 = load i32, ptr %p, align 4
511  %add = add i32 %res.2, %v
512  ret i32 %res.2
513}
514
515define i32 @test_pointer_phi_select_simp_store_clobber_8(ptr %a, ptr %b, ptr %c, i1 %cond)  {
516; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_8(
517; CHECK-NEXT:  entry:
518; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
519; CHECK:       then:
520; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
521; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
522; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
523; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
524; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
525; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[B]], align 4
526; CHECK-NEXT:    br label [[EXIT:%.*]]
527; CHECK:       else:
528; CHECK-NEXT:    br label [[EXIT]]
529; CHECK:       exit:
530; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
531; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ]
532; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
533; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
534; CHECK-NEXT:    ret i32 [[RES_2]]
535;
536entry:
537  br i1 %cond, label %then, label %else
538
539then:
540  %l.1 = load i32, ptr %a, align 4
541  %l.2 = load i32, ptr %b, align 4
542  store i32 99, ptr %c
543  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
544  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
545  %res.0 = load i32, ptr %b, align 4
546  br label %exit
547
548else:
549  br label %exit
550
551exit:
552  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
553  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
554  %res.2 = load i32, ptr %p, align 4
555  %add = add i32 %res.2, %v
556  ret i32 %res.2
557}
558
559define i32 @test_pointer_phi_select_simp_store_clobber_9(ptr %a, ptr %b, i1 %cond)  {
560; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_9(
561; CHECK-NEXT:  entry:
562; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
563; CHECK:       then:
564; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
565; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
566; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
567; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
568; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
569; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[B]], align 4
570; CHECK-NEXT:    br label [[EXIT:%.*]]
571; CHECK:       else:
572; CHECK-NEXT:    br label [[EXIT]]
573; CHECK:       exit:
574; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
575; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[RES_0]], [[THEN]] ], [ 10, [[ELSE]] ]
576; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
577; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
578; CHECK-NEXT:    ret i32 [[RES_2]]
579;
580entry:
581  br i1 %cond, label %then, label %else
582
583then:
584  %l.1 = load i32, ptr %a, align 4
585  %l.2 = load i32, ptr %b, align 4
586  store i32 99, ptr %a
587  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
588  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
589  %res.0 = load i32, ptr %b, align 4
590  br label %exit
591
592else:
593  br label %exit
594
595exit:
596  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
597  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
598  %res.2 = load i32, ptr %p, align 4
599  %add = add i32 %res.2, %v
600  ret i32 %res.2
601}
602
603define i32 @test_pointer_phi_select_simp_store_clobber_10(ptr %a, ptr %b, i1 %cond)  {
604; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_10(
605; CHECK-NEXT:  entry:
606; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
607; CHECK:       then:
608; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
609; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
610; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
611; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
612; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
613; CHECK-NEXT:    br label [[EXIT:%.*]]
614; CHECK:       else:
615; CHECK-NEXT:    br label [[EXIT]]
616; CHECK:       exit:
617; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
618; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[L_2]], [[THEN]] ], [ 10, [[ELSE]] ]
619; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
620; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
621; CHECK-NEXT:    ret i32 [[RES_2]]
622;
623entry:
624  br i1 %cond, label %then, label %else
625
626then:
627  %l.1 = load i32, ptr %a, align 4
628  store i32 99, ptr %a
629  %l.2 = load i32, ptr %b, align 4
630  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
631  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
632  %res.0 = load i32, ptr %b, align 4
633  br label %exit
634
635else:
636  br label %exit
637
638exit:
639  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
640  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
641  %res.2 = load i32, ptr %p, align 4
642  %add = add i32 %res.2, %v
643  ret i32 %res.2
644}
645
646define i32 @test_pointer_phi_select_simp_store_clobber_11(ptr %a, ptr %b, i1 %cond)  {
647; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_11(
648; CHECK-NEXT:  entry:
649; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
650; CHECK:       then:
651; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
652; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
653; CHECK-NEXT:    store i32 99, ptr [[B]], align 4
654; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
655; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
656; CHECK-NEXT:    br label [[EXIT:%.*]]
657; CHECK:       else:
658; CHECK-NEXT:    br label [[EXIT]]
659; CHECK:       exit:
660; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
661; CHECK-NEXT:    [[V:%.*]] = phi i32 [ 99, [[THEN]] ], [ 10, [[ELSE]] ]
662; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
663; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
664; CHECK-NEXT:    ret i32 [[RES_2]]
665;
666entry:
667  br i1 %cond, label %then, label %else
668
669then:
670  %l.1 = load i32, ptr %a, align 4
671  %l.2 = load i32, ptr %b, align 4
672  store i32 99, ptr %b
673  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
674  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
675  %res.0 = load i32, ptr %b, align 4
676  br label %exit
677
678else:
679  br label %exit
680
681exit:
682  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
683  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
684  %res.2 = load i32, ptr %p, align 4
685  %add = add i32 %res.2, %v
686  ret i32 %res.2
687}
688
689define i32 @test_pointer_phi_select_simp_store_clobber_12(ptr %a, ptr %b, i1 %cond)  {
690; CHECK-LABEL: @test_pointer_phi_select_simp_store_clobber_12(
691; CHECK-NEXT:  entry:
692; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
693; CHECK:       then:
694; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
695; CHECK-NEXT:    store i32 99, ptr [[B:%.*]], align 4
696; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], 99
697; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
698; CHECK-NEXT:    br label [[EXIT:%.*]]
699; CHECK:       else:
700; CHECK-NEXT:    br label [[EXIT]]
701; CHECK:       exit:
702; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[MIN_SELECT]], [[THEN]] ], [ [[A]], [[ELSE]] ]
703; CHECK-NEXT:    [[V:%.*]] = phi i32 [ 99, [[THEN]] ], [ 10, [[ELSE]] ]
704; CHECK-NEXT:    [[RES_2:%.*]] = load i32, ptr [[P]], align 4
705; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[RES_2]], [[V]]
706; CHECK-NEXT:    ret i32 [[RES_2]]
707;
708entry:
709  br i1 %cond, label %then, label %else
710
711then:
712  %l.1 = load i32, ptr %a, align 4
713  store i32 99, ptr %b
714  %l.2 = load i32, ptr %b, align 4
715  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
716  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
717  %res.0 = load i32, ptr %b, align 4
718  br label %exit
719
720else:
721  br label %exit
722
723exit:
724  %p = phi ptr [ %min.select, %then ], [ %a, %else ]
725  %v = phi i32 [ %res.0, %then ], [ 10, %else ]
726  %res.2 = load i32, ptr %p, align 4
727  %add = add i32 %res.2, %v
728  ret i32 %res.2
729}
730
731define i32 @test_pointer_phi_select_single_block_store(ptr %a, ptr %b)  {
732; CHECK-LABEL: @test_pointer_phi_select_single_block_store(
733; CHECK-NEXT:  entry:
734; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
735; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
736; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
737; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
738; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
739; CHECK-NEXT:    ret i32 [[TMP0]]
740;
741entry:
742  %l.1 = load i32, ptr %a, align 4
743  %l.2 = load i32, ptr %b, align 4
744  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
745  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
746  %res.0 = load i32, ptr %min.select, align 4
747  ret i32 %res.0
748}
749
750define i32 @test_pointer_phi_select_single_block_store_clobber_1(ptr %a, ptr %b, ptr %c)  {
751; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_1(
752; CHECK-NEXT:  entry:
753; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
754; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
755; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
756; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
757; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
758; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
759; CHECK-NEXT:    ret i32 [[RES_0]]
760;
761entry:
762  %l.1 = load i32, ptr %a, align 4
763  %l.2 = load i32, ptr %b, align 4
764  store i32 99, ptr %c
765  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
766  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
767  %res.0 = load i32, ptr %min.select, align 4
768  ret i32 %res.0
769}
770
771define i32 @test_pointer_phi_select_single_block_store_clobber_2(ptr %a, ptr %b, ptr %c)  {
772; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_2(
773; CHECK-NEXT:  entry:
774; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
775; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
776; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
777; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
778; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
779; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
780; CHECK-NEXT:    ret i32 [[RES_0]]
781;
782entry:
783  %l.1 = load i32, ptr %a, align 4
784  %l.2 = load i32, ptr %b, align 4
785  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
786  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
787  store i32 99, ptr %c
788  %res.0 = load i32, ptr %min.select, align 4
789  ret i32 %res.0
790}
791
792define i32 @test_pointer_phi_select_single_block_store_clobber_3(ptr %a, ptr %b, ptr %c)  {
793; CHECK-LABEL: @test_pointer_phi_select_single_block_store_clobber_3(
794; CHECK-NEXT:  entry:
795; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
796; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
797; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
798; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
799; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
800; CHECK-NEXT:    [[RES_0:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
801; CHECK-NEXT:    ret i32 [[RES_0]]
802;
803entry:
804  %l.1 = load i32, ptr %a, align 4
805  store i32 99, ptr %c
806  %l.2 = load i32, ptr %b, align 4
807  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
808  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
809  %res.0 = load i32, ptr %min.select, align 4
810  ret i32 %res.0
811}
812
813define i32 @test_pointer_phi_select_single_block_store_after(ptr %a, ptr %b, ptr %c)  {
814; CHECK-LABEL: @test_pointer_phi_select_single_block_store_after(
815; CHECK-NEXT:  entry:
816; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[A:%.*]], align 4
817; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[B:%.*]], align 4
818; CHECK-NEXT:    [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
819; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
820; CHECK-NEXT:    [[MIN_SELECT:%.*]] = select i1 [[CMP_I_I_I]], ptr [[A]], ptr [[B]]
821; CHECK-NEXT:    store i32 99, ptr [[C:%.*]], align 4
822; CHECK-NEXT:    ret i32 [[TMP0]]
823;
824entry:
825  %l.1 = load i32, ptr %a, align 4
826  %l.2 = load i32, ptr %b, align 4
827  %cmp.i.i.i = icmp ult i32 %l.1, %l.2
828  %min.select  = select i1 %cmp.i.i.i, ptr %a, ptr %b
829  %res.0 = load i32, ptr %min.select, align 4
830  store i32 99, ptr %c
831  ret i32 %res.0
832}
833
834define i32 @test_phi_select_index_non_local(ptr %A, i32 %N, i32 %i)  {
835; CHECK-LABEL: @test_phi_select_index_non_local(
836; CHECK-NEXT:  entry:
837; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
838; CHECK-NEXT:    br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END:%.*]]
839; CHECK:       land.lhs.true:
840; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[I]] to i64
841; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM]]
842; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
843; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[I]], 1
844; CHECK-NEXT:    [[IDXPROM1:%.*]] = sext i32 [[ADD]] to i64
845; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM1]]
846; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
847; CHECK-NEXT:    [[CMP3:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
848; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP3]], i32 [[ADD]], i32 [[I]]
849; CHECK-NEXT:    br label [[IF_END]]
850; CHECK:       if.end:
851; CHECK-NEXT:    [[I_ADDR_0:%.*]] = phi i32 [ [[I]], [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[LAND_LHS_TRUE]] ]
852; CHECK-NEXT:    [[IDXPROM5:%.*]] = sext i32 [[I_ADDR_0]] to i64
853; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM5]]
854; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4
855; CHECK-NEXT:    ret i32 [[TMP2]]
856;
857entry:
858  %cmp = icmp slt i32 %i, %N
859  br i1 %cmp, label %land.lhs.true, label %if.end
860
861land.lhs.true:
862  %idxprom = sext i32 %i to i64
863  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom
864  %0 = load i32, ptr %arrayidx, align 4
865  %add = add nsw i32 %i, 1
866  %idxprom1 = sext i32 %add to i64
867  %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %idxprom1
868  %1 = load i32, ptr %arrayidx2, align 4
869  %cmp3 = icmp slt i32 %0, %1
870  %spec.select = select i1 %cmp3, i32 %add, i32 %i
871  br label %if.end
872
873if.end:
874  %i.addr.0 = phi i32 [ %i, %entry ], [ %spec.select, %land.lhs.true ]
875  %idxprom5 = sext i32 %i.addr.0 to i64
876  %arrayidx6 = getelementptr inbounds i32, ptr %A, i64 %idxprom5
877  %2 = load i32, ptr %arrayidx6, align 4
878  ret i32 %2
879}
880
881define i32 @test_phi_select_index_loop(ptr %A, i32 %N)  {
882; CHECK-LABEL: @test_phi_select_index_loop(
883; CHECK-NEXT:  entry:
884; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], 1
885; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
886; CHECK:       for.body.preheader:
887; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
888; CHECK:       for.body:
889; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[FOR_BODY]] ], [ 1, [[FOR_BODY_PREHEADER]] ]
890; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[SPEC_SELECT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
891; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64
892; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM]]
893; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
894; CHECK-NEXT:    [[IDXPROM1:%.*]] = sext i32 [[RES]] to i64
895; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IDXPROM1]]
896; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
897; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
898; CHECK-NEXT:    [[SPEC_SELECT]] = select i1 [[CMP1]], i32 [[IDX]], i32 [[RES]]
899; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], 1
900; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IDX_NEXT]], [[N]]
901; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]
902; CHECK:       for.cond.cleanup.loopexit:
903; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
904; CHECK:       for.cond.cleanup:
905; CHECK-NEXT:    [[RES_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[FOR_COND_CLEANUP_LOOPEXIT]] ]
906; CHECK-NEXT:    ret i32 [[RES_0_LCSSA]]
907;
908entry:
909  %cmp = icmp sgt i32 %N, 1
910  br i1 %cmp, label %for.body, label %for.cond.cleanup
911
912for.body:
913  %idx = phi i32 [ 1, %entry ], [ %idx.next, %for.body ]
914  %res = phi i32 [ 0, %entry ], [ %spec.select, %for.body ]
915  %idxprom = sext i32 %idx to i64
916  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom
917  %0 = load i32, ptr %arrayidx, align 4
918  %idxprom1 = sext i32 %res to i64
919  %arrayidx1 = getelementptr inbounds i32, ptr %A, i64 %idxprom1
920  %1 = load i32, ptr %arrayidx1, align 4
921  %cmp1 = icmp slt i32 %0, %1
922  %spec.select = select i1 %cmp1, i32 %idx, i32 %res
923  %idx.next = add nsw i32 %idx, 1
924  %exitcond.not = icmp eq i32 %idx.next, %N
925  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
926
927  for.cond.cleanup:
928  %res.0.lcssa = phi i32 [ 0, %entry ], [ %spec.select, %for.body ]
929  ret i32 %res.0.lcssa
930}
931