1; RUN: opt -correlated-propagation -S < %s | FileCheck %s
2
3declare i32 @foo()
4
5define i32 @test1(i32 %a) nounwind {
6  %a.off = add i32 %a, -8
7  %cmp = icmp ult i32 %a.off, 8
8  br i1 %cmp, label %then, label %else
9
10then:
11  %dead = icmp eq i32 %a, 7
12  br i1 %dead, label %end, label %else
13
14else:
15  ret i32 1
16
17end:
18  ret i32 2
19
20; CHECK-LABEL: @test1(
21; CHECK: then:
22; CHECK-NEXT: br i1 false, label %end, label %else
23}
24
25define i32 @test2(i32 %a) nounwind {
26  %a.off = add i32 %a, -8
27  %cmp = icmp ult i32 %a.off, 8
28  br i1 %cmp, label %then, label %else
29
30then:
31  %dead = icmp ugt i32 %a, 15
32  br i1 %dead, label %end, label %else
33
34else:
35  ret i32 1
36
37end:
38  ret i32 2
39
40; CHECK-LABEL: @test2(
41; CHECK: then:
42; CHECK-NEXT: br i1 false, label %end, label %else
43}
44
45; CHECK-LABEL: @test3(
46define i32 @test3(i32 %c) nounwind {
47  %cmp = icmp slt i32 %c, 2
48  br i1 %cmp, label %if.then, label %if.end
49
50if.then:
51  ret i32 1
52
53if.end:
54  %cmp1 = icmp slt i32 %c, 3
55  br i1 %cmp1, label %if.then2, label %if.end8
56
57; CHECK: if.then2
58if.then2:
59  %cmp2 = icmp eq i32 %c, 2
60; CHECK: br i1 true
61  br i1 %cmp2, label %if.then4, label %if.end6
62
63; CHECK: if.end6
64if.end6:
65  ret i32 2
66
67if.then4:
68  ret i32 3
69
70if.end8:
71  ret i32 4
72}
73
74; CHECK-LABEL: @test4(
75define i32 @test4(i32 %c) nounwind {
76  switch i32 %c, label %sw.default [
77    i32 1, label %sw.bb
78    i32 2, label %sw.bb
79    i32 4, label %sw.bb
80  ]
81
82; CHECK: sw.bb
83sw.bb:
84  %cmp = icmp sge i32 %c, 1
85; CHECK: br i1 true
86  br i1 %cmp, label %if.then, label %if.end
87
88if.then:
89  br label %return
90
91if.end:
92  br label %return
93
94sw.default:
95  br label %return
96
97return:
98  %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]
99  ret i32 %retval.0
100}
101
102; CHECK-LABEL: @test5(
103define i1 @test5(i32 %c) nounwind {
104  %cmp = icmp slt i32 %c, 5
105  br i1 %cmp, label %if.then, label %if.end
106
107if.then:
108  %cmp1 = icmp eq i32 %c, 4
109  br i1 %cmp1, label %if.end, label %if.end8
110
111if.end:
112  ret i1 true
113
114if.end8:
115  %cmp2 = icmp eq i32 %c, 3
116  %cmp3 = icmp eq i32 %c, 4
117  %cmp4 = icmp eq i32 %c, 6
118; CHECK: %or = or i1 false, false
119  %or = or i1 %cmp3, %cmp4
120; CHECK: ret i1 %cmp2
121  ret i1 %cmp2
122}
123
124; CHECK-LABEL: @test6(
125define i1 @test6(i32 %c) nounwind {
126  %cmp = icmp ule i32 %c, 7
127  br i1 %cmp, label %if.then, label %if.end
128
129if.then:
130; CHECK: icmp eq i32 %c, 6
131; CHECK: br i1
132  switch i32 %c, label %if.end [
133    i32 6, label %sw.bb
134    i32 8, label %sw.bb
135  ]
136
137if.end:
138  ret i1 true
139
140sw.bb:
141  %cmp2 = icmp eq i32 %c, 6
142; CHECK: ret i1 true
143  ret i1 %cmp2
144}
145
146; CHECK-LABEL: @test7(
147define i1 @test7(i32 %c) nounwind {
148entry:
149 switch i32 %c, label %sw.default [
150   i32 6, label %sw.bb
151   i32 7, label %sw.bb
152 ]
153
154sw.bb:
155 ret i1 true
156
157sw.default:
158 %cmp5 = icmp eq i32 %c, 5
159 %cmp6 = icmp eq i32 %c, 6
160 %cmp7 = icmp eq i32 %c, 7
161 %cmp8 = icmp eq i32 %c, 8
162; CHECK: %or = or i1 %cmp5, false
163 %or = or i1 %cmp5, %cmp6
164; CHECK: %or2 = or i1 false, %cmp8
165 %or2 = or i1 %cmp7, %cmp8
166 ret i1 false
167}
168
169define i1 @test8(i64* %p) {
170; CHECK-LABEL: @test8
171; CHECK: ret i1 false
172  %a = load i64, i64* %p, !range !{i64 4, i64 255}
173  %res = icmp eq i64 %a, 0
174  ret i1 %res
175}
176
177define i1 @test9(i64* %p) {
178; CHECK-LABEL: @test9
179; CHECK: ret i1 true
180  %a = load i64, i64* %p, !range !{i64 0, i64 1}
181  %res = icmp eq i64 %a, 0
182  ret i1 %res
183}
184
185define i1 @test10(i64* %p) {
186; CHECK-LABEL: @test10
187; CHECK: ret i1 false
188  %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20}
189  %res = icmp eq i64 %a, 0
190  ret i1 %res
191}
192