1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes='require<domtree>,loop(loop-simplifycfg),gvn' -enable-split-backedge-in-load-pre -S %s | FileCheck %s
4 define i32 @test_pointer_phi_select_same_object(ptr %ptr, ptr %end) {
5 ; CHECK-LABEL: @test_pointer_phi_select_same_object(
7 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
8 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
12 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
13 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
14 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
15 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
16 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
17 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
18 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
19 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
20 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
22 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
23 ; CHECK-NEXT: ret i32 [[RES]]
26 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
30 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
31 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
32 %l.1 = load i32, ptr %ptr.iv, align 4
33 %l.2 = load i32, ptr %min.ptr, align 4
34 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
35 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
36 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
37 %ec = icmp eq ptr %ptr.iv.next, %end
38 br i1 %ec, label %exit, label %loop
41 %res = load i32, ptr %min.select, align 4
45 define i32 @test_pointer_phi_select_same_object_lcssa(ptr %ptr, ptr %end) {
46 ; CHECK-LABEL: @test_pointer_phi_select_same_object_lcssa(
48 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
49 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
50 ; CHECK-NEXT: br label [[LOOP:%.*]]
52 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
53 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
54 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
55 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
56 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
57 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
58 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
59 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
60 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
61 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
63 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
64 ; CHECK-NEXT: ret i32 [[RES]]
67 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
71 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
72 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
73 %l.1 = load i32, ptr %ptr.iv, align 4
74 %l.2 = load i32, ptr %min.ptr, align 4
75 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
76 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
77 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
78 %ec = icmp eq ptr %ptr.iv.next, %end
79 br i1 %ec, label %exit, label %loop
82 %lcssa.min = phi ptr [ %min.select, %loop ]
83 %res = load i32, ptr %lcssa.min, align 4
87 define i32 @test_pointer_phi_select_different_objects(ptr %A, ptr %B, ptr %end) {
88 ; CHECK-LABEL: @test_pointer_phi_select_different_objects(
90 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4
91 ; CHECK-NEXT: br label [[LOOP:%.*]]
93 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
94 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
95 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
96 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
97 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
98 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
99 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
100 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
101 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
102 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
104 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
105 ; CHECK-NEXT: ret i32 [[RES]]
111 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ]
112 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ]
113 %l.1 = load i32, ptr %ptr.iv, align 4
114 %l.2 = load i32, ptr %min.ptr, align 4
115 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
116 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
117 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
118 %ec = icmp eq ptr %ptr.iv.next, %end
119 br i1 %ec, label %exit, label %loop
122 %res = load i32, ptr %min.select, align 4
126 define i32 @test_pointer_phi_select_same_object_multiple_loads_1(ptr %ptr, ptr %end) {
127 ; CHECK-LABEL: @test_pointer_phi_select_same_object_multiple_loads_1(
129 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
130 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
131 ; CHECK-NEXT: br label [[LOOP:%.*]]
133 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
134 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
135 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
136 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
137 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
138 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
139 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
140 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
141 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
142 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
144 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
145 ; CHECK-NEXT: ret i32 [[RES]]
148 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
152 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
153 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
154 %l.1 = load i32, ptr %ptr.iv, align 4
155 %l.2 = load i32, ptr %min.ptr, align 4
156 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
157 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
158 %l.3 = load i32, ptr %min.ptr, align 4
159 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
160 %ec = icmp eq ptr %ptr.iv.next, %end
161 br i1 %ec, label %exit, label %loop
164 %res = load i32, ptr %min.select, align 4
168 define i32 @test_pointer_phi_select_same_object_multiple_loads_2(ptr %ptr, ptr %end) {
169 ; CHECK-LABEL: @test_pointer_phi_select_same_object_multiple_loads_2(
171 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
172 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
173 ; CHECK-NEXT: br label [[LOOP:%.*]]
175 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
176 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
177 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
178 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
179 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
180 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
181 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
182 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
183 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
184 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
186 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
187 ; CHECK-NEXT: ret i32 [[RES]]
190 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
194 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
195 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
196 %l.1 = load i32, ptr %ptr.iv, align 4
197 %l.2 = load i32, ptr %min.ptr, align 4
198 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
199 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
200 %l.3 = load i32, ptr %ptr.iv, align 4
201 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
202 %ec = icmp eq ptr %ptr.iv.next, %end
203 br i1 %ec, label %exit, label %loop
206 %res = load i32, ptr %min.select, align 4
210 define i32 @test_pointer_phi_select_load_after(ptr %A, ptr %B, ptr %end) {
211 ; CHECK-LABEL: @test_pointer_phi_select_load_after(
213 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4
214 ; CHECK-NEXT: br label [[LOOP:%.*]]
216 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3:%.*]], [[LOOP]] ]
217 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
218 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
219 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
220 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
221 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
222 ; CHECK-NEXT: [[L_3]] = load i32, ptr [[MIN_SELECT]], align 4
223 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]]
224 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
225 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
227 ; CHECK-NEXT: ret i32 [[L_3]]
233 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ]
234 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ]
235 %l.1 = load i32, ptr %ptr.iv, align 4
236 %l.2 = load i32, ptr %min.ptr, align 4
237 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
238 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
239 %l.3 = load i32, ptr %min.select, align 4
240 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3
241 %ec = icmp eq ptr %ptr.iv.next, %end
242 br i1 %ec, label %exit, label %loop
245 %res = load i32, ptr %min.select, align 4
249 define i32 @test_pointer_phi_select_same_object_split_edge(ptr %ptr, ptr %end, i1 %c) {
250 ; CHECK-LABEL: @test_pointer_phi_select_same_object_split_edge(
252 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
253 ; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
254 ; CHECK: loop.preheader:
255 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
256 ; CHECK-NEXT: br label [[LOOP:%.*]]
258 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[TMP0:%.*]], [[LOOP]] ], [ [[L_2_PRE]], [[LOOP_PREHEADER]] ]
259 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ], [ [[START_PTR]], [[LOOP_PREHEADER]] ]
260 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[MIN_SELECT:%.*]], [[LOOP]] ], [ [[PTR]], [[LOOP_PREHEADER]] ]
261 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
262 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
263 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
264 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
265 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
266 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
267 ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_EXIT:%.*]], label [[LOOP]]
269 ; CHECK-NEXT: br label [[EXIT]]
271 ; CHECK-NEXT: [[LCSSA_PHI_2:%.*]] = phi ptr [ [[END]], [[ENTRY:%.*]] ], [ [[MIN_SELECT]], [[LOOP_EXIT]] ]
272 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[LCSSA_PHI_2]], align 4
273 ; CHECK-NEXT: ret i32 [[RES]]
276 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
277 br i1 %c, label %exit, label %loop
280 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
281 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
282 %l.1 = load i32, ptr %ptr.iv, align 4
283 %l.2 = load i32, ptr %min.ptr, align 4
284 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
285 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
286 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
287 %ec = icmp eq ptr %ptr.iv.next, %end
288 br i1 %ec, label %loop.exit, label %loop
291 %lcssa.phi.1 = phi ptr [ %min.select, %loop ]
295 %lcssa.phi.2 = phi ptr [ %end, %entry ], [ %lcssa.phi.1, %loop.exit ]
296 %res = load i32, ptr %lcssa.phi.2, align 4
301 declare void @may_throw() readonly
303 define i32 @test_pointer_phi_select_load_may_not_execute_1(ptr %A, ptr %B, ptr %end) {
304 ; CHECK-LABEL: @test_pointer_phi_select_load_may_not_execute_1(
306 ; CHECK-NEXT: br label [[LOOP:%.*]]
308 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
309 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B:%.*]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
310 ; CHECK-NEXT: call void @may_throw()
311 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
312 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
313 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
314 ; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
315 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
316 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
317 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
318 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
320 ; CHECK-NEXT: ret i32 [[TMP0]]
326 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ]
327 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ]
328 call void @may_throw()
329 %l.1 = load i32, ptr %ptr.iv, align 4
330 %l.2 = load i32, ptr %min.ptr, align 4
331 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
332 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
333 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
334 %ec = icmp eq ptr %ptr.iv.next, %end
335 br i1 %ec, label %exit, label %loop
338 %res = load i32, ptr %min.select, align 4
342 define i32 @test_pointer_phi_select_load_may_not_execute_2(ptr %A, ptr %B, ptr %end) {
343 ; CHECK-LABEL: @test_pointer_phi_select_load_may_not_execute_2(
345 ; CHECK-NEXT: br label [[LOOP:%.*]]
347 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
348 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[B:%.*]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
349 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
350 ; CHECK-NEXT: call void @may_throw()
351 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
352 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
353 ; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
354 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
355 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
356 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
357 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
359 ; CHECK-NEXT: ret i32 [[TMP0]]
365 %ptr.iv = phi ptr [ %A, %entry ], [ %ptr.iv.next, %loop ]
366 %min.ptr = phi ptr [ %B, %entry ], [ %min.select, %loop ]
367 %l.1 = load i32, ptr %ptr.iv, align 4
368 call void @may_throw()
369 %l.2 = load i32, ptr %min.ptr, align 4
370 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
371 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
372 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
373 %ec = icmp eq ptr %ptr.iv.next, %end
374 br i1 %ec, label %exit, label %loop
377 %res = load i32, ptr %min.select, align 4
381 define i32 @test_pointer_phi_select_same_object_store_1(ptr %ptr, ptr %end) {
382 ; CHECK-LABEL: @test_pointer_phi_select_same_object_store_1(
384 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
385 ; CHECK-NEXT: br label [[LOOP:%.*]]
387 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
388 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
389 ; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4
390 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
391 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], 3
392 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
393 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
394 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
395 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
397 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
398 ; CHECK-NEXT: ret i32 [[RES]]
401 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
405 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
406 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
407 store i32 3, ptr %min.ptr
408 %l.1 = load i32, ptr %ptr.iv, align 4
409 %l.2 = load i32, ptr %min.ptr, align 4
410 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
411 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
412 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
413 %ec = icmp eq ptr %ptr.iv.next, %end
414 br i1 %ec, label %exit, label %loop
417 %res = load i32, ptr %min.select, align 4
421 define i32 @test_pointer_phi_select_same_object_store_2(ptr %ptr, ptr %end) {
422 ; CHECK-LABEL: @test_pointer_phi_select_same_object_store_2(
424 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
425 ; CHECK-NEXT: br label [[LOOP:%.*]]
427 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
428 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
429 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
430 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
431 ; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4
432 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
433 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
434 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
435 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
436 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
438 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
439 ; CHECK-NEXT: ret i32 [[RES]]
442 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
446 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
447 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
448 %l.1 = load i32, ptr %ptr.iv, align 4
449 %l.2 = load i32, ptr %min.ptr, align 4
450 store i32 3, ptr %min.ptr
451 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
452 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
453 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
454 %ec = icmp eq ptr %ptr.iv.next, %end
455 br i1 %ec, label %exit, label %loop
458 %res = load i32, ptr %min.select, align 4
462 define i32 @test_pointer_phi_select_same_object_store_3(ptr %ptr, ptr %end) {
463 ; CHECK-LABEL: @test_pointer_phi_select_same_object_store_3(
465 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
466 ; CHECK-NEXT: br label [[LOOP:%.*]]
468 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
469 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
470 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
471 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
472 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
473 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
474 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
475 ; CHECK-NEXT: store i32 3, ptr [[MIN_PTR]], align 4
476 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
477 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
479 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
480 ; CHECK-NEXT: ret i32 [[RES]]
483 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
487 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
488 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
489 %l.1 = load i32, ptr %ptr.iv, align 4
490 %l.2 = load i32, ptr %min.ptr, align 4
491 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
492 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
493 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
494 store i32 3, ptr %min.ptr
495 %ec = icmp eq ptr %ptr.iv.next, %end
496 br i1 %ec, label %exit, label %loop
499 %res = load i32, ptr %min.select, align 4
503 declare void @may_write()
505 define i32 @test_pointer_phi_select_same_object_may_write_call_1(ptr %ptr, ptr %end) {
506 ; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_1(
508 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
509 ; CHECK-NEXT: br label [[LOOP:%.*]]
511 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
512 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
513 ; CHECK-NEXT: call void @may_write()
514 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
515 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
516 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
517 ; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
518 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
519 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
520 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
521 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
523 ; CHECK-NEXT: ret i32 [[TMP0]]
526 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
530 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
531 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
532 call void @may_write()
533 %l.1 = load i32, ptr %ptr.iv, align 4
534 %l.2 = load i32, ptr %min.ptr, align 4
535 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
536 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
537 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
538 %ec = icmp eq ptr %ptr.iv.next, %end
539 br i1 %ec, label %exit, label %loop
542 %res = load i32, ptr %min.select, align 4
546 define i32 @test_pointer_phi_select_same_object_may_write_call_2(ptr %ptr, ptr %end) {
547 ; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_2(
549 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
550 ; CHECK-NEXT: br label [[LOOP:%.*]]
552 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
553 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
554 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
555 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
556 ; CHECK-NEXT: call void @may_write()
557 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
558 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
559 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
560 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
561 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
563 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
564 ; CHECK-NEXT: ret i32 [[RES]]
567 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
571 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
572 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
573 %l.1 = load i32, ptr %ptr.iv, align 4
574 %l.2 = load i32, ptr %min.ptr, align 4
575 call void @may_write()
576 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
577 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
578 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
579 %ec = icmp eq ptr %ptr.iv.next, %end
580 br i1 %ec, label %exit, label %loop
583 %res = load i32, ptr %min.select, align 4
587 define i32 @test_pointer_phi_select_same_object_may_write_call_3(ptr %ptr, ptr %end) {
588 ; CHECK-LABEL: @test_pointer_phi_select_same_object_may_write_call_3(
590 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
591 ; CHECK-NEXT: br label [[LOOP:%.*]]
593 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
594 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
595 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
596 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
597 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
598 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
599 ; CHECK-NEXT: call void @may_write()
600 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
601 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
602 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
604 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
605 ; CHECK-NEXT: ret i32 [[RES]]
608 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
612 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
613 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
614 %l.1 = load i32, ptr %ptr.iv, align 4
615 %l.2 = load i32, ptr %min.ptr, align 4
616 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
617 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
618 call void @may_write()
619 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
620 %ec = icmp eq ptr %ptr.iv.next, %end
621 br i1 %ec, label %exit, label %loop
624 %res = load i32, ptr %min.select, align 4
628 define i32 @test_pointer_phi_select_same_object_header_exit(ptr %ptr, ptr %end) {
629 ; CHECK-LABEL: @test_pointer_phi_select_same_object_header_exit(
631 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
632 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
633 ; CHECK: loop.header:
634 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
635 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP_LATCH]] ]
636 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
637 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
638 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
640 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
641 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
642 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
643 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
644 ; CHECK-NEXT: br label [[LOOP_HEADER]]
646 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_PTR]], align 4
647 ; CHECK-NEXT: ret i32 [[RES]]
650 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
651 br label %loop.header
654 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop.latch ]
655 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop.latch ]
656 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
657 %ec = icmp eq ptr %ptr.iv.next, %end
658 br i1 %ec, label %exit, label %loop.latch
661 %l.1 = load i32, ptr %ptr.iv, align 4
662 %l.2 = load i32, ptr %min.ptr, align 4
663 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
664 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
665 br label %loop.header
668 %res = load i32, ptr %min.ptr, align 4
672 define i32 @test_pointer_phi_select_same_object_ptr_use_cycle(ptr %ptr, ptr %end) {
673 ; CHECK-LABEL: @test_pointer_phi_select_same_object_ptr_use_cycle(
675 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
676 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
677 ; CHECK-NEXT: br label [[LOOP:%.*]]
679 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
680 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
681 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
682 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
683 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
684 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
685 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
686 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
687 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
688 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT_PREHEADER:%.*]], label [[LOOP]]
689 ; CHECK: exit.preheader:
690 ; CHECK-NEXT: br label [[EXIT:%.*]]
692 ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[P_NEXT:%.*]], [[EXIT]] ], [ [[MIN_SELECT]], [[EXIT_PREHEADER]] ]
693 ; CHECK-NEXT: store i32 0, ptr [[P]], align 4
694 ; CHECK-NEXT: [[P_NEXT]] = getelementptr inbounds i32, ptr [[P]], i64 1
695 ; CHECK-NEXT: br label [[EXIT]]
698 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
702 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
703 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
704 %l.1 = load i32, ptr %ptr.iv, align 4
705 %l.2 = load i32, ptr %min.ptr, align 4
706 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
707 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
708 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
709 %ec = icmp eq ptr %ptr.iv.next, %end
710 br i1 %ec, label %exit, label %loop
713 %p = phi ptr [ %min.select, %loop ], [ %p.next, %exit ]
715 %p.next = getelementptr inbounds i32, ptr %p, i64 1
719 define i32 @test_pointer_phi_select_same_object_maybe_clobbered_in_exit(ptr %ptr, ptr %end) {
720 ; CHECK-LABEL: @test_pointer_phi_select_same_object_maybe_clobbered_in_exit(
722 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
723 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
724 ; CHECK-NEXT: br label [[LOOP:%.*]]
726 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
727 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
728 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
729 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
730 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
731 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
732 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
733 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
734 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
735 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
737 ; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4
738 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
739 ; CHECK-NEXT: ret i32 [[RES]]
742 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
746 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
747 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
748 %l.1 = load i32, ptr %ptr.iv, align 4
749 %l.2 = load i32, ptr %min.ptr, align 4
750 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
751 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
752 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
753 %ec = icmp eq ptr %ptr.iv.next, %end
754 br i1 %ec, label %exit, label %loop
757 store i32 0, ptr %start.ptr
758 %res = load i32, ptr %min.select, align 4
762 define i32 @test_pointer_phi_select_same_object_maybe_clobbered_in_exit_2(ptr %ptr, ptr %end) {
763 ; CHECK-LABEL: @test_pointer_phi_select_same_object_maybe_clobbered_in_exit_2(
765 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
766 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
767 ; CHECK-NEXT: br label [[LOOP:%.*]]
769 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
770 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
771 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
772 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
773 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
774 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
775 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
776 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
777 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
778 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]]
780 ; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4
781 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
782 ; CHECK-NEXT: ret i32 [[RES]]
785 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
789 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
790 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
791 %l.1 = load i32, ptr %ptr.iv, align 4
792 %l.2 = load i32, ptr %min.ptr, align 4
793 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
794 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
795 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
796 %ec = icmp eq ptr %ptr.iv.next, %end
797 br i1 %ec, label %exit.1, label %loop
800 %lcssa.min = phi ptr [ %min.select, %loop ]
801 store i32 0, ptr %start.ptr
805 %res = load i32, ptr %lcssa.min, align 4
809 declare i32 @__CxxFrameHandler3(...)
811 define i32 @test_pointer_phi_select_same_object_invoke_in_chain(ptr %ptr, ptr %end) personality ptr @__CxxFrameHandler3 {
812 ; CHECK-LABEL: @test_pointer_phi_select_same_object_invoke_in_chain(
814 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
815 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
816 ; CHECK-NEXT: br label [[LOOP:%.*]]
818 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
819 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
820 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
821 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
822 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
823 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
824 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
825 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
826 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
827 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]]
829 ; CHECK-NEXT: store i32 0, ptr [[START_PTR]], align 4
830 ; CHECK-NEXT: invoke void @may_throw()
831 ; CHECK-NEXT: to label [[EXIT_2:%.*]] unwind label [[CATCH_OBJECT:%.*]]
833 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
834 ; CHECK-NEXT: ret i32 [[RES]]
835 ; CHECK: catch.object:
836 ; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
837 ; CHECK-NEXT: catch ptr null
838 ; CHECK-NEXT: unreachable
841 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
845 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
846 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
847 %l.1 = load i32, ptr %ptr.iv, align 4
848 %l.2 = load i32, ptr %min.ptr, align 4
849 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
850 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
851 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
852 %ec = icmp eq ptr %ptr.iv.next, %end
853 br i1 %ec, label %exit.1, label %loop
856 %lcssa.min = phi ptr [ %min.select, %loop ]
857 store i32 0, ptr %start.ptr
858 invoke void @may_throw()
859 to label %exit.2 unwind label %catch.object
862 %res = load i32, ptr %lcssa.min, align 4
866 %lp = landingpad { ptr, i32 }
871 define i32 @test_pointer_phi_select_used_by_others_in_loop(ptr %ptr, ptr %end) {
872 ; CHECK-LABEL: @test_pointer_phi_select_used_by_others_in_loop(
874 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
875 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
876 ; CHECK-NEXT: br label [[LOOP:%.*]]
878 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3:%.*]], [[LOOP]] ]
879 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
880 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
881 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
882 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
883 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
884 ; CHECK-NEXT: [[L_3]] = load i32, ptr [[MIN_SELECT]], align 4
885 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]]
886 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
887 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
889 ; CHECK-NEXT: ret i32 [[L_3]]
892 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
896 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
897 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
898 %l.1 = load i32, ptr %ptr.iv, align 4
899 %l.2 = load i32, ptr %min.ptr, align 4
900 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
901 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
902 %l.3 = load i32, ptr %min.select, align 4
903 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3
904 %ec = icmp eq ptr %ptr.iv.next, %end
905 br i1 %ec, label %exit, label %loop
908 %res = load i32, ptr %min.select, align 4
912 define i32 @test_pointer_phi_used_by_others_in_loop_1(ptr %ptr, ptr %end) {
913 ; CHECK-LABEL: @test_pointer_phi_used_by_others_in_loop_1(
915 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
916 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
917 ; CHECK-NEXT: br label [[LOOP:%.*]]
919 ; CHECK-NEXT: [[L_3:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[L_3_PRE:%.*]], [[LOOP_LOOP_CRIT_EDGE:%.*]] ]
920 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY]] ], [ [[TMP0:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ]
921 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ]
922 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP_LOOP_CRIT_EDGE]] ]
923 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
924 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
925 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
926 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
927 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]]
928 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
929 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_LOOP_CRIT_EDGE]]
930 ; CHECK: loop.loop_crit_edge:
931 ; CHECK-NEXT: [[L_3_PRE]] = load i32, ptr [[MIN_SELECT]], align 4
932 ; CHECK-NEXT: br label [[LOOP]]
934 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
935 ; CHECK-NEXT: ret i32 [[RES]]
938 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
942 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
943 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
944 %l.1 = load i32, ptr %ptr.iv, align 4
945 %l.2 = load i32, ptr %min.ptr, align 4
946 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
947 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
948 %l.3 = load i32, ptr %min.ptr, align 4
949 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3
950 %ec = icmp eq ptr %ptr.iv.next, %end
951 br i1 %ec, label %exit, label %loop
954 %res = load i32, ptr %min.select, align 4
958 define i32 @test_pointer_phi_used_by_others_in_loop_2(ptr %ptr, ptr %end) {
959 ; CHECK-LABEL: @test_pointer_phi_used_by_others_in_loop_2(
961 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
962 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
963 ; CHECK-NEXT: br label [[LOOP:%.*]]
965 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[TMP0:%.*]], [[LOOP]] ]
966 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
967 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
968 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
969 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
970 ; CHECK-NEXT: [[TMP0]] = select i1 [[CMP_I_I_I]], i32 [[L_1]], i32 [[L_2]]
971 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
972 ; CHECK-NEXT: [[GEP_MIN_PTR:%.*]] = getelementptr inbounds i32, ptr [[MIN_PTR]], i32 1
973 ; CHECK-NEXT: [[L_3:%.*]] = load i32, ptr [[GEP_MIN_PTR]], align 4
974 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i32 [[L_3]]
975 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
976 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
978 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
979 ; CHECK-NEXT: ret i32 [[RES]]
982 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
986 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
987 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
988 %l.1 = load i32, ptr %ptr.iv, align 4
989 %l.2 = load i32, ptr %min.ptr, align 4
990 %cmp.i.i.i = icmp ult i32 %l.1, %l.2
991 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
992 %gep.min.ptr = getelementptr inbounds i32, ptr %min.ptr, i32 1
993 %l.3 = load i32, ptr %gep.min.ptr, align 4
994 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i32 %l.3
995 %ec = icmp eq ptr %ptr.iv.next, %end
996 br i1 %ec, label %exit, label %loop
999 %res = load i32, ptr %min.select, align 4
1003 define i32 @test_pointer_phi_select_no_iter_load(ptr %ptr, ptr %end) {
1004 ; CHECK-LABEL: @test_pointer_phi_select_no_iter_load(
1005 ; CHECK-NEXT: entry:
1006 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
1007 ; CHECK-NEXT: br label [[LOOP:%.*]]
1009 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
1010 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
1011 ; CHECK-NEXT: [[L_2:%.*]] = load i32, ptr [[MIN_PTR]], align 4
1012 ; CHECK-NEXT: [[CMP_I_I_I:%.*]] = icmp ult i32 10, [[L_2]]
1013 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_I_I_I]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
1014 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
1015 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
1016 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
1018 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
1019 ; CHECK-NEXT: ret i32 [[RES]]
1022 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
1026 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
1027 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
1028 %l.2 = load i32, ptr %min.ptr, align 4
1029 %cmp.i.i.i = icmp ult i32 10, %l.2
1030 %min.select = select i1 %cmp.i.i.i, ptr %ptr.iv, ptr %min.ptr
1031 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
1032 %ec = icmp eq ptr %ptr.iv.next, %end
1033 br i1 %ec, label %exit, label %loop
1036 %res = load i32, ptr %min.select, align 4