[AMDGPU] Add True16 register classes.
[llvm-project.git] / llvm / test / Transforms / GVN / PRE / pre-loop-load-through-select.ll
blobdc128a4b1e63176a169288590e228994b540eaa4
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(
6 ; CHECK-NEXT:  entry:
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:%.*]]
10 ; CHECK:       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]]
21 ; CHECK:       exit:
22 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
23 ; CHECK-NEXT:    ret i32 [[RES]]
25 entry:
26   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
27   br label %loop
29 loop:
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
40 exit:
41   %res = load i32, ptr %min.select, align 4
42   ret i32 %res
45 define i32 @test_pointer_phi_select_same_object_lcssa(ptr %ptr, ptr %end)  {
46 ; CHECK-LABEL: @test_pointer_phi_select_same_object_lcssa(
47 ; CHECK-NEXT:  entry:
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:%.*]]
51 ; CHECK:       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]]
62 ; CHECK:       exit:
63 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
64 ; CHECK-NEXT:    ret i32 [[RES]]
66 entry:
67   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
68   br label %loop
70 loop:
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
81 exit:
82   %lcssa.min = phi ptr [ %min.select, %loop ]
83   %res = load i32, ptr %lcssa.min, align 4
84   ret i32 %res
87 define i32 @test_pointer_phi_select_different_objects(ptr %A, ptr %B, ptr %end)  {
88 ; CHECK-LABEL: @test_pointer_phi_select_different_objects(
89 ; CHECK-NEXT:  entry:
90 ; CHECK-NEXT:    [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4
91 ; CHECK-NEXT:    br label [[LOOP:%.*]]
92 ; CHECK:       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]]
103 ; CHECK:       exit:
104 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
105 ; CHECK-NEXT:    ret i32 [[RES]]
107 entry:
108   br label %loop
110 loop:
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
121 exit:
122   %res = load i32, ptr %min.select, align 4
123   ret i32 %res
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(
128 ; CHECK-NEXT:  entry:
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:%.*]]
132 ; CHECK:       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]]
143 ; CHECK:       exit:
144 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
145 ; CHECK-NEXT:    ret i32 [[RES]]
147 entry:
148   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
149   br label %loop
151 loop:
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
163 exit:
164   %res = load i32, ptr %min.select, align 4
165   ret i32 %res
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(
170 ; CHECK-NEXT:  entry:
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:%.*]]
174 ; CHECK:       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]]
185 ; CHECK:       exit:
186 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
187 ; CHECK-NEXT:    ret i32 [[RES]]
189 entry:
190   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
191   br label %loop
193 loop:
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
205 exit:
206   %res = load i32, ptr %min.select, align 4
207   ret i32 %res
210 define i32 @test_pointer_phi_select_load_after(ptr %A, ptr %B, ptr %end)  {
211 ; CHECK-LABEL: @test_pointer_phi_select_load_after(
212 ; CHECK-NEXT:  entry:
213 ; CHECK-NEXT:    [[L_2_PRE:%.*]] = load i32, ptr [[B:%.*]], align 4
214 ; CHECK-NEXT:    br label [[LOOP:%.*]]
215 ; CHECK:       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]]
226 ; CHECK:       exit:
227 ; CHECK-NEXT:    ret i32 [[L_3]]
229 entry:
230   br label %loop
232 loop:
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
244 exit:
245   %res = load i32, ptr %min.select, align 4
246   ret i32 %res
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(
251 ; CHECK-NEXT:  entry:
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:%.*]]
257 ; CHECK:       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]]
268 ; CHECK:       loop.exit:
269 ; CHECK-NEXT:    br label [[EXIT]]
270 ; CHECK:       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]]
275 entry:
276   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
277   br i1 %c, label %exit, label %loop
279 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
290 loop.exit:
291   %lcssa.phi.1 = phi ptr [ %min.select, %loop ]
292   br label %exit
294 exit:
295   %lcssa.phi.2 = phi ptr [ %end, %entry ], [ %lcssa.phi.1, %loop.exit ]
296   %res = load i32, ptr %lcssa.phi.2, align 4
297   ret i32 %res
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(
305 ; CHECK-NEXT:  entry:
306 ; CHECK-NEXT:    br label [[LOOP:%.*]]
307 ; CHECK:       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]]
319 ; CHECK:       exit:
320 ; CHECK-NEXT:    ret i32 [[TMP0]]
322 entry:
323   br label %loop
325 loop:
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
337 exit:
338   %res = load i32, ptr %min.select, align 4
339   ret i32 %res
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(
344 ; CHECK-NEXT:  entry:
345 ; CHECK-NEXT:    br label [[LOOP:%.*]]
346 ; CHECK:       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]]
358 ; CHECK:       exit:
359 ; CHECK-NEXT:    ret i32 [[TMP0]]
361 entry:
362   br label %loop
364 loop:
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
376 exit:
377   %res = load i32, ptr %min.select, align 4
378   ret i32 %res
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(
383 ; CHECK-NEXT:  entry:
384 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
385 ; CHECK-NEXT:    br label [[LOOP:%.*]]
386 ; CHECK:       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]]
396 ; CHECK:       exit:
397 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
398 ; CHECK-NEXT:    ret i32 [[RES]]
400 entry:
401   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
402   br label %loop
404 loop:
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
416 exit:
417   %res = load i32, ptr %min.select, align 4
418   ret i32 %res
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(
423 ; CHECK-NEXT:  entry:
424 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
425 ; CHECK-NEXT:    br label [[LOOP:%.*]]
426 ; CHECK:       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]]
437 ; CHECK:       exit:
438 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
439 ; CHECK-NEXT:    ret i32 [[RES]]
441 entry:
442   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
443   br label %loop
445 loop:
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
457 exit:
458   %res = load i32, ptr %min.select, align 4
459   ret i32 %res
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(
464 ; CHECK-NEXT:  entry:
465 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
466 ; CHECK-NEXT:    br label [[LOOP:%.*]]
467 ; CHECK:       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]]
478 ; CHECK:       exit:
479 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
480 ; CHECK-NEXT:    ret i32 [[RES]]
482 entry:
483   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
484   br label %loop
486 loop:
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
498 exit:
499   %res = load i32, ptr %min.select, align 4
500   ret i32 %res
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(
507 ; CHECK-NEXT:  entry:
508 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
509 ; CHECK-NEXT:    br label [[LOOP:%.*]]
510 ; CHECK:       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]]
522 ; CHECK:       exit:
523 ; CHECK-NEXT:    ret i32 [[TMP0]]
525 entry:
526   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
527   br label %loop
529 loop:
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
541 exit:
542   %res = load i32, ptr %min.select, align 4
543   ret i32 %res
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(
548 ; CHECK-NEXT:  entry:
549 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
550 ; CHECK-NEXT:    br label [[LOOP:%.*]]
551 ; CHECK:       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]]
562 ; CHECK:       exit:
563 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
564 ; CHECK-NEXT:    ret i32 [[RES]]
566 entry:
567   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
568   br label %loop
570 loop:
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
582 exit:
583   %res = load i32, ptr %min.select, align 4
584   ret i32 %res
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(
589 ; CHECK-NEXT:  entry:
590 ; CHECK-NEXT:    [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
591 ; CHECK-NEXT:    br label [[LOOP:%.*]]
592 ; CHECK:       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]]
603 ; CHECK:       exit:
604 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
605 ; CHECK-NEXT:    ret i32 [[RES]]
607 entry:
608   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
609   br label %loop
611 loop:
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
623 exit:
624   %res = load i32, ptr %min.select, align 4
625   ret i32 %res
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(
630 ; CHECK-NEXT:  entry:
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]]
639 ; CHECK:       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]]
645 ; CHECK:       exit:
646 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_PTR]], align 4
647 ; CHECK-NEXT:    ret i32 [[RES]]
649 entry:
650   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
651   br label %loop.header
653 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
660 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
667 exit:
668   %res = load i32, ptr %min.ptr, align 4
669   ret i32 %res
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(
674 ; CHECK-NEXT:  entry:
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:%.*]]
678 ; CHECK:       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:%.*]]
691 ; CHECK:       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]]
697 entry:
698   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
699   br label %loop
701 loop:
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
712 exit:
713   %p = phi ptr [ %min.select, %loop ], [ %p.next, %exit ]
714   store i32 0, ptr %p
715   %p.next = getelementptr inbounds i32, ptr %p, i64 1
716   br label %exit
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(
721 ; CHECK-NEXT:  entry:
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:%.*]]
725 ; CHECK:       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]]
736 ; CHECK:       exit:
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]]
741 entry:
742   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
743   br label %loop
745 loop:
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
756 exit:
757   store i32 0, ptr %start.ptr
758   %res = load i32, ptr %min.select, align 4
759   ret i32 %res
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(
764 ; CHECK-NEXT:  entry:
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:%.*]]
768 ; CHECK:       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]]
779 ; CHECK:       exit.1:
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]]
784 entry:
785   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
786   br label %loop
788 loop:
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
799 exit.1:
800   %lcssa.min = phi ptr [ %min.select, %loop ]
801   store i32 0, ptr %start.ptr
802   br label %exit.2
804 exit.2:
805   %res = load i32, ptr %lcssa.min, align 4
806   ret i32 %res
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(
813 ; CHECK-NEXT:  entry:
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:%.*]]
817 ; CHECK:       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]]
828 ; CHECK:       exit.1:
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:%.*]]
832 ; CHECK:       exit.2:
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
840 entry:
841   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
842   br label %loop
844 loop:
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
855 exit.1:
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
861 exit.2:
862   %res = load i32, ptr %lcssa.min, align 4
863   ret i32 %res
865 catch.object:
866   %lp = landingpad { ptr, i32 }
867   catch ptr null
868   unreachable
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(
873 ; CHECK-NEXT:  entry:
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:%.*]]
877 ; CHECK:       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]]
888 ; CHECK:       exit:
889 ; CHECK-NEXT:    ret i32 [[L_3]]
891 entry:
892   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
893   br label %loop
895 loop:
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
907 exit:
908   %res = load i32, ptr %min.select, align 4
909   ret i32 %res
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(
914 ; CHECK-NEXT:  entry:
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:%.*]]
918 ; CHECK:       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]]
933 ; CHECK:       exit:
934 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
935 ; CHECK-NEXT:    ret i32 [[RES]]
937 entry:
938   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
939   br label %loop
941 loop:
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
953 exit:
954   %res = load i32, ptr %min.select, align 4
955   ret i32 %res
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(
960 ; CHECK-NEXT:  entry:
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:%.*]]
964 ; CHECK:       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]]
977 ; CHECK:       exit:
978 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
979 ; CHECK-NEXT:    ret i32 [[RES]]
981 entry:
982   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
983   br label %loop
985 loop:
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
998 exit:
999   %res = load i32, ptr %min.select, align 4
1000   ret i32 %res
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:%.*]]
1008 ; CHECK:       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]]
1017 ; CHECK:       exit:
1018 ; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
1019 ; CHECK-NEXT:    ret i32 [[RES]]
1021 entry:
1022   %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
1023   br label %loop
1025 loop:
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
1035 exit:
1036   %res = load i32, ptr %min.select, align 4
1037   ret i32 %res