[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / SCCP / widening.ll
blob23a88c35a93eacc84cc27662042b44e0ce86fc4d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -sccp -S | FileCheck --check-prefix=SCCP %s
3 ; RUN: opt %s -ipsccp -S | FileCheck --check-prefix=IPSCCP %s
5 ; Test different widening scenarios.
7 declare void @use(i1)
8 declare i1 @cond()
10 define void @test_2_incoming_constants(i32 %x) {
11 ; SCCP-LABEL: @test_2_incoming_constants(
12 ; SCCP-NEXT:  entry:
13 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
14 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
15 ; SCCP:       bb1:
16 ; SCCP-NEXT:    br label [[EXIT]]
17 ; SCCP:       exit:
18 ; SCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
19 ; SCCP-NEXT:    [[A:%.*]] = add i32 [[P]], 1
20 ; SCCP-NEXT:    call void @use(i1 true)
21 ; SCCP-NEXT:    call void @use(i1 false)
22 ; SCCP-NEXT:    ret void
24 ; IPSCCP-LABEL: @test_2_incoming_constants(
25 ; IPSCCP-NEXT:  entry:
26 ; IPSCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
27 ; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
28 ; IPSCCP:       bb1:
29 ; IPSCCP-NEXT:    br label [[EXIT]]
30 ; IPSCCP:       exit:
31 ; IPSCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ]
32 ; IPSCCP-NEXT:    [[A:%.*]] = add i32 [[P]], 1
33 ; IPSCCP-NEXT:    call void @use(i1 true)
34 ; IPSCCP-NEXT:    call void @use(i1 false)
35 ; IPSCCP-NEXT:    ret void
37 entry:
38   %c.1 = call i1 @cond()
39   br i1 %c.1, label %bb1, label %exit
41 bb1:
42   br label %exit
44 exit:
45   %p = phi i32 [0, %entry], [1, %bb1]
46   %a = add i32 %p, 1
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)
51   ret void
54 define void @test_3_incoming_constants(i32 %x) {
55 ; SCCP-LABEL: @test_3_incoming_constants(
56 ; SCCP-NEXT:  entry:
57 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
58 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
59 ; SCCP:       bb1:
60 ; SCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
61 ; SCCP-NEXT:    br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
62 ; SCCP:       bb2:
63 ; SCCP-NEXT:    br label [[EXIT]]
64 ; SCCP:       exit:
65 ; SCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
66 ; SCCP-NEXT:    [[A:%.*]] = add i32 [[P]], 1
67 ; SCCP-NEXT:    call void @use(i1 true)
68 ; SCCP-NEXT:    call void @use(i1 false)
69 ; SCCP-NEXT:    ret void
71 ; IPSCCP-LABEL: @test_3_incoming_constants(
72 ; IPSCCP-NEXT:  entry:
73 ; IPSCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
74 ; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
75 ; IPSCCP:       bb1:
76 ; IPSCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
77 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
78 ; IPSCCP:       bb2:
79 ; IPSCCP-NEXT:    br label [[EXIT]]
80 ; IPSCCP:       exit:
81 ; IPSCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ]
82 ; IPSCCP-NEXT:    [[A:%.*]] = add i32 [[P]], 1
83 ; IPSCCP-NEXT:    call void @use(i1 true)
84 ; IPSCCP-NEXT:    call void @use(i1 false)
85 ; IPSCCP-NEXT:    ret void
87 entry:
88   %c.1 = call i1 @cond()
89   br i1 %c.1, label %bb1, label %exit
91 bb1:
92   %c.2 = call i1 @cond()
93   br i1 %c.2, label %bb2, label %exit
95 bb2:
96   br label %exit
98 exit:
99   %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2]
100   %a = add i32 %p, 1
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)
105   ret void
108 define void @test_5_incoming_constants(i32 %x) {
109 ; SCCP-LABEL: @test_5_incoming_constants(
110 ; SCCP-NEXT:  entry:
111 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
112 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
113 ; SCCP:       bb1:
114 ; SCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
115 ; SCCP-NEXT:    br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
116 ; SCCP:       bb2:
117 ; SCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
118 ; SCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
119 ; SCCP:       bb3:
120 ; SCCP-NEXT:    [[C_4:%.*]] = call i1 @cond()
121 ; SCCP-NEXT:    br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
122 ; SCCP:       bb4:
123 ; SCCP-NEXT:    br label [[EXIT]]
124 ; SCCP:       exit:
125 ; SCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
126 ; SCCP-NEXT:    [[A:%.*]] = add 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:%.*]]
135 ; IPSCCP:       bb1:
136 ; IPSCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
137 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
138 ; IPSCCP:       bb2:
139 ; IPSCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
140 ; IPSCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
141 ; IPSCCP:       bb3:
142 ; IPSCCP-NEXT:    [[C_4:%.*]] = call i1 @cond()
143 ; IPSCCP-NEXT:    br i1 [[C_4]], label [[BB4:%.*]], label [[EXIT]]
144 ; IPSCCP:       bb4:
145 ; IPSCCP-NEXT:    br label [[EXIT]]
146 ; IPSCCP:       exit:
147 ; IPSCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[BB1]] ], [ 2, [[BB2]] ], [ 3, [[BB3]] ], [ 4, [[BB4]] ]
148 ; IPSCCP-NEXT:    [[A:%.*]] = add i32 [[P]], 1
149 ; IPSCCP-NEXT:    call void @use(i1 true)
150 ; IPSCCP-NEXT:    call void @use(i1 false)
151 ; IPSCCP-NEXT:    ret void
153 entry:
154   %c.1 = call i1 @cond()
155   br i1 %c.1, label %bb1, label %exit
157 bb1:
158   %c.2 = call i1 @cond()
159   br i1 %c.2, label %bb2, label %exit
161 bb2:
162   %c.3 = call i1 @cond()
163   br i1 %c.3, label %bb3, label %exit
165 bb3:
166   %c.4 = call i1 @cond()
167   br i1 %c.4, label %bb4, label %exit
169 bb4:
170   br label %exit
172 exit:
173   %p = phi i32 [0, %entry], [1, %bb1], [2, %bb2], [3, %bb3], [4, %bb4]
174   %a = add i32 %p, 1
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)
179   ret void
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(
186 ; SCCP-NEXT:  entry:
187 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
188 ; SCCP-NEXT:    br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
189 ; SCCP:       bb1:
190 ; SCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
191 ; SCCP-NEXT:    br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
192 ; SCCP:       bb2:
193 ; SCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
194 ; SCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
195 ; SCCP:       bb3:
196 ; SCCP-NEXT:    br label [[EXIT]]
197 ; SCCP:       exit:
198 ; SCCP-NEXT:    [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ], [ [[A:%.*]], [[EXIT]] ]
199 ; SCCP-NEXT:    [[A]] = add i32 [[P]], 1
200 ; SCCP-NEXT:    call void @use(i1 true)
201 ; SCCP-NEXT:    call void @use(i1 false)
202 ; SCCP-NEXT:    br i1 false, label [[EXIT]], label [[EXIT_1:%.*]]
203 ; SCCP:       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:%.*]]
210 ; IPSCCP:       bb1:
211 ; IPSCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
212 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
213 ; IPSCCP:       bb2:
214 ; IPSCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
215 ; IPSCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
216 ; IPSCCP:       bb3:
217 ; IPSCCP-NEXT:    br label [[EXIT]]
218 ; IPSCCP:       exit:
219 ; IPSCCP-NEXT:    [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 3, [[BB1]] ], [ 2, [[BB2]] ], [ 5, [[BB3]] ]
220 ; IPSCCP-NEXT:    [[A:%.*]] = add 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:%.*]]
224 ; IPSCCP:       exit.1:
225 ; IPSCCP-NEXT:    ret void
227 entry:
228   %c.1 = call i1 @cond()
229   br i1 %c.1, label %exit, label %bb1
231 bb1:
232   %c.2 = call i1 @cond()
233   br i1 %c.2, label %exit, label %bb2
235 bb2:
236   %c.3 = call i1 @cond()
237   br i1 %c.3, label %bb3, label %exit
239 bb3:
240   br label %exit
242 exit:
243   %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
244   %a = add i32 %p, 1
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
252 exit.1:
253   ret void
256 define void @rotated_loop_3(i32 %x) {
257 ; SCCP-LABEL: @rotated_loop_3(
258 ; SCCP-NEXT:  entry:
259 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
260 ; SCCP-NEXT:    br i1 [[C_1]], label [[EXIT:%.*]], label [[BB1:%.*]]
261 ; SCCP:       bb1:
262 ; SCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
263 ; SCCP-NEXT:    br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
264 ; SCCP:       bb2:
265 ; SCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
266 ; SCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
267 ; SCCP:       bb3:
268 ; SCCP-NEXT:    br label [[EXIT]]
269 ; SCCP:       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:%.*]]
278 ; SCCP:       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:%.*]]
285 ; IPSCCP:       bb1:
286 ; IPSCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
287 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[EXIT]], label [[BB2:%.*]]
288 ; IPSCCP:       bb2:
289 ; IPSCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
290 ; IPSCCP-NEXT:    br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
291 ; IPSCCP:       bb3:
292 ; IPSCCP-NEXT:    br label [[EXIT]]
293 ; IPSCCP:       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:%.*]]
302 ; IPSCCP:       exit.1:
303 ; IPSCCP-NEXT:    ret void
305 entry:
306   %c.1 = call i1 @cond()
307   br i1 %c.1, label %exit, label %bb1
309 bb1:
310   %c.2 = call i1 @cond()
311   br i1 %c.2, label %exit, label %bb2
313 bb2:
314   %c.3 = call i1 @cond()
315   br i1 %c.3, label %bb3, label %exit
317 bb3:
318   br label %exit
320 exit:
321   %p = phi i32 [1, %entry], [3, %bb1], [2, %bb2], [5, %bb3], [%a, %exit]
322   %a = add i32 %p, 1
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
330 exit.1:
331   ret void
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(
338 ; SCCP-NEXT:  entry:
339 ; SCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
340 ; SCCP:       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:%.*]]
344 ; SCCP:       loop.body:
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]]
349 ; SCCP:       exit:
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:%.*]]
359 ; IPSCCP:       loop.body:
360 ; IPSCCP-NEXT:    call void @use(i1 true)
361 ; IPSCCP-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
362 ; IPSCCP-NEXT:    br label [[LOOP_HEADER]]
363 ; IPSCCP:       exit:
364 ; IPSCCP-NEXT:    ret void
366 entry:
367   br label %loop.header
369 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
374 loop.body:
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
380 exit:
381   ret void
384 define void @loop_with_header_2(i32 %x) {
385 ; SCCP-LABEL: @loop_with_header_2(
386 ; SCCP-NEXT:  entry:
387 ; SCCP-NEXT:    br label [[LOOP_HEADER:%.*]]
388 ; SCCP:       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:%.*]]
392 ; SCCP:       loop.body:
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]]
397 ; SCCP:       exit:
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:%.*]]
407 ; IPSCCP:       loop.body:
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]]
411 ; IPSCCP:       exit:
412 ; IPSCCP-NEXT:    ret void
414 entry:
415   br label %loop.header
417 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
422 loop.body:
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
428 exit:
429   ret void
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(i64* %arg) {
436 ; SCCP-LABEL: @foo(
437 ; SCCP-NEXT:  bb:
438 ; SCCP-NEXT:    [[TMP:%.*]] = zext i8 undef to i32
439 ; SCCP-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0
440 ; SCCP-NEXT:    [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8
441 ; SCCP-NEXT:    switch i32 [[TMP]], label [[BB20:%.*]] [
442 ; SCCP-NEXT:    i32 1, label [[BB3:%.*]]
443 ; SCCP-NEXT:    i32 2, label [[BB4:%.*]]
444 ; SCCP-NEXT:    i32 4, label [[BB19:%.*]]
445 ; SCCP-NEXT:    ]
446 ; SCCP:       bb3:
447 ; SCCP-NEXT:    unreachable
448 ; SCCP:       bb4:
449 ; SCCP-NEXT:    [[TMP5:%.*]] = add i64 [[TMP2]], 3
450 ; SCCP-NEXT:    [[TMP6:%.*]] = and i64 [[TMP5]], 3
451 ; SCCP-NEXT:    [[TMP7:%.*]] = sub i64 3, [[TMP6]]
452 ; SCCP-NEXT:    [[TMP8:%.*]] = shl i64 [[TMP7]], 1
453 ; SCCP-NEXT:    [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
454 ; SCCP-NEXT:    [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
455 ; SCCP-NEXT:    br label [[BB11:%.*]]
456 ; SCCP:       bb11:
457 ; SCCP-NEXT:    [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
458 ; SCCP-NEXT:    br label [[BB13:%.*]]
459 ; SCCP:       bb13:
460 ; SCCP-NEXT:    [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
461 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
462 ; SCCP:       bb15:
463 ; SCCP-NEXT:    unreachable
464 ; SCCP:       bb16:
465 ; SCCP-NEXT:    [[TMP17]] = add i64 [[TMP12]], 2
466 ; SCCP-NEXT:    br label [[BB18]]
467 ; SCCP:       bb18:
468 ; SCCP-NEXT:    br label [[BB11]]
469 ; SCCP:       bb19:
470 ; SCCP-NEXT:    unreachable
471 ; SCCP:       bb20:
472 ; SCCP-NEXT:    ret void
474 ; IPSCCP-LABEL: @foo(
475 ; IPSCCP-NEXT:  bb:
476 ; IPSCCP-NEXT:    [[TMP:%.*]] = zext i8 undef to i32
477 ; IPSCCP-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, i64* [[ARG:%.*]], i32 0
478 ; IPSCCP-NEXT:    [[TMP2:%.*]] = load i64, i64* [[TMP1]], align 8
479 ; IPSCCP-NEXT:    switch i32 [[TMP]], label [[BB20:%.*]] [
480 ; IPSCCP-NEXT:    i32 1, label [[BB3:%.*]]
481 ; IPSCCP-NEXT:    i32 2, label [[BB4:%.*]]
482 ; IPSCCP-NEXT:    i32 4, label [[BB19:%.*]]
483 ; IPSCCP-NEXT:    ]
484 ; IPSCCP:       bb3:
485 ; IPSCCP-NEXT:    unreachable
486 ; IPSCCP:       bb4:
487 ; IPSCCP-NEXT:    [[TMP5:%.*]] = add i64 [[TMP2]], 3
488 ; IPSCCP-NEXT:    [[TMP6:%.*]] = and i64 [[TMP5]], 3
489 ; IPSCCP-NEXT:    [[TMP7:%.*]] = sub i64 3, [[TMP6]]
490 ; IPSCCP-NEXT:    [[TMP8:%.*]] = shl i64 [[TMP7]], 1
491 ; IPSCCP-NEXT:    [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
492 ; IPSCCP-NEXT:    [[TMP0:%.*]] = zext i32 [[TMP9]] to i64
493 ; IPSCCP-NEXT:    br label [[BB11:%.*]]
494 ; IPSCCP:       bb11:
495 ; IPSCCP-NEXT:    [[TMP12:%.*]] = phi i64 [ [[TMP0]], [[BB4]] ], [ [[TMP17:%.*]], [[BB18:%.*]] ]
496 ; IPSCCP-NEXT:    br label [[BB13:%.*]]
497 ; IPSCCP:       bb13:
498 ; IPSCCP-NEXT:    [[C_1:%.*]] = icmp eq i64 [[TMP12]], 6
499 ; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB15:%.*]], label [[BB16:%.*]]
500 ; IPSCCP:       bb15:
501 ; IPSCCP-NEXT:    unreachable
502 ; IPSCCP:       bb16:
503 ; IPSCCP-NEXT:    [[TMP17]] = add i64 [[TMP12]], 2
504 ; IPSCCP-NEXT:    br label [[BB18]]
505 ; IPSCCP:       bb18:
506 ; IPSCCP-NEXT:    br label [[BB11]]
507 ; IPSCCP:       bb19:
508 ; IPSCCP-NEXT:    unreachable
509 ; IPSCCP:       bb20:
510 ; IPSCCP-NEXT:    ret void
513   %tmp = zext i8 undef to i32
514   %tmp1 = getelementptr inbounds i64, i64* %arg, i32 0
515   %tmp2 = load i64, i64* %tmp1, align 8
516   switch i32 %tmp, label %bb20 [
517   i32 1, label %bb3
518   i32 2, label %bb4
519   i32 4, label %bb19
520   ]
522 bb3:                                              ; preds = %bb
523   unreachable
525 bb4:                                              ; preds = %bb
526   %tmp5 = add i64 %tmp2, 3
527   %tmp6 = and i64 %tmp5, 3
528   %tmp7 = sub i64 3, %tmp6
529   %tmp8 = shl i64 %tmp7, 1
530   %tmp9 = trunc i64 %tmp8 to i32
531   %tmp10 = sext i32 %tmp9 to i64
532   br label %bb11
534 bb11:                                             ; preds = %bb18, %bb4
535   %tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ]
536   br label %bb13
538 bb13:                                             ; preds = %bb11
539   %c.1 = icmp eq i64 %tmp12, 6
540   br i1 %c.1, label %bb15, label %bb16
542 bb15:                                             ; preds = %bb13
543   unreachable
545 bb16:                                             ; preds = %bb13
546   %tmp17 = add i64 %tmp12, 2
547   br label %bb18
549 bb18:                                             ; preds = %bb16
550   br label %bb11
552 bb19:                                             ; preds = %bb
553   unreachable
555 bb20:                                             ; preds = %bb
556   ret void
559 ; The functions below check that widening with an upper bound does correctly
560 ; return whether the range changed. Make sure we do not eliminate %c.2.
562 %struct.baz.1 = type { i32, i32, i8*, i8* }
563 %struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }>
565 @global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1
567 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1
569 define linkonce_odr dereferenceable(1) i8* @spam(%struct.baz.1* %arg, i32 %arg1) align 2 {
570 ; SCCP-LABEL: @spam(
571 ; SCCP-NEXT:  bb:
572 ; SCCP-NEXT:    [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3
573 ; SCCP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8
574 ; SCCP-NEXT:    [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
575 ; SCCP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]]
576 ; SCCP-NEXT:    ret i8* [[TMP4]]
578 ; IPSCCP-LABEL: @spam(
579 ; IPSCCP-NEXT:  bb:
580 ; IPSCCP-NEXT:    [[TMP:%.*]] = getelementptr inbounds [[STRUCT_BAZ_1:%.*]], %struct.baz.1* [[ARG:%.*]], i32 0, i32 3
581 ; IPSCCP-NEXT:    [[TMP2:%.*]] = load i8*, i8** [[TMP]], align 8
582 ; IPSCCP-NEXT:    [[TMP3:%.*]] = sext i32 [[ARG1:%.*]] to i64
583 ; IPSCCP-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[TMP2]], i64 [[TMP3]]
584 ; IPSCCP-NEXT:    ret i8* [[TMP4]]
587   %tmp = getelementptr inbounds %struct.baz.1, %struct.baz.1* %arg, i32 0, i32 3
588   %tmp2 = load i8*, i8** %tmp, align 8
589   %tmp3 = sext i32 %arg1 to i64
590   %tmp4 = getelementptr inbounds i8, i8* %tmp2, i64 %tmp3
591   ret i8* %tmp4
594 define i8* @wobble(%struct.blam.2* %arg, i32 %arg1) align 2 {
595 ; SCCP-LABEL: @wobble(
596 ; SCCP-NEXT:  bb:
597 ; SCCP-NEXT:    [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
598 ; SCCP-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
599 ; SCCP-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 65535
600 ; SCCP-NEXT:    [[TMP4:%.*]] = mul i32 [[ARG1]], 8
601 ; SCCP-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1
602 ; SCCP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8
603 ; SCCP-NEXT:    [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
604 ; SCCP-NEXT:    br label [[BB8:%.*]]
605 ; SCCP:       bb8:
606 ; SCCP-NEXT:    [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
607 ; SCCP-NEXT:    [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ]
608 ; SCCP-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
609 ; SCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
610 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
611 ; SCCP:       bb13:
612 ; SCCP-NEXT:    [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
613 ; SCCP-NEXT:    [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
614 ; SCCP-NEXT:    [[TMP16:%.*]] = mul i32 [[TMP15]], 4
615 ; SCCP-NEXT:    [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]])
616 ; SCCP-NEXT:    [[TMP18]] = bitcast i8* [[TMP17]] to i16*
617 ; SCCP-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2
618 ; SCCP-NEXT:    [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1
619 ; SCCP-NEXT:    [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
620 ; SCCP-NEXT:    [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
621 ; SCCP-NEXT:    br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
622 ; SCCP:       bb23:
623 ; SCCP-NEXT:    [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
624 ; SCCP-NEXT:    store i16 [[TMP24]], i16* [[TMP18]], align 2
625 ; SCCP-NEXT:    br label [[BB31]]
626 ; SCCP:       bb25:
627 ; SCCP-NEXT:    [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2
628 ; SCCP-NEXT:    [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
629 ; SCCP-NEXT:    [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
630 ; SCCP-NEXT:    br i1 [[TMP28]], label [[BB31]], label [[BB29]]
631 ; SCCP:       bb29:
632 ; SCCP-NEXT:    [[TMP30]] = add nsw i32 [[TMP11]], 1
633 ; SCCP-NEXT:    br label [[BB8]]
634 ; SCCP:       bb31:
635 ; SCCP-NEXT:    [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
636 ; SCCP-NEXT:    [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
637 ; SCCP-NEXT:    [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
638 ; SCCP-NEXT:    br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
639 ; SCCP:       bb35:
640 ; SCCP-NEXT:    [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1
641 ; SCCP-NEXT:    br label [[BB66:%.*]]
642 ; SCCP:       bb37:
643 ; SCCP-NEXT:    [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
644 ; SCCP-NEXT:    br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
645 ; SCCP:       bb39:
646 ; SCCP-NEXT:    [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
647 ; SCCP-NEXT:    [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
648 ; SCCP-NEXT:    store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
649 ; SCCP-NEXT:    [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
650 ; SCCP-NEXT:    [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
651 ; SCCP-NEXT:    [[TMP44:%.*]] = mul i32 [[TMP43]], 4
652 ; SCCP-NEXT:    [[TMP45:%.*]] = add i32 [[TMP44]], 2
653 ; SCCP-NEXT:    [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]])
654 ; SCCP-NEXT:    [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1
655 ; SCCP-NEXT:    [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
656 ; SCCP-NEXT:    [[TMP49:%.*]] = sub i32 [[TMP43]], 1
657 ; SCCP-NEXT:    [[TMP50:%.*]] = mul i32 [[TMP49]], 4
658 ; SCCP-NEXT:    [[TMP51:%.*]] = add i32 [[TMP50]], 2
659 ; SCCP-NEXT:    [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]])
660 ; SCCP-NEXT:    [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1
661 ; SCCP-NEXT:    [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
662 ; SCCP-NEXT:    [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
663 ; SCCP-NEXT:    br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
664 ; SCCP:       bb56:
665 ; SCCP-NEXT:    [[TMP57:%.*]] = add nsw i32 [[TMP40]], -1
666 ; SCCP-NEXT:    br label [[BB60]]
667 ; SCCP:       bb58:
668 ; SCCP-NEXT:    [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8*
669 ; SCCP-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false)
670 ; SCCP-NEXT:    br label [[BB60]]
671 ; SCCP:       bb60:
672 ; SCCP-NEXT:    [[TMP61:%.*]] = phi i32 [ [[TMP57]], [[BB56]] ], [ [[TMP40]], [[BB39]] ], [ [[TMP11]], [[BB58]] ]
673 ; SCCP-NEXT:    [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
674 ; SCCP-NEXT:    [[TMP63:%.*]] = add i32 [[TMP7]], 1
675 ; SCCP-NEXT:    [[TMP64:%.*]] = mul i32 [[TMP63]], 4
676 ; SCCP-NEXT:    [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]])
677 ; SCCP-NEXT:    br label [[BB66]]
678 ; SCCP:       bb66:
679 ; SCCP-NEXT:    [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
680 ; SCCP-NEXT:    ret i8* [[TMP67]]
682 ; IPSCCP-LABEL: @wobble(
683 ; IPSCCP-NEXT:  bb:
684 ; IPSCCP-NEXT:    [[TMP:%.*]] = lshr i32 [[ARG1:%.*]], 16
685 ; IPSCCP-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP]], [[ARG1]]
686 ; IPSCCP-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 65535
687 ; IPSCCP-NEXT:    [[TMP4:%.*]] = mul i32 [[ARG1]], 8
688 ; IPSCCP-NEXT:    [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2:%.*]], %struct.blam.2* [[ARG:%.*]], i32 0, i32 1
689 ; IPSCCP-NEXT:    [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 8
690 ; IPSCCP-NEXT:    [[TMP7:%.*]] = and i32 [[TMP4]], [[TMP6]]
691 ; IPSCCP-NEXT:    br label [[BB8:%.*]]
692 ; IPSCCP:       bb8:
693 ; IPSCCP-NEXT:    [[TMP9:%.*]] = phi i8* [ undef, [[BB:%.*]] ], [ [[TMP17:%.*]], [[BB29:%.*]] ]
694 ; IPSCCP-NEXT:    [[TMP10:%.*]] = phi i16* [ undef, [[BB]] ], [ [[TMP18:%.*]], [[BB29]] ]
695 ; IPSCCP-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP30:%.*]], [[BB29]] ]
696 ; IPSCCP-NEXT:    [[C_1:%.*]] = icmp slt i32 [[TMP11]], 8
697 ; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB13:%.*]], label [[BB31:%.*]]
698 ; IPSCCP:       bb13:
699 ; IPSCCP-NEXT:    [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
700 ; IPSCCP-NEXT:    [[TMP15:%.*]] = add i32 [[TMP7]], [[TMP11]]
701 ; IPSCCP-NEXT:    [[TMP16:%.*]] = mul i32 [[TMP15]], 4
702 ; IPSCCP-NEXT:    [[TMP17]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP14]], i32 [[TMP16]])
703 ; IPSCCP-NEXT:    [[TMP18]] = bitcast i8* [[TMP17]] to i16*
704 ; IPSCCP-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP17]], i64 2
705 ; IPSCCP-NEXT:    [[TMP20:%.*]] = load i8, i8* [[TMP19]], align 1
706 ; IPSCCP-NEXT:    [[TMP21:%.*]] = zext i8 [[TMP20]] to i32
707 ; IPSCCP-NEXT:    [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
708 ; IPSCCP-NEXT:    br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
709 ; IPSCCP:       bb23:
710 ; IPSCCP-NEXT:    [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
711 ; IPSCCP-NEXT:    store i16 [[TMP24]], i16* [[TMP18]], align 2
712 ; IPSCCP-NEXT:    br label [[BB31]]
713 ; IPSCCP:       bb25:
714 ; IPSCCP-NEXT:    [[TMP26:%.*]] = load i16, i16* [[TMP18]], align 2
715 ; IPSCCP-NEXT:    [[TMP27:%.*]] = zext i16 [[TMP26]] to i32
716 ; IPSCCP-NEXT:    [[TMP28:%.*]] = icmp eq i32 [[TMP27]], [[TMP3]]
717 ; IPSCCP-NEXT:    br i1 [[TMP28]], label [[BB31]], label [[BB29]]
718 ; IPSCCP:       bb29:
719 ; IPSCCP-NEXT:    [[TMP30]] = add nsw i32 [[TMP11]], 1
720 ; IPSCCP-NEXT:    br label [[BB8]]
721 ; IPSCCP:       bb31:
722 ; IPSCCP-NEXT:    [[TMP32:%.*]] = phi i8* [ [[TMP17]], [[BB23]] ], [ [[TMP17]], [[BB25]] ], [ [[TMP9]], [[BB8]] ]
723 ; IPSCCP-NEXT:    [[TMP33:%.*]] = phi i16* [ [[TMP18]], [[BB23]] ], [ [[TMP18]], [[BB25]] ], [ [[TMP10]], [[BB8]] ]
724 ; IPSCCP-NEXT:    [[TMP34:%.*]] = icmp eq i32 [[TMP11]], 0
725 ; IPSCCP-NEXT:    br i1 [[TMP34]], label [[BB35:%.*]], label [[BB37:%.*]]
726 ; IPSCCP:       bb35:
727 ; IPSCCP-NEXT:    [[TMP36:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 1
728 ; IPSCCP-NEXT:    br label [[BB66:%.*]]
729 ; IPSCCP:       bb37:
730 ; IPSCCP-NEXT:    [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
731 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
732 ; IPSCCP:       bb39:
733 ; IPSCCP-NEXT:    [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
734 ; IPSCCP-NEXT:    store i16 [[TMP41]], i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
735 ; IPSCCP-NEXT:    [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
736 ; IPSCCP-NEXT:    [[TMP43:%.*]] = add i32 [[TMP7]], 7
737 ; IPSCCP-NEXT:    [[TMP44:%.*]] = mul i32 [[TMP43]], 4
738 ; IPSCCP-NEXT:    [[TMP45:%.*]] = add i32 [[TMP44]], 2
739 ; IPSCCP-NEXT:    [[TMP46:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP45]])
740 ; IPSCCP-NEXT:    [[TMP47:%.*]] = load i8, i8* [[TMP46]], align 1
741 ; IPSCCP-NEXT:    [[TMP48:%.*]] = zext i8 [[TMP47]] to i32
742 ; IPSCCP-NEXT:    [[TMP49:%.*]] = sub i32 [[TMP43]], 1
743 ; IPSCCP-NEXT:    [[TMP50:%.*]] = mul i32 [[TMP49]], 4
744 ; IPSCCP-NEXT:    [[TMP51:%.*]] = add i32 [[TMP50]], 2
745 ; IPSCCP-NEXT:    [[TMP52:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP42]], i32 [[TMP51]])
746 ; IPSCCP-NEXT:    [[TMP53:%.*]] = load i8, i8* [[TMP52]], align 1
747 ; IPSCCP-NEXT:    [[TMP54:%.*]] = zext i8 [[TMP53]] to i32
748 ; IPSCCP-NEXT:    [[TMP55:%.*]] = icmp sgt i32 [[TMP48]], [[TMP54]]
749 ; IPSCCP-NEXT:    br i1 [[TMP55]], label [[BB56:%.*]], label [[BB60:%.*]]
750 ; IPSCCP:       bb56:
751 ; IPSCCP-NEXT:    br label [[BB60]]
752 ; IPSCCP:       bb58:
753 ; IPSCCP-NEXT:    [[TMP59:%.*]] = bitcast i16* [[TMP33]] to i8*
754 ; IPSCCP-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 [[TMP59]], i64 4, i1 false)
755 ; IPSCCP-NEXT:    br label [[BB60]]
756 ; IPSCCP:       bb60:
757 ; IPSCCP-NEXT:    [[TMP61:%.*]] = phi i32 [ 6, [[BB56]] ], [ 7, [[BB39]] ], [ [[TMP11]], [[BB58]] ]
758 ; IPSCCP-NEXT:    [[TMP62:%.*]] = getelementptr inbounds [[STRUCT_BLAM_2]], %struct.blam.2* [[ARG]], i32 0, i32 0
759 ; IPSCCP-NEXT:    [[TMP63:%.*]] = add i32 [[TMP7]], 1
760 ; IPSCCP-NEXT:    [[TMP64:%.*]] = mul i32 [[TMP63]], 4
761 ; IPSCCP-NEXT:    [[TMP65:%.*]] = call dereferenceable(1) i8* @spam(%struct.baz.1* [[TMP62]], i32 [[TMP64]])
762 ; IPSCCP-NEXT:    br label [[BB66]]
763 ; IPSCCP:       bb66:
764 ; IPSCCP-NEXT:    [[TMP67:%.*]] = phi i8* [ [[TMP36]], [[BB35]] ], [ null, [[BB60]] ]
765 ; IPSCCP-NEXT:    ret i8* [[TMP67]]
768   %tmp = lshr i32 %arg1, 16
769   %tmp2 = xor i32 %tmp, %arg1
770   %tmp3 = and i32 %tmp2, 65535
771   %tmp4 = mul i32 %arg1, 8
772   %tmp5 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 1
773   %tmp6 = load i32, i32* %tmp5, align 8
774   %tmp7 = and i32 %tmp4, %tmp6
775   br label %bb8
777 bb8:                                              ; preds = %bb29, %bb
778   %tmp9 = phi i8* [ undef, %bb ], [ %tmp17, %bb29 ]
779   %tmp10 = phi i16* [ undef, %bb ], [ %tmp18, %bb29 ]
780   %tmp11 = phi i32 [ 0, %bb ], [ %tmp30, %bb29 ]
781   %c.1 = icmp slt i32 %tmp11, 8
782   br i1 %c.1, label %bb13, label %bb31
784 bb13:                                             ; preds = %bb8
785   %tmp14 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
786   %tmp15 = add i32 %tmp7, %tmp11
787   %tmp16 = mul i32 %tmp15, 4
788   %tmp17 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp14, i32 %tmp16)
789   %tmp18 = bitcast i8* %tmp17 to i16*
790   %tmp19 = getelementptr inbounds i8, i8* %tmp17, i64 2
791   %tmp20 = load i8, i8* %tmp19, align 1
792   %tmp21 = zext i8 %tmp20 to i32
793   %tmp22 = icmp eq i32 %tmp21, 0
794   br i1 %tmp22, label %bb23, label %bb25
796 bb23:                                             ; preds = %bb13
797   %tmp24 = trunc i32 %tmp3 to i16
798   store i16 %tmp24, i16* %tmp18, align 2
799   br label %bb31
801 bb25:                                             ; preds = %bb13
802   %tmp26 = load i16, i16* %tmp18, align 2
803   %tmp27 = zext i16 %tmp26 to i32
804   %tmp28 = icmp eq i32 %tmp27, %tmp3
805   br i1 %tmp28, label %bb31, label %bb29
807 bb29:                                             ; preds = %bb25
808   %tmp30 = add nsw i32 %tmp11, 1
809   br label %bb8
811 bb31:                                             ; preds = %bb25, %bb23, %bb8
812   %tmp32 = phi i8* [ %tmp17, %bb23 ], [ %tmp17, %bb25 ], [ %tmp9, %bb8 ]
813   %tmp33 = phi i16* [ %tmp18, %bb23 ], [ %tmp18, %bb25 ], [ %tmp10, %bb8 ]
814   %tmp34 = icmp eq i32 %tmp11, 0
815   br i1 %tmp34, label %bb35, label %bb37
817 bb35:                                             ; preds = %bb31
818   %tmp36 = getelementptr inbounds i8, i8* %tmp32, i64 1
819   br label %bb66
821 bb37:                                             ; preds = %bb31
822   %c.2 = icmp eq i32 %tmp11, 8
823   br i1 %c.2, label %bb39, label %bb58
825 bb39:                                             ; preds = %bb37
826   %tmp40 = add nsw i32 %tmp11, -1
827   %tmp41 = trunc i32 %tmp3 to i16
828   store i16 %tmp41, i16* bitcast ([4 x i8]* @global.11 to i16*), align 1
829   %tmp42 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
830   %tmp43 = add i32 %tmp7, %tmp40
831   %tmp44 = mul i32 %tmp43, 4
832   %tmp45 = add i32 %tmp44, 2
833   %tmp46 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp45)
834   %tmp47 = load i8, i8* %tmp46, align 1
835   %tmp48 = zext i8 %tmp47 to i32
836   %tmp49 = sub i32 %tmp43, 1
837   %tmp50 = mul i32 %tmp49, 4
838   %tmp51 = add i32 %tmp50, 2
839   %tmp52 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp42, i32 %tmp51)
840   %tmp53 = load i8, i8* %tmp52, align 1
841   %tmp54 = zext i8 %tmp53 to i32
842   %tmp55 = icmp sgt i32 %tmp48, %tmp54
843   br i1 %tmp55, label %bb56, label %bb60
845 bb56:                                             ; preds = %bb39
846   %tmp57 = add nsw i32 %tmp40, -1
847   br label %bb60
849 bb58:                                             ; preds = %bb37
850   %tmp59 = bitcast i16* %tmp33 to i8*
851   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 getelementptr inbounds ([4 x i8], [4 x i8]* @global.11, i64 0, i64 0), i8* align 2 %tmp59, i64 4, i1 false)
852   br label %bb60
854 bb60:                                             ; preds = %bb58, %bb56, %bb39
855   %tmp61 = phi i32 [ %tmp57, %bb56 ], [ %tmp40, %bb39 ], [ %tmp11, %bb58 ]
856   %tmp62 = getelementptr inbounds %struct.blam.2, %struct.blam.2* %arg, i32 0, i32 0
857   %tmp63 = add i32 %tmp7, 1
858   %tmp64 = mul i32 %tmp63, 4
859   %tmp65 = call dereferenceable(1) i8* @spam(%struct.baz.1* %tmp62, i32 %tmp64)
860   br label %bb66
862 bb66:                                             ; preds = %bb60, %bb35
863   %tmp67 = phi i8* [ %tmp36, %bb35 ], [ null, %bb60 ]
864   ret i8* %tmp67
868 define i32 @loop_with_multiple_euqal_incomings(i32 %N) {
869 ; SCCP-LABEL: @loop_with_multiple_euqal_incomings(
870 ; SCCP-NEXT:  entry:
871 ; SCCP-NEXT:    br label [[LOOP:%.*]]
872 ; SCCP:       loop:
873 ; SCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
874 ; SCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
875 ; SCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
876 ; SCCP:       bb1:
877 ; SCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
878 ; SCCP-NEXT:    br i1 [[C_2]], label [[BB3]], label [[BB4]]
879 ; SCCP:       bb2:
880 ; SCCP-NEXT:    [[C_4:%.*]] = call i1 @cond()
881 ; SCCP-NEXT:    br i1 [[C_4]], label [[BB5]], label [[BB6]]
882 ; SCCP:       bb3:
883 ; SCCP-NEXT:    [[P_NEXT]] = add i32 [[P]], 1
884 ; SCCP-NEXT:    br label [[LOOP]]
885 ; SCCP:       bb4:
886 ; SCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
887 ; SCCP-NEXT:    br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
888 ; SCCP:       bb5:
889 ; SCCP-NEXT:    br label [[LOOP]]
890 ; SCCP:       bb6:
891 ; SCCP-NEXT:    br label [[LOOP]]
892 ; SCCP:       end:
893 ; SCCP-NEXT:    ret i32 [[P]]
895 ; IPSCCP-LABEL: @loop_with_multiple_euqal_incomings(
896 ; IPSCCP-NEXT:  entry:
897 ; IPSCCP-NEXT:    br label [[LOOP:%.*]]
898 ; IPSCCP:       loop:
899 ; IPSCCP-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[BB3:%.*]] ], [ 0, [[BB4:%.*]] ], [ 0, [[BB5:%.*]] ], [ 0, [[BB6:%.*]] ]
900 ; IPSCCP-NEXT:    [[C_1:%.*]] = call i1 @cond()
901 ; IPSCCP-NEXT:    br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
902 ; IPSCCP:       bb1:
903 ; IPSCCP-NEXT:    [[C_2:%.*]] = call i1 @cond()
904 ; IPSCCP-NEXT:    br i1 [[C_2]], label [[BB3]], label [[BB4]]
905 ; IPSCCP:       bb2:
906 ; IPSCCP-NEXT:    [[C_4:%.*]] = call i1 @cond()
907 ; IPSCCP-NEXT:    br i1 [[C_4]], label [[BB5]], label [[BB6]]
908 ; IPSCCP:       bb3:
909 ; IPSCCP-NEXT:    [[P_NEXT]] = add i32 [[P]], 1
910 ; IPSCCP-NEXT:    br label [[LOOP]]
911 ; IPSCCP:       bb4:
912 ; IPSCCP-NEXT:    [[C_3:%.*]] = call i1 @cond()
913 ; IPSCCP-NEXT:    br i1 [[C_3]], label [[LOOP]], label [[END:%.*]]
914 ; IPSCCP:       bb5:
915 ; IPSCCP-NEXT:    br label [[LOOP]]
916 ; IPSCCP:       bb6:
917 ; IPSCCP-NEXT:    br label [[LOOP]]
918 ; IPSCCP:       end:
919 ; IPSCCP-NEXT:    ret i32 [[P]]
921 entry:
922   br label %loop
924 loop:
925   %p = phi i32 [ 0, %entry ], [ %p.next, %bb3 ], [ 0, %bb4 ], [ 0, %bb5], [ 0, %bb6 ]
926   %c.1 = call i1 @cond()
927   br i1 %c.1, label %bb1, label %bb2
929 bb1:
930   %c.2 = call i1 @cond()
931   br i1 %c.2, label %bb3, label %bb4
933 bb2:
934   %c.4 = call i1 @cond()
935   br i1 %c.4, label %bb5, label %bb6
937 bb3:
938   %p.next = add i32 %p, 1
939   br label %loop
941 bb4:
942   %c.3 = call i1 @cond()
943   br i1 %c.3, label %loop, label %end
945 bb5:
946   br label %loop
948 bb6:
949   br label %loop
951 end:
952   ret i32 %p