Revert "Warn when unique objects might be duplicated in shared libraries (#117622)"
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / unsupported_early_exit.ll
blob5b2a95f1b368c31334cd42d0e63b1b14032d7dd3
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -S < %s -p loop-vectorize -enable-early-exit-vectorization  -force-vector-width=4 | FileCheck %s
4 declare void @init_mem(ptr, i64);
7 ; The early exit (i.e. unknown exit-not-taken count) is the latch - we don't
8 ; support this yet.
9 define i64 @early_exit_on_last_block() {
10 ; CHECK-LABEL: define i64 @early_exit_on_last_block() {
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
13 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
14 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
15 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
16 ; CHECK-NEXT:    br label [[LAND_RHS:%.*]]
17 ; CHECK:       loop:
18 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[SEARCH:%.*]] ], [ 3, [[ENTRY:%.*]] ]
19 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
20 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
21 ; CHECK-NEXT:    br i1 [[CMP1]], label [[SEARCH]], label [[FOR_END_LOOPEXIT:%.*]]
22 ; CHECK:       search:
23 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
24 ; CHECK-NEXT:    [[TMP41:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
25 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
26 ; CHECK-NEXT:    [[TMP42:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
27 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i8 [[TMP41]], [[TMP42]]
28 ; CHECK-NEXT:    br i1 [[CMP3]], label [[FOR_END_LOOPEXIT]], label [[LAND_RHS]]
29 ; CHECK:       loop.end:
30 ; CHECK-NEXT:    [[START_0_LCSSA:%.*]] = phi i64 [ 64, [[LAND_RHS]] ], [ [[INDEX]], [[SEARCH]] ]
31 ; CHECK-NEXT:    ret i64 [[START_0_LCSSA]]
33 entry:
34   %p1 = alloca [1024 x i8]
35   %p2 = alloca [1024 x i8]
36   call void @init_mem(ptr %p1, i64 1024)
37   call void @init_mem(ptr %p2, i64 1024)
38   br label %loop
40 loop:
41   %index = phi i64 [ %index.next, %search ], [ 3, %entry ]
42   %index.next = add i64 %index, 1
43   %exitcond = icmp ne i64 %index.next, 67
44   br i1 %exitcond, label %search, label %loop.end
46 search:
47   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
48   %ld1 = load i8, ptr %arrayidx, align 1
49   %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
50   %ld2 = load i8, ptr %arrayidx1, align 1
51   %cmp3 = icmp eq i8 %ld1, %ld2
52   br i1 %cmp3, label %loop.end, label %loop
54 loop.end:
55   %retval = phi i64 [ 64, %loop ], [ %index, %search ]
56   ret i64 %retval
60 ; We don't currently support multiple early exits.
61 define i64 @multiple_uncountable_exits() {
62 ; CHECK-LABEL: define i64 @multiple_uncountable_exits() {
63 ; CHECK-NEXT:  entry:
64 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
65 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
66 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
67 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
68 ; CHECK-NEXT:    br label [[SEARCH1:%.*]]
69 ; CHECK:       search1:
70 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
71 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
72 ; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
73 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
74 ; CHECK-NEXT:    [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
75 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
76 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP_END:%.*]], label [[SEARCH2:%.*]]
77 ; CHECK:       search2:
78 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i8 [[LD1]], 34
79 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP_END]], label [[LOOP_INC]]
80 ; CHECK:       loop.inc:
81 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
82 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
83 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[SEARCH1]], label [[LOOP_END]]
84 ; CHECK:       loop.end:
85 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[SEARCH1]] ], [ 100, [[SEARCH2]] ], [ 43, [[LOOP_INC]] ]
86 ; CHECK-NEXT:    ret i64 [[RETVAL]]
88 entry:
89   %p1 = alloca [1024 x i8]
90   %p2 = alloca [1024 x i8]
91   call void @init_mem(ptr %p1, i64 1024)
92   call void @init_mem(ptr %p2, i64 1024)
93   br label %search1
95 search1:
96   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
97   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
98   %ld1 = load i8, ptr %arrayidx, align 1
99   %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
100   %ld2 = load i8, ptr %arrayidx1, align 1
101   %cmp1 = icmp eq i8 %ld1, %ld2
102   br i1 %cmp1, label %loop.end, label %search2
104 search2:
105   %cmp2 = icmp ult i8 %ld1, 34
106   br i1 %cmp2, label %loop.end, label %loop.inc
108 loop.inc:
109   %index.next = add i64 %index, 1
110   %exitcond = icmp ne i64 %index.next, 67
111   br i1 %exitcond, label %search1, label %loop.end
113 loop.end:
114   %retval = phi i64 [ %index, %search1 ], [ 100, %search2 ], [ 43, %loop.inc ]
115   ret i64 %retval
119 define i64 @uncountable_exit_infinite_loop() {
120 ; CHECK-LABEL: define i64 @uncountable_exit_infinite_loop() {
121 ; CHECK-NEXT:  entry:
122 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
123 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
124 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
125 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
126 ; CHECK-NEXT:    br label [[LOOP:%.*]]
127 ; CHECK:       loop:
128 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
129 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
130 ; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
131 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
132 ; CHECK-NEXT:    [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
133 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
134 ; CHECK-NEXT:    br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END:%.*]]
135 ; CHECK:       loop.inc:
136 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
137 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
138 ; CHECK-NEXT:    br label [[LOOP]]
139 ; CHECK:       loop.end:
140 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ]
141 ; CHECK-NEXT:    ret i64 [[RETVAL]]
143 entry:
144   %p1 = alloca [1024 x i8]
145   %p2 = alloca [1024 x i8]
146   call void @init_mem(ptr %p1, i64 1024)
147   call void @init_mem(ptr %p2, i64 1024)
148   br label %loop
150 loop:
151   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
152   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
153   %ld1 = load i8, ptr %arrayidx, align 1
154   %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
155   %ld2 = load i8, ptr %arrayidx1, align 1
156   %cmp3 = icmp eq i8 %ld1, %ld2
157   br i1 %cmp3, label %loop.inc, label %loop.end
159 loop.inc:
160   %index.next = add i64 %index, 1
161   %exitcond = icmp ne i64 %index.next, 67
162   br label %loop
164 loop.end:
165   %retval = phi i64 [ %index, %loop ]
166   ret i64 %retval
170 define i64 @loop_contains_unsafe_call() {
171 ; CHECK-LABEL: define i64 @loop_contains_unsafe_call() {
172 ; CHECK-NEXT:  entry:
173 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
174 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
175 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
176 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
177 ; CHECK-NEXT:    br label [[LOOP:%.*]]
178 ; CHECK:       loop:
179 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
180 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]]
181 ; CHECK-NEXT:    [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1
182 ; CHECK-NEXT:    [[BAD_CALL:%.*]] = call i32 @foo(i32 [[LD1]]) #[[ATTR1:[0-9]+]]
183 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[BAD_CALL]], 34
184 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]
185 ; CHECK:       loop.inc:
186 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
187 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
188 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
189 ; CHECK:       loop.end:
190 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]
191 ; CHECK-NEXT:    ret i64 [[RETVAL]]
193 entry:
194   %p1 = alloca [1024 x i8]
195   %p2 = alloca [1024 x i8]
196   call void @init_mem(ptr %p1, i64 1024)
197   call void @init_mem(ptr %p2, i64 1024)
198   br label %loop
200 loop:
201   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
202   %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index
203   %ld1 = load i32, ptr %arrayidx, align 1
204   %bad_call = call i32 @foo(i32 %ld1) #0
205   %cmp = icmp eq i32 %bad_call, 34
206   br i1 %cmp, label %loop.inc, label %loop.end
208 loop.inc:
209   %index.next = add i64 %index, 1
210   %exitcond = icmp ne i64 %index.next, 67
211   br i1 %exitcond, label %loop, label %loop.end
213 loop.end:
214   %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
215   ret i64 %retval
219 define i64 @loop_contains_unsafe_div() {
220 ; CHECK-LABEL: define i64 @loop_contains_unsafe_div() {
221 ; CHECK-NEXT:  entry:
222 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
223 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
224 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
225 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
226 ; CHECK-NEXT:    br label [[LOOP:%.*]]
227 ; CHECK:       loop:
228 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
229 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
230 ; CHECK-NEXT:    [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1
231 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 20000, [[LD1]]
232 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[DIV]], 1
233 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]
234 ; CHECK:       loop.inc:
235 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
236 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
237 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
238 ; CHECK:       loop.end:
239 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]
240 ; CHECK-NEXT:    ret i64 [[RETVAL]]
242 entry:
243   %p1 = alloca [1024 x i8]
244   %p2 = alloca [1024 x i8]
245   call void @init_mem(ptr %p1, i64 1024)
246   call void @init_mem(ptr %p2, i64 1024)
247   br label %loop
249 loop:
250   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
251   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
252   %ld1 = load i32, ptr %arrayidx, align 1
253   %div = udiv i32 20000, %ld1
254   %cmp = icmp eq i32 %div, 1
255   br i1 %cmp, label %loop.inc, label %loop.end
257 loop.inc:
258   %index.next = add i64 %index, 1
259   %exitcond = icmp ne i64 %index.next, 67
260   br i1 %exitcond, label %loop, label %loop.end
262 loop.end:
263   %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
264   ret i64 %retval
268 define i64 @loop_contains_store(ptr %dest) {
269 ; CHECK-LABEL: define i64 @loop_contains_store(
270 ; CHECK-SAME: ptr [[DEST:%.*]]) {
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
273 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
274 ; CHECK-NEXT:    br label [[LOOP:%.*]]
275 ; CHECK:       loop:
276 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
277 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[P1]], i64 [[INDEX]]
278 ; CHECK-NEXT:    [[LD1:%.*]] = load i32, ptr [[ARRAYIDX]], align 1
279 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[DEST]], i64 [[INDEX]]
280 ; CHECK-NEXT:    store i32 [[LD1]], ptr [[ARRAYIDX2]], align 4
281 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[LD1]], 1
282 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_INC]], label [[LOOP_END:%.*]]
283 ; CHECK:       loop.inc:
284 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
285 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
286 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
287 ; CHECK:       loop.end:
288 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]
289 ; CHECK-NEXT:    ret i64 [[RETVAL]]
291 entry:
292   %p1 = alloca [1024 x i8]
293   call void @init_mem(ptr %p1, i64 1024)
294   br label %loop
296 loop:
297   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
298   %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index
299   %ld1 = load i32, ptr %arrayidx, align 1
300   %arrayidx2 = getelementptr inbounds i32, ptr %dest, i64 %index
301   store i32 %ld1, ptr %arrayidx2, align 4
302   %cmp = icmp eq i32 %ld1, 1
303   br i1 %cmp, label %loop.inc, label %loop.end
305 loop.inc:
306   %index.next = add i64 %index, 1
307   %exitcond = icmp ne i64 %index.next, 67
308   br i1 %exitcond, label %loop, label %loop.end
310 loop.end:
311   %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
312   ret i64 %retval
316 define i64 @uncountable_exit_in_conditional_block(ptr %mask) {
317 ; CHECK-LABEL: define i64 @uncountable_exit_in_conditional_block(
318 ; CHECK-SAME: ptr [[MASK:%.*]]) {
319 ; CHECK-NEXT:  entry:
320 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
321 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
322 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
323 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
324 ; CHECK-NEXT:    br label [[LOOP:%.*]]
325 ; CHECK:       loop:
326 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
327 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[MASK]], i64 [[INDEX]]
328 ; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
329 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[LD1]], 0
330 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LOOP_SEARCH:%.*]], label [[LOOP_INC]]
331 ; CHECK:       loop.search:
332 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
333 ; CHECK-NEXT:    [[LD2:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
334 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
335 ; CHECK-NEXT:    [[LD3:%.*]] = load i8, ptr [[ARRAYIDX3]], align 1
336 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[LD2]], [[LD3]]
337 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP_INC]], label [[LOOP_END:%.*]]
338 ; CHECK:       loop.inc:
339 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
340 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
341 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
342 ; CHECK:       loop.end:
343 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP_SEARCH]] ], [ 67, [[LOOP_INC]] ]
344 ; CHECK-NEXT:    ret i64 [[RETVAL]]
346 entry:
347   %p1 = alloca [1024 x i8]
348   %p2 = alloca [1024 x i8]
349   call void @init_mem(ptr %p1, i64 1024)
350   call void @init_mem(ptr %p2, i64 1024)
351   br label %loop
353 loop:
354   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
355   %arrayidx1 = getelementptr inbounds i8, ptr %mask, i64 %index
356   %ld1 = load i8, ptr %arrayidx1, align 1
357   %cmp1 = icmp ne i8 %ld1, 0
358   br i1 %cmp1, label %loop.search, label %loop.inc
360 loop.search:
361   %arrayidx2 = getelementptr inbounds i8, ptr %p1, i64 %index
362   %ld2 = load i8, ptr %arrayidx2, align 1
363   %arrayidx3 = getelementptr inbounds i8, ptr %p2, i64 %index
364   %ld3 = load i8, ptr %arrayidx3, align 1
365   %cmp2 = icmp eq i8 %ld2, %ld3
366   br i1 %cmp2, label %loop.inc, label %loop.end
368 loop.inc:
369   %index.next = add i64 %index, 1
370   %exitcond = icmp ne i64 %index.next, 67
371   br i1 %exitcond, label %loop, label %loop.end
373 loop.end:
374   %retval = phi i64 [ %index, %loop.search ], [ 67, %loop.inc ]
375   ret i64 %retval
379 define i64 @same_exit_block_pre_inc_use1_with_reduction() {
380 ; CHECK-LABEL: define i64 @same_exit_block_pre_inc_use1_with_reduction() {
381 ; CHECK-NEXT:  entry:
382 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
383 ; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
384 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
385 ; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
386 ; CHECK-NEXT:    br label [[LAND_RHS:%.*]]
387 ; CHECK:       loop:
388 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
389 ; CHECK-NEXT:    [[RED:%.*]] = phi i64 [ [[RED_NEXT:%.*]], [[FOR_INC]] ], [ 0, [[ENTRY]] ]
390 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
391 ; CHECK-NEXT:    [[TMP38:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
392 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
393 ; CHECK-NEXT:    [[TMP39:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
394 ; CHECK-NEXT:    [[LD2_ZEXT:%.*]] = zext i8 [[TMP39]] to i64
395 ; CHECK-NEXT:    [[RED_NEXT]] = add i64 [[RED]], [[LD2_ZEXT]]
396 ; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i8 [[TMP38]], [[TMP39]]
397 ; CHECK-NEXT:    br i1 [[CMP3]], label [[FOR_INC]], label [[FOR_END_LOOPEXIT:%.*]]
398 ; CHECK:       loop.inc:
399 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
400 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
401 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LAND_RHS]], label [[FOR_END_LOOPEXIT]]
402 ; CHECK:       loop.end:
403 ; CHECK-NEXT:    [[RED_NEXT_LCSSA:%.*]] = phi i64 [ [[RED_NEXT]], [[FOR_INC]] ], [ [[RED_NEXT]], [[LAND_RHS]] ]
404 ; CHECK-NEXT:    [[FINAL_IND:%.*]] = phi i64 [ [[INDEX]], [[LAND_RHS]] ], [ 67, [[FOR_INC]] ]
405 ; CHECK-NEXT:    [[START_0_LCSSA:%.*]] = add i64 [[RED_NEXT_LCSSA]], [[FINAL_IND]]
406 ; CHECK-NEXT:    ret i64 [[START_0_LCSSA]]
408 entry:
409   %p1 = alloca [1024 x i8]
410   %p2 = alloca [1024 x i8]
411   call void @init_mem(ptr %p1, i64 1024)
412   call void @init_mem(ptr %p2, i64 1024)
413   br label %loop
415 loop:
416   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
417   %red = phi i64 [ %red.next, %loop.inc ], [ 0, %entry ]
418   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
419   %ld1 = load i8, ptr %arrayidx, align 1
420   %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
421   %ld2 = load i8, ptr %arrayidx1, align 1
422   %ld2.zext = zext i8 %ld2 to i64
423   %red.next = add i64 %red, %ld2.zext
424   %cmp3 = icmp eq i8 %ld1, %ld2
425   br i1 %cmp3, label %loop.inc, label %loop.end
427 loop.inc:
428   %index.next = add i64 %index, 1
429   %exitcond = icmp ne i64 %index.next, 67
430   br i1 %exitcond, label %loop, label %loop.end
432 loop.end:
433   %final.ind = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
434   %retval = add i64 %red.next, %final.ind
435   ret i64 %retval
439 define i64 @uncountable_exit_has_multiple_outside_successors() {
440 ; CHECK-LABEL: define i64 @uncountable_exit_has_multiple_outside_successors() {
441 ; CHECK-NEXT:  entry:
442 ; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
443 ; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
444 ; CHECK-NEXT:    br label [[LOOP:%.*]]
445 ; CHECK:       loop:
446 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
447 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
448 ; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
449 ; CHECK-NEXT:    switch i8 [[LD1]], label [[LOOP_INC]] [
450 ; CHECK-NEXT:      i8 2, label [[LOOP_END:%.*]]
451 ; CHECK-NEXT:      i8 3, label [[LOOP_SURPRISE:%.*]]
452 ; CHECK-NEXT:    ]
453 ; CHECK:       loop.inc:
454 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
455 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 67
456 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
457 ; CHECK:       loop.surprise:
458 ; CHECK-NEXT:    ret i64 3
459 ; CHECK:       loop.end:
460 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[INDEX]], [[LOOP]] ], [ 67, [[LOOP_INC]] ]
461 ; CHECK-NEXT:    ret i64 [[RETVAL]]
463 entry:
464   %p1 = alloca [1024 x i8]
465   call void @init_mem(ptr %p1, i64 1024)
466   br label %loop
468 loop:
469   %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
470   %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
471   %ld1 = load i8, ptr %arrayidx, align 1
472   switch i8 %ld1, label %loop.inc [
473   i8 2, label %loop.end
474   i8 3, label %loop.surprise
475   ]
477 loop.inc:
478   %index.next = add i64 %index, 1
479   %exitcond = icmp ne i64 %index.next, 67
480   br i1 %exitcond, label %loop, label %loop.end
482 loop.surprise:
483   ret i64 3
485 loop.end:
486   %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]
487   ret i64 %retval
491 declare i32 @foo(i32) readonly
492 declare <vscale x 4 x i32> @foo_vec(<vscale x 4 x i32>)
494 attributes #0 = { "vector-function-abi-variant"="_ZGVsNxv_foo(foo_vec)" }