• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
4
5; Test different widening scenarios.
6
7declare void @use(i1)
8declare i1 @cond()
9
10define 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
23;
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
36;
37entry:
38  %c.1 = call i1 @cond()
39  br i1 %c.1, label %bb1, label %exit
40
41bb1:
42  br label %exit
43
44exit:
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
52}
53
54define 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
70;
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
86;
87entry:
88  %c.1 = call i1 @cond()
89  br i1 %c.1, label %bb1, label %exit
90
91bb1:
92  %c.2 = call i1 @cond()
93  br i1 %c.2, label %bb2, label %exit
94
95bb2:
96  br label %exit
97
98exit:
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
106}
107
108define 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
130;
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
152;
153entry:
154  %c.1 = call i1 @cond()
155  br i1 %c.1, label %bb1, label %exit
156
157bb1:
158  %c.2 = call i1 @cond()
159  br i1 %c.2, label %bb2, label %exit
160
161bb2:
162  %c.3 = call i1 @cond()
163  br i1 %c.3, label %bb3, label %exit
164
165bb3:
166  %c.4 = call i1 @cond()
167  br i1 %c.4, label %bb4, label %exit
168
169bb4:
170  br label %exit
171
172exit:
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
180}
181
182; For the rotated_loop_* test cases %p and %a are extended on each iteration.
183
184define 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
205;
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
226;
227entry:
228  %c.1 = call i1 @cond()
229  br i1 %c.1, label %exit, label %bb1
230
231bb1:
232  %c.2 = call i1 @cond()
233  br i1 %c.2, label %exit, label %bb2
234
235bb2:
236  %c.3 = call i1 @cond()
237  br i1 %c.3, label %bb3, label %exit
238
239bb3:
240  br label %exit
241
242exit:
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
251
252exit.1:
253  ret void
254}
255
256define 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
280;
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
304;
305entry:
306  %c.1 = call i1 @cond()
307  br i1 %c.1, label %exit, label %bb1
308
309bb1:
310  %c.2 = call i1 @cond()
311  br i1 %c.2, label %exit, label %bb2
312
313bb2:
314  %c.3 = call i1 @cond()
315  br i1 %c.3, label %bb3, label %exit
316
317bb3:
318  br label %exit
319
320exit:
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
329
330exit.1:
331  ret void
332}
333
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.
336define 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
351;
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
365;
366entry:
367  br label %loop.header
368
369loop.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
373
374loop.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
379
380exit:
381  ret void
382}
383
384define 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
399;
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
413;
414entry:
415  br label %loop.header
416
417loop.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
421
422loop.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
427
428exit:
429  ret void
430}
431
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.
435define 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
473;
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
511;
512bb:
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  ]
521
522bb3:                                              ; preds = %bb
523  unreachable
524
525bb4:                                              ; 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
533
534bb11:                                             ; preds = %bb18, %bb4
535  %tmp12 = phi i64 [ %tmp10, %bb4 ], [ %tmp17, %bb18 ]
536  br label %bb13
537
538bb13:                                             ; preds = %bb11
539  %c.1 = icmp eq i64 %tmp12, 6
540  br i1 %c.1, label %bb15, label %bb16
541
542bb15:                                             ; preds = %bb13
543  unreachable
544
545bb16:                                             ; preds = %bb13
546  %tmp17 = add i64 %tmp12, 2
547  br label %bb18
548
549bb18:                                             ; preds = %bb16
550  br label %bb11
551
552bb19:                                             ; preds = %bb
553  unreachable
554
555bb20:                                             ; preds = %bb
556  ret void
557}
558
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.
561
562%struct.baz.1 = type { i32, i32, i8*, i8* }
563%struct.blam.2 = type <{ %struct.baz.1, i32, [4 x i8] }>
564
565@global.11 = linkonce_odr global [4 x i8] zeroinitializer, align 1
566
567declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1
568
569define 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]]
577;
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]]
585;
586bb:
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
592}
593
594define 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]]
681;
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]]
766;
767bb:
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
776
777bb8:                                              ; 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
783
784bb13:                                             ; 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
795
796bb23:                                             ; preds = %bb13
797  %tmp24 = trunc i32 %tmp3 to i16
798  store i16 %tmp24, i16* %tmp18, align 2
799  br label %bb31
800
801bb25:                                             ; 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
806
807bb29:                                             ; preds = %bb25
808  %tmp30 = add nsw i32 %tmp11, 1
809  br label %bb8
810
811bb31:                                             ; 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
816
817bb35:                                             ; preds = %bb31
818  %tmp36 = getelementptr inbounds i8, i8* %tmp32, i64 1
819  br label %bb66
820
821bb37:                                             ; preds = %bb31
822  %c.2 = icmp eq i32 %tmp11, 8
823  br i1 %c.2, label %bb39, label %bb58
824
825bb39:                                             ; 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
844
845bb56:                                             ; preds = %bb39
846  %tmp57 = add nsw i32 %tmp40, -1
847  br label %bb60
848
849bb58:                                             ; 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
853
854bb60:                                             ; 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
861
862bb66:                                             ; preds = %bb60, %bb35
863  %tmp67 = phi i8* [ %tmp36, %bb35 ], [ null, %bb60 ]
864  ret i8* %tmp67
865}
866
867
868define 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]]
894;
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]]
920;
921entry:
922  br label %loop
923
924loop:
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
928
929bb1:
930  %c.2 = call i1 @cond()
931  br i1 %c.2, label %bb3, label %bb4
932
933bb2:
934  %c.4 = call i1 @cond()
935  br i1 %c.4, label %bb5, label %bb6
936
937bb3:
938  %p.next = add i32 %p, 1
939  br label %loop
940
941bb4:
942  %c.3 = call i1 @cond()
943  br i1 %c.3, label %loop, label %end
944
945bb5:
946  br label %loop
947
948bb6:
949  br label %loop
950
951end:
952  ret i32 %p
953}
954