1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -passes=sccp -S | FileCheck --check-prefix=SCCP %s
3 ; RUN: opt %s -passes=ipsccp -S | FileCheck --check-prefix=IPSCCP %s
5 ; Test different widening scenarios.
10 define void @test_2_incoming_constants(i32 %x) {
11 ; SCCP-LABEL: @test_2_incoming_constants(
13 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
14 ; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
16 ; SCCP-NEXT: br label [[EXIT]]
18 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
19 ; SCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
20 ; SCCP-NEXT: call void @use(i1 true)
21 ; SCCP-NEXT: call void @use(i1 false)
24 ; IPSCCP-LABEL: @test_2_incoming_constants(
26 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
27 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
29 ; IPSCCP-NEXT: br label [[EXIT]]
31 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
32 ; IPSCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
33 ; IPSCCP-NEXT: call void @use(i1 true)
34 ; IPSCCP-NEXT: call void @use(i1 false)
35 ; IPSCCP-NEXT: ret void
38 %c.1 = call i1 @cond()
39 br i1 %c.1, label %bb1, label %exit
45 %p = phi i32 [0, %entry], [1, %bb1]
47 %t.1 = icmp ult i32 %a, 20
48 call void @use(i1 %t.1)
49 %f.1 = icmp ugt i32 %a, 10
50 call void @use(i1 %f.1)
54 define void @test_3_incoming_constants(i32 %x) {
55 ; SCCP-LABEL: @test_3_incoming_constants(
57 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
58 ; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
60 ; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
61 ; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
63 ; SCCP-NEXT: br label [[EXIT]]
65 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
66 ; SCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
67 ; SCCP-NEXT: call void @use(i1 true)
68 ; SCCP-NEXT: call void @use(i1 false)
71 ; IPSCCP-LABEL: @test_3_incoming_constants(
73 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
74 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
76 ; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
77 ; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
79 ; IPSCCP-NEXT: br label [[EXIT]]
81 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
82 ; IPSCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
83 ; IPSCCP-NEXT: call void @use(i1 true)
84 ; IPSCCP-NEXT: call void @use(i1 false)
85 ; IPSCCP-NEXT: ret void
88 %c.1 = call i1 @cond()
89 br i1 %c.1, label %bb1, label %exit
92 %c.2 = call i1 @cond()
93 br i1 %c.2, label %bb2, label %exit
99 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2]
101 %t.1 = icmp ult i32 %a, 20
102 call void @use(i1 %t.1)
103 %f.1 = icmp ugt i32 %a, 10
104 call void @use(i1 %f.1)
108 define void @test_5_incoming_constants(i32 %x) {
109 ; SCCP-LABEL: @test_5_incoming_constants(
111 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
112 ; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
114 ; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
115 ; SCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
117 ; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
118 ; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
120 ; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
121 ; SCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
123 ; SCCP-NEXT: br label [[EXIT]]
125 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
126 ; SCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
127 ; SCCP-NEXT: call void @use(i1 true)
128 ; SCCP-NEXT: call void @use(i1 false)
129 ; SCCP-NEXT: ret void
131 ; IPSCCP-LABEL: @test_5_incoming_constants(
132 ; IPSCCP-NEXT: entry:
133 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
134 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
136 ; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
137 ; IPSCCP-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
139 ; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
140 ; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
142 ; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
143 ; IPSCCP-NEXT: br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
145 ; IPSCCP-NEXT: br label [[EXIT]]
147 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
148 ; IPSCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
149 ; IPSCCP-NEXT: call void @use(i1 true)
150 ; IPSCCP-NEXT: call void @use(i1 false)
151 ; IPSCCP-NEXT: ret void
154 %c.1 = call i1 @cond()
155 br i1 %c.1, label %bb1, label %exit
158 %c.2 = call i1 @cond()
159 br i1 %c.2, label %bb2, label %exit
162 %c.3 = call i1 @cond()
163 br i1 %c.3, label %bb3, label %exit
166 %c.4 = call i1 @cond()
167 br i1 %c.4, label %bb4, label %exit
173 %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2], [3, %bb3], [4, %bb4]
175 %t.1 = icmp ult i32 %a, 20
176 call void @use(i1 %t.1)
177 %f.1 = icmp ugt i32 %a, 10
178 call void @use(i1 %f.1)
182 ; For the rotated_loop_* test cases %p and %a are extended on each iteration.
184 define void @rotated_loop_2(i32 %x) {
185 ; SCCP-LABEL: @rotated_loop_2(
187 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
188 ; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
190 ; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
191 ; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
193 ; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
194 ; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
196 ; SCCP-NEXT: br label [[EXIT]]
198 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
199 ; SCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
200 ; SCCP-NEXT: call void @use(i1 true)
201 ; SCCP-NEXT: call void @use(i1 false)
202 ; SCCP-NEXT: br label [[EXIT_1:%.*]]
204 ; SCCP-NEXT: ret void
206 ; IPSCCP-LABEL: @rotated_loop_2(
207 ; IPSCCP-NEXT: entry:
208 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
209 ; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
211 ; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
212 ; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
214 ; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
215 ; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
217 ; IPSCCP-NEXT: br label [[EXIT]]
219 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
220 ; IPSCCP-NEXT: [[A:%.*]] = add nuw nsw i32 [[P]], 1
221 ; IPSCCP-NEXT: call void @use(i1 true)
222 ; IPSCCP-NEXT: call void @use(i1 false)
223 ; IPSCCP-NEXT: br label [[EXIT_1:%.*]]
225 ; IPSCCP-NEXT: ret void
228 %c.1 = call i1 @cond()
229 br i1 %c.1, label %exit, label %bb1
232 %c.2 = call i1 @cond()
233 br i1 %c.2, label %exit, label %bb2
236 %c.3 = call i1 @cond()
237 br i1 %c.3, label %bb3, label %exit
243 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
245 %t.1 = icmp ult i32 %a, 20
246 call void @use(i1 %t.1)
247 %f.1 = icmp ugt i32 %a, 10
248 call void @use(i1 %f.1)
249 %c.4 = icmp ult i32 %a, 2
250 br i1 %c.4, label %exit, label %exit.1
256 define void @rotated_loop_3(i32 %x) {
257 ; SCCP-LABEL: @rotated_loop_3(
259 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
260 ; SCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
262 ; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
263 ; SCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
265 ; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
266 ; SCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
268 ; SCCP-NEXT: br label [[EXIT]]
270 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
271 ; SCCP-NEXT: [[A]] = add i32 [[P]], 1
272 ; SCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20
273 ; SCCP-NEXT: call void @use(i1 [[T_1]])
274 ; SCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10
275 ; SCCP-NEXT: call void @use(i1 [[F_1]])
276 ; SCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3
277 ; SCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]]
279 ; SCCP-NEXT: ret void
281 ; IPSCCP-LABEL: @rotated_loop_3(
282 ; IPSCCP-NEXT: entry:
283 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
284 ; IPSCCP-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
286 ; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
287 ; IPSCCP-NEXT: br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
289 ; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
290 ; IPSCCP-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
292 ; IPSCCP-NEXT: br label [[EXIT]]
294 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
295 ; IPSCCP-NEXT: [[A]] = add i32 [[P]], 1
296 ; IPSCCP-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 20
297 ; IPSCCP-NEXT: call void @use(i1 [[T_1]])
298 ; IPSCCP-NEXT: [[F_1:%.*]] = icmp ugt i32 [[A]], 10
299 ; IPSCCP-NEXT: call void @use(i1 [[F_1]])
300 ; IPSCCP-NEXT: [[C_4:%.*]] = icmp ult i32 [[A]], 3
301 ; IPSCCP-NEXT: br i1 [[C_4]], label [[EXIT]], label [[EXIT_1:%.*]]
303 ; IPSCCP-NEXT: ret void
306 %c.1 = call i1 @cond()
307 br i1 %c.1, label %exit, label %bb1
310 %c.2 = call i1 @cond()
311 br i1 %c.2, label %exit, label %bb2
314 %c.3 = call i1 @cond()
315 br i1 %c.3, label %bb3, label %exit
321 %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
323 %t.1 = icmp ult i32 %a, 20
324 call void @use(i1 %t.1)
325 %f.1 = icmp ugt i32 %a, 10
326 call void @use(i1 %f.1)
327 %c.4 = icmp ult i32 %a, 3
328 br i1 %c.4, label %exit, label %exit.1
334 ; For the loop_with_header_* tests, %iv and %a change on each iteration, but we
335 ; can use the range imposed by the condition %c.1 when widening.
336 define void @loop_with_header_1(i32 %x) {
337 ; SCCP-LABEL: @loop_with_header_1(
339 ; SCCP-NEXT: br label [[LOOP_HEADER:%.*]]
341 ; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
342 ; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2
343 ; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
345 ; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 2
346 ; SCCP-NEXT: call void @use(i1 [[T_1]])
347 ; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
348 ; SCCP-NEXT: br label [[LOOP_HEADER]]
350 ; SCCP-NEXT: ret void
352 ; IPSCCP-LABEL: @loop_with_header_1(
353 ; IPSCCP-NEXT: entry:
354 ; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]]
355 ; IPSCCP: loop.header:
356 ; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
357 ; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 2
358 ; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
360 ; IPSCCP-NEXT: call void @use(i1 true)
361 ; IPSCCP-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
362 ; IPSCCP-NEXT: br label [[LOOP_HEADER]]
364 ; IPSCCP-NEXT: ret void
367 br label %loop.header
370 %iv = phi i32 [0, %entry], [%iv.next, %loop.body]
371 %c.1 = icmp slt i32 %iv, 2
372 br i1 %c.1, label %loop.body, label %exit
375 %t.1 = icmp slt i32 %iv, 2
376 call void @use(i1 %t.1)
377 %iv.next = add nsw i32 %iv, 1
378 br label %loop.header
384 define void @loop_with_header_2(i32 %x) {
385 ; SCCP-LABEL: @loop_with_header_2(
387 ; SCCP-NEXT: br label [[LOOP_HEADER:%.*]]
389 ; SCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
390 ; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200
391 ; SCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
393 ; SCCP-NEXT: [[T_1:%.*]] = icmp slt i32 [[IV]], 200
394 ; SCCP-NEXT: call void @use(i1 [[T_1]])
395 ; SCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
396 ; SCCP-NEXT: br label [[LOOP_HEADER]]
398 ; SCCP-NEXT: ret void
400 ; IPSCCP-LABEL: @loop_with_header_2(
401 ; IPSCCP-NEXT: entry:
402 ; IPSCCP-NEXT: br label [[LOOP_HEADER:%.*]]
403 ; IPSCCP: loop.header:
404 ; IPSCCP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_BODY:%.*]] ]
405 ; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 200
406 ; IPSCCP-NEXT: br i1 [[C_1]], label [[LOOP_BODY]], label [[EXIT:%.*]]
408 ; IPSCCP-NEXT: call void @use(i1 true)
409 ; IPSCCP-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
410 ; IPSCCP-NEXT: br label [[LOOP_HEADER]]
412 ; IPSCCP-NEXT: ret void
415 br label %loop.header
418 %iv = phi i32 [0, %entry], [%iv.next, %loop.body]
419 %c.1 = icmp slt i32 %iv, 200
420 br i1 %c.1, label %loop.body, label %exit
423 %t.1 = icmp slt i32 %iv, 200
424 call void @use(i1 %t.1)
425 %iv.next = add nsw i32 %iv, 1
426 br label %loop.header
432 ; In the function below, the condition %c.1 results in a range [7, 6), which
433 ; can be used as a widening bound. It does not fully contain the range we get
434 ; from combining it with the information from %tmp12.
435 define void @foo(ptr %arg, i8 %x) {
438 ; SCCP-NEXT: [[TMP:%.*]] = zext i8 [[X:%.*]] to i32
439 ; SCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
440 ; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
441 ; SCCP-NEXT: i32 1, label [[BB3:%.*]]
442 ; SCCP-NEXT: i32 2, label [[BB4:%.*]]
443 ; SCCP-NEXT: i32 4, label [[BB19:%.*]]
446 ; SCCP-NEXT: unreachable
448 ; SCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
449 ; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
450 ; SCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
451 ; SCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
452 ; SCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
453 ; SCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
454 ; SCCP-NEXT: br label [[BB11:%.*]]
456 ; SCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
457 ; SCCP-NEXT: br label [[BB13:%.*]]
459 ; SCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
460 ; SCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
462 ; SCCP-NEXT: unreachable
464 ; SCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2
465 ; SCCP-NEXT: br label [[BB18]]
467 ; SCCP-NEXT: br label [[BB11]]
469 ; SCCP-NEXT: unreachable
471 ; SCCP-NEXT: ret void
473 ; IPSCCP-LABEL: @foo(
475 ; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 [[X:%.*]] to i32
476 ; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
477 ; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
478 ; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
479 ; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
480 ; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
483 ; IPSCCP-NEXT: unreachable
485 ; IPSCCP-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], 3
486 ; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
487 ; IPSCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
488 ; IPSCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
489 ; IPSCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
490 ; IPSCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
491 ; IPSCCP-NEXT: br label [[BB11:%.*]]
493 ; IPSCCP-NEXT: [[TMP12:%.*]] = phi i64 [ [[TMP10]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
494 ; IPSCCP-NEXT: br label [[BB13:%.*]]
496 ; IPSCCP-NEXT: [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
497 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
499 ; IPSCCP-NEXT: unreachable
501 ; IPSCCP-NEXT: [[TMP17]] = add i64 [[TMP12]], 2
502 ; IPSCCP-NEXT: br label [[BB18]]
504 ; IPSCCP-NEXT: br label [[BB11]]
506 ; IPSCCP-NEXT: unreachable
508 ; IPSCCP-NEXT: ret void
511 %tmp = zext i8 %x to i32
512 %tmp2 = load i64, ptr %arg, align 8
513 switch i32 %tmp, label %bb20 [
523 %tmp5 = add i64 %tmp2, 3
524 %tmp6 = and i64 %tmp5, 3
525 %tmp7 = sub i64 3, %tmp6
526 %tmp8 = shl i64 %tmp7, 1
527 %tmp9 = trunc i64 %tmp8 to i32
528 %tmp10 = sext i32 %tmp9 to i64
531 bb11: ; preds = %bb18, %bb4
532 %tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ]
535 bb13: ; preds = %bb11
536 %c.1 = icmp eq i64 %tmp12, 6
537 br i1 %c.1, label %bb15, label %bb16
539 bb15: ; preds = %bb13
542 bb16: ; preds = %bb13
543 %tmp17 = add i64 %tmp12, 2
546 bb18: ; preds = %bb16
556 ; The functions below check that widening with an upper bound does correctly
557 ; return whether the range changed. Make sure we do not eliminate %c.2.
559 %struct.baz.1 = type { i32, i32, ptr, ptr }
560 %struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }>
562 @global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1
564 declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1
566 define linkonce_odr dereferenceable(1) ptr @spam(ptr %arg, i32 %arg1) align 2 {
569 ; SCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
570 ; SCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
571 ; SCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
572 ; SCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
573 ; SCCP-NEXT: ret ptr [[TMP4]]
575 ; IPSCCP-LABEL: @spam(
577 ; IPSCCP-NEXT: [[TMP:%.*]] = getelementptr inbounds nuw [[STRUCT_BAZ_1:%.*]], ptr [[ARG:%.*]], i32 0, i32 3
578 ; IPSCCP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP]], align 8
579 ; IPSCCP-NEXT: [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
580 ; IPSCCP-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 [[TMP3]]
581 ; IPSCCP-NEXT: ret ptr [[TMP4]]
584 %tmp = getelementptr inbounds %struct.baz.1, ptr %arg, i32 0, i32 3
585 %tmp2 = load ptr, ptr %tmp, align 8
586 %tmp3 = sext i32 %arg1 to i64
587 %tmp4 = getelementptr inbounds i8, ptr %tmp2, i64 %tmp3
591 define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
592 ; SCCP-LABEL: @wobble(
594 ; SCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
595 ; SCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
596 ; SCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
597 ; SCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
598 ; SCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
599 ; SCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
600 ; SCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
601 ; SCCP-NEXT: br label [[BB8:%.*]]
603 ; SCCP-NEXT: [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
604 ; SCCP-NEXT: [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ]
605 ; SCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
606 ; SCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
607 ; SCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
609 ; SCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
610 ; SCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
611 ; SCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
612 ; SCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
613 ; SCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
614 ; SCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
615 ; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
616 ; SCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
618 ; SCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
619 ; SCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
620 ; SCCP-NEXT: br label [[BB31]]
622 ; SCCP-NEXT: [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2
623 ; SCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
624 ; SCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
625 ; SCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]]
627 ; SCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1
628 ; SCCP-NEXT: br label [[BB8]]
630 ; SCCP-NEXT: [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
631 ; SCCP-NEXT: [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
632 ; SCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
633 ; SCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
635 ; SCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
636 ; SCCP-NEXT: br label [[BB66:%.*]]
638 ; SCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
639 ; SCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
641 ; SCCP-NEXT: [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
642 ; SCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
643 ; SCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
644 ; SCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
645 ; SCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
646 ; SCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2
647 ; SCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]])
648 ; SCCP-NEXT: [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1
649 ; SCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
650 ; SCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1
651 ; SCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4
652 ; SCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2
653 ; SCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]])
654 ; SCCP-NEXT: [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1
655 ; SCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
656 ; SCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
657 ; SCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
659 ; SCCP-NEXT: [[TMP57:%.*]] = add nsw i32 [[TMP40]], -1
660 ; SCCP-NEXT: br label [[BB60]]
662 ; SCCP-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false)
663 ; SCCP-NEXT: br label [[BB60]]
665 ; SCCP-NEXT: [[TMP61:%.*]] = phi i32 [ [[TMP57]], [[BB56]] ], [ [[TMP40]], [[BB39]] ], [ [[TMP11]], [[BB58]] ]
666 ; SCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1
667 ; SCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4
668 ; SCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]])
669 ; SCCP-NEXT: br label [[BB66]]
671 ; SCCP-NEXT: [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
672 ; SCCP-NEXT: ret ptr [[TMP67]]
674 ; IPSCCP-LABEL: @wobble(
676 ; IPSCCP-NEXT: [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
677 ; IPSCCP-NEXT: [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
678 ; IPSCCP-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 65535
679 ; IPSCCP-NEXT: [[TMP4:%.*]] = mul i32 [[ARG1]], 8
680 ; IPSCCP-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT_BLAM_2:%.*]], ptr [[ARG:%.*]], i32 0, i32 1
681 ; IPSCCP-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 8
682 ; IPSCCP-NEXT: [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
683 ; IPSCCP-NEXT: br label [[BB8:%.*]]
685 ; IPSCCP-NEXT: [[TMP9:%.*]] = phi ptr [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
686 ; IPSCCP-NEXT: [[TMP10:%.*]] = phi ptr [ undef, [[BB]] ], [ [[TMP17]], [[BB29]] ]
687 ; IPSCCP-NEXT: [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
688 ; IPSCCP-NEXT: [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
689 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
691 ; IPSCCP-NEXT: [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
692 ; IPSCCP-NEXT: [[TMP16:%.*]] = mul i32 [[TMP15]], 4
693 ; IPSCCP-NEXT: [[TMP17]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP16]])
694 ; IPSCCP-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP17]], i64 2
695 ; IPSCCP-NEXT: [[TMP20:%.*]] = load i8, ptr [[TMP19]], align 1
696 ; IPSCCP-NEXT: [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
697 ; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
698 ; IPSCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
700 ; IPSCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
701 ; IPSCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
702 ; IPSCCP-NEXT: br label [[BB31]]
704 ; IPSCCP-NEXT: [[TMP26:%.*]] = load i16, ptr [[TMP17]], align 2
705 ; IPSCCP-NEXT: [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
706 ; IPSCCP-NEXT: [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
707 ; IPSCCP-NEXT: br i1 [[TMP28]], label [[BB31]], label [[BB29]]
709 ; IPSCCP-NEXT: [[TMP30]] = add nsw i32 [[TMP11]], 1
710 ; IPSCCP-NEXT: br label [[BB8]]
712 ; IPSCCP-NEXT: [[TMP32:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
713 ; IPSCCP-NEXT: [[TMP33:%.*]] = phi ptr [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
714 ; IPSCCP-NEXT: [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
715 ; IPSCCP-NEXT: br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
717 ; IPSCCP-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP32]], i64 1
718 ; IPSCCP-NEXT: br label [[BB66:%.*]]
720 ; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
721 ; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
723 ; IPSCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
724 ; IPSCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
725 ; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7
726 ; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
727 ; IPSCCP-NEXT: [[TMP45:%.*]] = add i32 [[TMP44]], 2
728 ; IPSCCP-NEXT: [[TMP46:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP45]])
729 ; IPSCCP-NEXT: [[TMP47:%.*]] = load i8, ptr [[TMP46]], align 1
730 ; IPSCCP-NEXT: [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
731 ; IPSCCP-NEXT: [[TMP49:%.*]] = sub i32 [[TMP43]], 1
732 ; IPSCCP-NEXT: [[TMP50:%.*]] = mul i32 [[TMP49]], 4
733 ; IPSCCP-NEXT: [[TMP51:%.*]] = add i32 [[TMP50]], 2
734 ; IPSCCP-NEXT: [[TMP52:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP51]])
735 ; IPSCCP-NEXT: [[TMP53:%.*]] = load i8, ptr [[TMP52]], align 1
736 ; IPSCCP-NEXT: [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
737 ; IPSCCP-NEXT: [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
738 ; IPSCCP-NEXT: br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
740 ; IPSCCP-NEXT: br label [[BB60]]
742 ; IPSCCP-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 [[TMP33]], i64 4, i1 false)
743 ; IPSCCP-NEXT: br label [[BB60]]
745 ; IPSCCP-NEXT: [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ]
746 ; IPSCCP-NEXT: [[TMP63:%.*]] = add i32 [[TMP7]], 1
747 ; IPSCCP-NEXT: [[TMP64:%.*]] = mul i32 [[TMP63]], 4
748 ; IPSCCP-NEXT: [[TMP65:%.*]] = call dereferenceable(1) ptr @spam(ptr [[ARG]], i32 [[TMP64]])
749 ; IPSCCP-NEXT: br label [[BB66]]
751 ; IPSCCP-NEXT: [[TMP67:%.*]] = phi ptr [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
752 ; IPSCCP-NEXT: ret ptr [[TMP67]]
755 %tmp = lshr i32 %arg1, 16
756 %tmp2 = xor i32 %tmp, %arg1
757 %tmp3 = and i32 %tmp2, 65535
758 %tmp4 = mul i32 %arg1, 8
759 %tmp5 = getelementptr inbounds %struct.blam.2, ptr %arg, i32 0, i32 1
760 %tmp6 = load i32, ptr %tmp5, align 8
761 %tmp7 = and i32 %tmp4, %tmp6
764 bb8: ; preds = %bb29, %bb
765 %tmp9 = phi ptr [ undef, %bb ], [ %tmp17, %bb29 ]
766 %tmp10 = phi ptr [ undef, %bb ], [ %tmp17, %bb29 ]
767 %tmp11 = phi i32 [ 0, %bb ], [ %tmp30, %bb29 ]
768 %c.1 = icmp slt i32 %tmp11, 8
769 br i1 %c.1, label %bb13, label %bb31
772 %tmp15 = add i32 %tmp7, %tmp11
773 %tmp16 = mul i32 %tmp15, 4
774 %tmp17 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp16)
775 %tmp19 = getelementptr inbounds i8, ptr %tmp17, i64 2
776 %tmp20 = load i8, ptr %tmp19, align 1
777 %tmp21 = zext i8 %tmp20 to i32
778 %tmp22 = icmp eq i32 %tmp21, 0
779 br i1 %tmp22, label %bb23, label %bb25
781 bb23: ; preds = %bb13
782 %tmp24 = trunc i32 %tmp3 to i16
783 store i16 %tmp24, ptr %tmp17, align 2
786 bb25: ; preds = %bb13
787 %tmp26 = load i16, ptr %tmp17, align 2
788 %tmp27 = zext i16 %tmp26 to i32
789 %tmp28 = icmp eq i32 %tmp27, %tmp3
790 br i1 %tmp28, label %bb31, label %bb29
792 bb29: ; preds = %bb25
793 %tmp30 = add nsw i32 %tmp11, 1
796 bb31: ; preds = %bb25, %bb23, %bb8
797 %tmp32 = phi ptr [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp9, %bb8 ]
798 %tmp33 = phi ptr [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp10, %bb8 ]
799 %tmp34 = icmp eq i32 %tmp11, 0
800 br i1 %tmp34, label %bb35, label %bb37
802 bb35: ; preds = %bb31
803 %tmp36 = getelementptr inbounds i8, ptr %tmp32, i64 1
806 bb37: ; preds = %bb31
807 %c.2 = icmp eq i32 %tmp11, 8
808 br i1 %c.2, label %bb39, label %bb58
810 bb39: ; preds = %bb37
811 %tmp40 = add nsw i32 %tmp11, -1
812 %tmp41 = trunc i32 %tmp3 to i16
813 store i16 %tmp41, ptr @global.11, align 1
814 %tmp43 = add i32 %tmp7, %tmp40
815 %tmp44 = mul i32 %tmp43, 4
816 %tmp45 = add i32 %tmp44, 2
817 %tmp46 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp45)
818 %tmp47 = load i8, ptr %tmp46, align 1
819 %tmp48 = zext i8 %tmp47 to i32
820 %tmp49 = sub i32 %tmp43, 1
821 %tmp50 = mul i32 %tmp49, 4
822 %tmp51 = add i32 %tmp50, 2
823 %tmp52 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp51)
824 %tmp53 = load i8, ptr %tmp52, align 1
825 %tmp54 = zext i8 %tmp53 to i32
826 %tmp55 = icmp sgt i32 %tmp48, %tmp54
827 br i1 %tmp55, label %bb56, label %bb60
829 bb56: ; preds = %bb39
830 %tmp57 = add nsw i32 %tmp40, -1
833 bb58: ; preds = %bb37
834 call void @llvm.memcpy.p0.p0.i64(ptr align 1 @global.11, ptr align 2 %tmp33, i64 4, i1 false)
837 bb60: ; preds = %bb58, %bb56, %bb39
838 %tmp61 = phi i32 [ %tmp57, %bb56 ], [ %tmp40, %bb39 ], [ %tmp11, %bb58 ]
839 %tmp63 = add i32 %tmp7, 1
840 %tmp64 = mul i32 %tmp63, 4
841 %tmp65 = call dereferenceable(1) ptr @spam(ptr %arg, i32 %tmp64)
844 bb66: ; preds = %bb60, %bb35
845 %tmp67 = phi ptr [ %tmp36, %bb35 ], [ null, %bb60 ]
850 define i32 @loop_with_multiple_euqal_incomings(i32 %N) {
851 ; SCCP-LABEL: @loop_with_multiple_euqal_incomings(
853 ; SCCP-NEXT: br label [[LOOP:%.*]]
855 ; SCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
856 ; SCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
857 ; SCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
859 ; SCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
860 ; SCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]]
862 ; SCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
863 ; SCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]]
865 ; SCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1
866 ; SCCP-NEXT: br label [[LOOP]]
868 ; SCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
869 ; SCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
871 ; SCCP-NEXT: br label [[LOOP]]
873 ; SCCP-NEXT: br label [[LOOP]]
875 ; SCCP-NEXT: ret i32 [[P]]
877 ; IPSCCP-LABEL: @loop_with_multiple_euqal_incomings(
878 ; IPSCCP-NEXT: entry:
879 ; IPSCCP-NEXT: br label [[LOOP:%.*]]
881 ; IPSCCP-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
882 ; IPSCCP-NEXT: [[C_1:%.*]] = call i1 @cond()
883 ; IPSCCP-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
885 ; IPSCCP-NEXT: [[C_2:%.*]] = call i1 @cond()
886 ; IPSCCP-NEXT: br i1 [[C_2]], label [[BB3]], label [[BB4]]
888 ; IPSCCP-NEXT: [[C_4:%.*]] = call i1 @cond()
889 ; IPSCCP-NEXT: br i1 [[C_4]], label [[BB5]], label [[BB6]]
891 ; IPSCCP-NEXT: [[P_NEXT]] = add i32 [[P]], 1
892 ; IPSCCP-NEXT: br label [[LOOP]]
894 ; IPSCCP-NEXT: [[C_3:%.*]] = call i1 @cond()
895 ; IPSCCP-NEXT: br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
897 ; IPSCCP-NEXT: br label [[LOOP]]
899 ; IPSCCP-NEXT: br label [[LOOP]]
901 ; IPSCCP-NEXT: ret i32 [[P]]
907 %p = phi i32 [ 0, %entry ], [ %p.next, %bb3 ], [ 0, %bb4 ], [ 0, %bb5], [ 0, %bb6 ]
908 %c.1 = call i1 @cond()
909 br i1 %c.1, label %bb1, label %bb2
912 %c.2 = call i1 @cond()
913 br i1 %c.2, label %bb3, label %bb4
916 %c.4 = call i1 @cond()
917 br i1 %c.4, label %bb5, label %bb6
920 %p.next = add i32 %p, 1
924 %c.3 = call i1 @cond()
925 br i1 %c.3, label %loop, label %end