1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes='gvn' -S %s | FileCheck %s
4 define i32 @load_of_ptr_select_can_be_replaced_by_value_select(ptr %ptr, ptr %end) {
5 ; CHECK-LABEL: @load_of_ptr_select_can_be_replaced_by_value_select(
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:%.*]] ], [ [[MIN_VAL:%.*]], [[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_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
16 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
17 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], 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
27 %l.2.pre = load i32, ptr %ptr, align 4
31 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
32 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
33 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
34 %l.1 = load i32, ptr %ptr.iv, align 4
35 %cmp.1 = icmp ult i32 %l.1, %l.2
36 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
37 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
38 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
39 %ec = icmp eq ptr %ptr.iv.next, %end
40 br i1 %ec, label %exit, label %loop
43 %res = load i32, ptr %min.select, align 4
47 define i32 @different_phis_1(ptr %ptr, ptr %end) {
48 ; CHECK-LABEL: @different_phis_1(
50 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
51 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
52 ; CHECK-NEXT: br label [[LOOP:%.*]]
54 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
55 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
56 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ null, [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
57 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
58 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
59 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
60 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
61 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
62 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
63 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
65 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
66 ; CHECK-NEXT: ret i32 [[RES]]
69 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
70 %l.2.pre = load i32, ptr %ptr, align 4
74 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
75 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
76 %min.ptr = phi ptr [ null, %entry ], [ %min.select, %loop ]
77 %l.1 = load i32, ptr %ptr.iv, align 4
78 %cmp.1 = icmp ult i32 %l.1, %l.2
79 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
80 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
81 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
82 %ec = icmp eq ptr %ptr.iv.next, %end
83 br i1 %ec, label %exit, label %loop
86 %res = load i32, ptr %min.select, align 4
90 define i32 @different_phi_2(ptr %ptr, ptr %end) {
91 ; CHECK-LABEL: @different_phi_2(
93 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
94 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
95 ; CHECK-NEXT: br label [[LOOP:%.*]]
97 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
98 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
99 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[START_PTR]], [[LOOP]] ]
100 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
101 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
102 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
103 ; CHECK-NEXT: [[MIN_SELECT:%.*]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
104 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
105 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
106 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
108 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
109 ; CHECK-NEXT: ret i32 [[RES]]
112 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
113 %l.2.pre = load i32, ptr %ptr, align 4
117 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
118 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
119 %min.ptr = phi ptr [ %ptr, %entry ], [ %start.ptr, %loop ]
120 %l.1 = load i32, ptr %ptr.iv, align 4
121 %cmp.1 = icmp ult i32 %l.1, %l.2
122 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
123 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
124 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
125 %ec = icmp eq ptr %ptr.iv.next, %end
126 br i1 %ec, label %exit, label %loop
129 %res = load i32, ptr %min.select, align 4
133 define i32 @different_phis_3(ptr %ptr, ptr %end) {
134 ; CHECK-LABEL: @different_phis_3(
136 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
137 ; CHECK-NEXT: br label [[LOOP:%.*]]
139 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ 19, [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
140 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
141 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
142 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
143 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
144 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
145 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
146 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
147 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
148 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
150 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
151 ; CHECK-NEXT: ret i32 [[RES]]
154 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
158 %l.2 = phi i32 [ 19, %entry ], [ %min.val, %loop ]
159 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
160 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
161 %l.1 = load i32, ptr %ptr.iv, align 4
162 %cmp.1 = icmp ult i32 %l.1, %l.2
163 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
164 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
165 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
166 %ec = icmp eq ptr %ptr.iv.next, %end
167 br i1 %ec, label %exit, label %loop
170 %res = load i32, ptr %min.select, align 4
174 define i32 @different_phis_4(ptr %ptr, ptr %end) {
175 ; CHECK-LABEL: @different_phis_4(
177 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
178 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
179 ; CHECK-NEXT: br label [[LOOP:%.*]]
181 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ 10, [[LOOP]] ]
182 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
183 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
184 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
185 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
186 ; CHECK-NEXT: [[MIN_VAL:%.*]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
187 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
188 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
189 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
190 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
192 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
193 ; CHECK-NEXT: ret i32 [[RES]]
196 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
197 %l.2.pre = load i32, ptr %ptr, align 4
201 %l.2 = phi i32 [ %l.2.pre, %entry ], [ 10, %loop ]
202 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
203 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
204 %l.1 = load i32, ptr %ptr.iv, align 4
205 %cmp.1 = icmp ult i32 %l.1, %l.2
206 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
207 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
208 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
209 %ec = icmp eq ptr %ptr.iv.next, %end
210 br i1 %ec, label %exit, label %loop
213 %res = load i32, ptr %min.select, align 4
217 define i32 @load_before_loop_in_different_block(ptr %ptr, ptr %end, i1 %c) {
218 ; CHECK-LABEL: @load_before_loop_in_different_block(
220 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
221 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
222 ; CHECK-NEXT: br i1 [[C:%.*]], label [[PH:%.*]], label [[EXIT_2:%.*]]
224 ; CHECK-NEXT: br label [[LOOP:%.*]]
226 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[PH]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
227 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
228 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[PH]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
229 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
230 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
231 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
232 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
233 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
234 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
235 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
237 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
238 ; CHECK-NEXT: ret i32 [[RES]]
240 ; CHECK-NEXT: ret i32 0
243 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
244 %l.2.pre = load i32, ptr %ptr, align 4
245 br i1 %c, label %ph, label %exit.2
251 %l.2 = phi i32 [ %l.2.pre, %ph ], [ %min.val, %loop ]
252 %ptr.iv = phi ptr [ %start.ptr, %ph ], [ %ptr.iv.next, %loop ]
253 %min.ptr = phi ptr [ %ptr, %ph ], [ %min.select, %loop ]
254 %l.1 = load i32, ptr %ptr.iv, align 4
255 %cmp.1 = icmp ult i32 %l.1, %l.2
256 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
257 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
258 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
259 %ec = icmp eq ptr %ptr.iv.next, %end
260 br i1 %ec, label %exit, label %loop
263 %res = load i32, ptr %min.select, align 4
270 define i32 @selects_use_different_compares(ptr %ptr, ptr %end) {
271 ; CHECK-LABEL: @selects_use_different_compares(
273 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
274 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
275 ; CHECK-NEXT: br label [[LOOP:%.*]]
277 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
278 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
279 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
280 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
281 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
282 ; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[L_1]], 10
283 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_2]], i32 [[L_1]], i32 [[L_2]]
284 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
285 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
286 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
287 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
289 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
290 ; CHECK-NEXT: ret i32 [[RES]]
293 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
294 %l.2.pre = load i32, ptr %ptr, align 4
298 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
299 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
300 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
301 %l.1 = load i32, ptr %ptr.iv, align 4
302 %cmp.1 = icmp ult i32 %l.1, %l.2
303 %cmp.2 = icmp ult i32 %l.1, 10
304 %min.val = select i1 %cmp.2, i32 %l.1, i32 %l.2
305 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
306 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
307 %ec = icmp eq ptr %ptr.iv.next, %end
308 br i1 %ec, label %exit, label %loop
311 %res = load i32, ptr %min.select, align 4
316 define i32 @value_select_different_value_1(ptr %ptr, ptr %end) {
317 ; CHECK-LABEL: @value_select_different_value_1(
319 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
320 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
321 ; CHECK-NEXT: br label [[LOOP:%.*]]
323 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
324 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
325 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
326 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
327 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
328 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 10
329 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
330 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
331 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
332 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
334 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
335 ; CHECK-NEXT: ret i32 [[RES]]
338 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
339 %l.2.pre = load i32, ptr %ptr, align 4
343 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
344 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
345 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
346 %l.1 = load i32, ptr %ptr.iv, align 4
347 %cmp.1 = icmp ult i32 %l.1, %l.2
348 %min.val = select i1 %cmp.1, i32 %l.1, i32 10
349 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
350 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
351 %ec = icmp eq ptr %ptr.iv.next, %end
352 br i1 %ec, label %exit, label %loop
355 %res = load i32, ptr %min.select, align 4
359 define i32 @value_select_different_value_2(ptr %ptr, ptr %end, ptr %ptr.2) {
360 ; CHECK-LABEL: @value_select_different_value_2(
362 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
363 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
364 ; CHECK-NEXT: [[L_1_PRE:%.*]] = load i32, ptr [[PTR_2:%.*]], align 4
365 ; CHECK-NEXT: br label [[LOOP:%.*]]
367 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
368 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
369 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
370 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1_PRE]], [[L_2]]
371 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1_PRE]], i32 [[L_2]]
372 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
373 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
374 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
375 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
377 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
378 ; CHECK-NEXT: ret i32 [[RES]]
381 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
382 %l.2.pre = load i32, ptr %ptr, align 4
386 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
387 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
388 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
389 %l.1 = load i32, ptr %ptr.2, align 4
390 %cmp.1 = icmp ult i32 %l.1, %l.2
391 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
392 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
393 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
394 %ec = icmp eq ptr %ptr.iv.next, %end
395 br i1 %ec, label %exit, label %loop
398 %res = load i32, ptr %min.select, align 4
402 define i32 @pointer_select_clobbered_1(ptr %ptr, ptr %end) {
403 ; CHECK-LABEL: @pointer_select_clobbered_1(
405 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
406 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
407 ; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4
408 ; CHECK-NEXT: br label [[LOOP:%.*]]
410 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
411 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
412 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
413 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
414 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
415 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
416 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
417 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
418 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
419 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
421 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
422 ; CHECK-NEXT: ret i32 [[RES]]
425 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
426 %l.2.pre = load i32, ptr %ptr, align 4
427 store i32 99, ptr %ptr
431 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
432 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
433 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
434 %l.1 = load i32, ptr %ptr.iv, align 4
435 %cmp.1 = icmp ult i32 %l.1, %l.2
436 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
437 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
438 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
439 %ec = icmp eq ptr %ptr.iv.next, %end
440 br i1 %ec, label %exit, label %loop
443 %res = load i32, ptr %min.select, align 4
447 define i32 @pointer_select_clobbered_in_loop(ptr %ptr, ptr %end) {
448 ; CHECK-LABEL: @pointer_select_clobbered_in_loop(
450 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
451 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
452 ; CHECK-NEXT: br label [[LOOP:%.*]]
454 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
455 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
456 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
457 ; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4
458 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
459 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
460 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
461 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
462 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
463 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
464 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
466 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
467 ; CHECK-NEXT: ret i32 [[RES]]
470 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
471 %l.2.pre = load i32, ptr %ptr, align 4
475 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
476 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
477 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
478 store i32 99, ptr %ptr
479 %l.1 = load i32, ptr %ptr.iv, align 4
480 %cmp.1 = icmp ult i32 %l.1, %l.2
481 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
482 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
483 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
484 %ec = icmp eq ptr %ptr.iv.next, %end
485 br i1 %ec, label %exit, label %loop
488 %res = load i32, ptr %min.select, align 4
492 define i32 @pointer_select_clobbered_in_loop_2(ptr %ptr, ptr %end) {
493 ; CHECK-LABEL: @pointer_select_clobbered_in_loop_2(
495 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
496 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
497 ; CHECK-NEXT: br label [[LOOP:%.*]]
499 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
500 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
501 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
502 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
503 ; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4
504 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
505 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
506 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
507 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
508 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
509 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
511 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
512 ; CHECK-NEXT: ret i32 [[RES]]
515 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
516 %l.2.pre = load i32, ptr %ptr, align 4
520 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
521 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
522 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
523 %l.1 = load i32, ptr %ptr.iv, align 4
524 store i32 99, ptr %ptr
525 %cmp.1 = icmp ult i32 %l.1, %l.2
526 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
527 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
528 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
529 %ec = icmp eq ptr %ptr.iv.next, %end
530 br i1 %ec, label %exit, label %loop
533 %res = load i32, ptr %min.select, align 4
537 define i32 @pointer_select_clobbered_in_loop_3(ptr %ptr, ptr %end) {
538 ; CHECK-LABEL: @pointer_select_clobbered_in_loop_3(
540 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
541 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
542 ; CHECK-NEXT: br label [[LOOP:%.*]]
544 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
545 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
546 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
547 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
548 ; CHECK-NEXT: store i32 99, ptr [[PTR_IV]], align 4
549 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
550 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
551 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
552 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
553 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
554 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
556 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
557 ; CHECK-NEXT: ret i32 [[RES]]
560 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
561 %l.2.pre = load i32, ptr %ptr, align 4
565 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
566 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
567 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
568 %l.1 = load i32, ptr %ptr.iv, align 4
569 store i32 99, ptr %ptr.iv
570 %cmp.1 = icmp ult i32 %l.1, %l.2
571 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
572 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
573 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
574 %ec = icmp eq ptr %ptr.iv.next, %end
575 br i1 %ec, label %exit, label %loop
578 %res = load i32, ptr %min.select, align 4
582 define i32 @pointer_select_clobbered_in_loop_4(ptr %ptr, ptr %end, ptr %ptr.2) {
583 ; CHECK-LABEL: @pointer_select_clobbered_in_loop_4(
585 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
586 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
587 ; CHECK-NEXT: br label [[LOOP:%.*]]
589 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
590 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
591 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
592 ; CHECK-NEXT: store i32 99, ptr [[PTR_2:%.*]], align 4
593 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
594 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
595 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
596 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
597 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
598 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
599 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
601 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
602 ; CHECK-NEXT: ret i32 [[RES]]
605 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
606 %l.2.pre = load i32, ptr %ptr, align 4
610 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
611 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
612 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
613 store i32 99, ptr %ptr.2
614 %l.1 = load i32, ptr %ptr.iv, align 4
615 %cmp.1 = icmp ult i32 %l.1, %l.2
616 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
617 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
618 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
619 %ec = icmp eq ptr %ptr.iv.next, %end
620 br i1 %ec, label %exit, label %loop
623 %res = load i32, ptr %min.select, align 4
627 declare void @may_write()
629 define i32 @pointer_select_clobbered_by_call_before_loop(ptr %ptr, ptr %end, ptr %ptr.2) {
630 ; CHECK-LABEL: @pointer_select_clobbered_by_call_before_loop(
632 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
633 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
634 ; CHECK-NEXT: call void @may_write()
635 ; CHECK-NEXT: br label [[LOOP:%.*]]
637 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
638 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
639 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
640 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
641 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
642 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
643 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
644 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
645 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
646 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
648 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
649 ; CHECK-NEXT: ret i32 [[RES]]
652 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
653 %l.2.pre = load i32, ptr %ptr, align 4
654 call void @may_write()
658 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
659 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
660 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
661 %l.1 = load i32, ptr %ptr.iv, align 4
662 %cmp.1 = icmp ult i32 %l.1, %l.2
663 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
664 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
665 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
666 %ec = icmp eq ptr %ptr.iv.next, %end
667 br i1 %ec, label %exit, label %loop
670 %res = load i32, ptr %min.select, align 4
674 define i32 @pointer_select_clobbered_by_call_in_loop(ptr %ptr, ptr %end, ptr %ptr.2) {
675 ; CHECK-LABEL: @pointer_select_clobbered_by_call_in_loop(
677 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
678 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
679 ; CHECK-NEXT: br label [[LOOP:%.*]]
681 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
682 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
683 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
684 ; CHECK-NEXT: call void @may_write()
685 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
686 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
687 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
688 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
689 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
690 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
691 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
693 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
694 ; CHECK-NEXT: ret i32 [[RES]]
697 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
698 %l.2.pre = load i32, ptr %ptr, align 4
702 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
703 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
704 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
705 call void @may_write()
706 %l.1 = load i32, ptr %ptr.iv, align 4
707 %cmp.1 = icmp ult i32 %l.1, %l.2
708 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
709 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
710 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
711 %ec = icmp eq ptr %ptr.iv.next, %end
712 br i1 %ec, label %exit, label %loop
715 %res = load i32, ptr %min.select, align 4
719 define i32 @pointer_select_clobbered_by_call_after_loop(ptr %ptr, ptr %end, ptr %ptr.2) {
720 ; CHECK-LABEL: @pointer_select_clobbered_by_call_after_loop(
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:%.*]] ], [ [[MIN_VAL:%.*]], [[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_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
731 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
732 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], 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: call void @may_write()
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
743 %l.2.pre = load i32, ptr %ptr, align 4
747 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
748 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
749 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
750 %l.1 = load i32, ptr %ptr.iv, align 4
751 %cmp.1 = icmp ult i32 %l.1, %l.2
752 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
753 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
754 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
755 %ec = icmp eq ptr %ptr.iv.next, %end
756 br i1 %ec, label %exit, label %loop
759 call void @may_write()
760 %res = load i32, ptr %min.select, align 4
764 define i32 @pointer_select_clobbered_after_loop(ptr %ptr, ptr %end) {
765 ; CHECK-LABEL: @pointer_select_clobbered_after_loop(
767 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
768 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
769 ; CHECK-NEXT: br label [[LOOP:%.*]]
771 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
772 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
773 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
774 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
775 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
776 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
777 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
778 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
779 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
780 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
782 ; CHECK-NEXT: store i32 99, ptr [[PTR]], align 4
783 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
784 ; CHECK-NEXT: ret i32 [[RES]]
787 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
788 %l.2.pre = load i32, ptr %ptr, align 4
792 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
793 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
794 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
795 %l.1 = load i32, ptr %ptr.iv, align 4
796 %cmp.1 = icmp ult i32 %l.1, %l.2
797 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
798 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
799 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
800 %ec = icmp eq ptr %ptr.iv.next, %end
801 br i1 %ec, label %exit, label %loop
804 store i32 99, ptr %ptr
805 %res = load i32, ptr %min.select, align 4
809 declare void @may_throw() readonly
811 define i32 @pointer_select_may_throw_before_loop(ptr %ptr, ptr %end) {
812 ; CHECK-LABEL: @pointer_select_may_throw_before_loop(
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: call void @may_throw()
817 ; CHECK-NEXT: br label [[LOOP:%.*]]
819 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
820 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
821 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
822 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
823 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
824 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
825 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
826 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
827 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
828 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
830 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
831 ; CHECK-NEXT: ret i32 [[RES]]
834 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
835 %l.2.pre = load i32, ptr %ptr, align 4
836 call void @may_throw()
840 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
841 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
842 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
843 %l.1 = load i32, ptr %ptr.iv, align 4
844 %cmp.1 = icmp ult i32 %l.1, %l.2
845 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
846 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
847 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
848 %ec = icmp eq ptr %ptr.iv.next, %end
849 br i1 %ec, label %exit, label %loop
852 %res = load i32, ptr %min.select, align 4
856 define i32 @pointer_select_may_throw_in_loop(ptr %ptr, ptr %end) {
857 ; CHECK-LABEL: @pointer_select_may_throw_in_loop(
859 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
860 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
861 ; CHECK-NEXT: br label [[LOOP:%.*]]
863 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
864 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
865 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
866 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
867 ; CHECK-NEXT: call void @may_throw()
868 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
869 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
870 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
871 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
872 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
873 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
875 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
876 ; CHECK-NEXT: ret i32 [[RES]]
879 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
880 %l.2.pre = load i32, ptr %ptr, align 4
884 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
885 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
886 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
887 %l.1 = load i32, ptr %ptr.iv, align 4
888 call void @may_throw()
889 %cmp.1 = icmp ult i32 %l.1, %l.2
890 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
891 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
892 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
893 %ec = icmp eq ptr %ptr.iv.next, %end
894 br i1 %ec, label %exit, label %loop
897 %res = load i32, ptr %min.select, align 4
901 define i32 @pointer_select_may_throw_after_loop(ptr %ptr, ptr %end) {
902 ; CHECK-LABEL: @pointer_select_may_throw_after_loop(
904 ; CHECK-NEXT: [[START_PTR:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
905 ; CHECK-NEXT: [[L_2_PRE:%.*]] = load i32, ptr [[PTR]], align 4
906 ; CHECK-NEXT: br label [[LOOP:%.*]]
908 ; CHECK-NEXT: [[L_2:%.*]] = phi i32 [ [[L_2_PRE]], [[ENTRY:%.*]] ], [ [[MIN_VAL:%.*]], [[LOOP]] ]
909 ; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START_PTR]], [[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP]] ]
910 ; CHECK-NEXT: [[MIN_PTR:%.*]] = phi ptr [ [[PTR]], [[ENTRY]] ], [ [[MIN_SELECT:%.*]], [[LOOP]] ]
911 ; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV]], align 4
912 ; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[L_1]], [[L_2]]
913 ; CHECK-NEXT: [[MIN_VAL]] = select i1 [[CMP_1]], i32 [[L_1]], i32 [[L_2]]
914 ; CHECK-NEXT: [[MIN_SELECT]] = select i1 [[CMP_1]], ptr [[PTR_IV]], ptr [[MIN_PTR]]
915 ; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i64 1
916 ; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END:%.*]]
917 ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]
919 ; CHECK-NEXT: call void @may_throw()
920 ; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[MIN_SELECT]], align 4
921 ; CHECK-NEXT: ret i32 [[RES]]
924 %start.ptr = getelementptr inbounds i32, ptr %ptr, i64 1
925 %l.2.pre = load i32, ptr %ptr, align 4
929 %l.2 = phi i32 [ %l.2.pre, %entry ], [ %min.val, %loop ]
930 %ptr.iv = phi ptr [ %start.ptr, %entry ], [ %ptr.iv.next, %loop ]
931 %min.ptr = phi ptr [ %ptr, %entry ], [ %min.select, %loop ]
932 %l.1 = load i32, ptr %ptr.iv, align 4
933 %cmp.1 = icmp ult i32 %l.1, %l.2
934 %min.val = select i1 %cmp.1, i32 %l.1, i32 %l.2
935 %min.select = select i1 %cmp.1, ptr %ptr.iv, ptr %min.ptr
936 %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i64 1
937 %ec = icmp eq ptr %ptr.iv.next, %end
938 br i1 %ec, label %exit, label %loop
941 call void @may_throw()
942 %res = load i32, ptr %min.select, align 4