[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / CorrelatedValuePropagation / add.ll
blob026af75220df9c83488308c6510b6754f84a1ab6
1 ; RUN: opt < %s -correlated-propagation -cvp-dont-add-nowrap-flags=false -S | FileCheck %s
3 ; CHECK-LABEL: @test0(
4 define void @test0(i32 %a) {
5 entry:
6   %cmp = icmp slt i32 %a, 100
7   br i1 %cmp, label %bb, label %exit
9 bb:
10 ; CHECK: %add = add nsw i32 %a, 1
11   %add = add i32 %a, 1
12   br label %exit
14 exit:
15   ret void
18 ; CHECK-LABEL: @test1(
19 define void @test1(i32 %a) {
20 entry:
21   %cmp = icmp ult i32 %a, 100
22   br i1 %cmp, label %bb, label %exit
24 bb:
25 ; CHECK: %add = add nuw nsw i32 %a, 1
26   %add = add i32 %a, 1
27   br label %exit
29 exit:
30   ret void
33 ; CHECK-LABEL: @test2(
34 define void @test2(i32 %a) {
35 entry:
36   %cmp = icmp ult i32 %a, -1
37   br i1 %cmp, label %bb, label %exit
39 bb:
40 ; CHECK: %add = add nuw i32 %a, 1
41   %add = add i32 %a, 1
42   br label %exit
44 exit:
45   ret void
48 ; CHECK-LABEL: @test3(
49 define void @test3(i32 %a) {
50 entry:
51   %cmp = icmp ule i32 %a, -1
52   br i1 %cmp, label %bb, label %exit
54 bb:
55 ; CHECK: %add = add i32 %a, 1
56   %add = add i32 %a, 1
57   br label %exit
59 exit:
60   ret void
63 ; CHECK-LABEL: @test4(
64 define void @test4(i32 %a) {
65 entry:
66   %cmp = icmp slt i32 %a, 2147483647
67   br i1 %cmp, label %bb, label %exit
69 bb:
70 ; CHECK: %add = add nsw i32 %a, 1
71   %add = add i32 %a, 1
72   br label %exit
74 exit:
75   ret void
78 ; CHECK-LABEL: @test5(
79 define void @test5(i32 %a) {
80 entry:
81   %cmp = icmp sle i32 %a, 2147483647
82   br i1 %cmp, label %bb, label %exit
84 bb:
85 ; CHECK: %add = add i32 %a, 1
86   %add = add i32 %a, 1
87   br label %exit
89 exit:
90   ret void
93 ; Check for a corner case where an integer value is represented with a constant
94 ; LVILatticeValue instead of constantrange. Check that we don't fail with an
95 ; assertion in this case.
96 @b = global i32 0, align 4
97 define void @test6(i32 %a) {
98 bb:
99   %add = add i32 %a, ptrtoint (i32* @b to i32)
100   ret void
103 ; Check that we can gather information for conditions is the form of
104 ;   and ( i s< 100, Unknown )
105 ; CHECK-LABEL: @test7(
106 define void @test7(i32 %a, i1 %flag) {
107 entry:
108   %cmp.1 = icmp slt i32 %a, 100
109   %cmp = and i1 %cmp.1, %flag
110   br i1 %cmp, label %bb, label %exit
113 ; CHECK: %add = add nsw i32 %a, 1
114   %add = add i32 %a, 1
115   br label %exit
117 exit:
118   ret void
121 ; Check that we can gather information for conditions is the form of
122 ;   and ( i s< 100, i s> 0 )
123 ; CHECK-LABEL: @test8(
124 define void @test8(i32 %a) {
125 entry:
126   %cmp.1 = icmp slt i32 %a, 100
127   %cmp.2 = icmp sgt i32 %a, 0
128   %cmp = and i1 %cmp.1, %cmp.2
129   br i1 %cmp, label %bb, label %exit
132 ; CHECK: %add = add nuw nsw i32 %a, 1
133   %add = add i32 %a, 1
134   br label %exit
136 exit:
137   ret void
140 ; Check that for conditions is the form of cond1 && cond2 we don't mistakenly
141 ; assume that !cond1 && !cond2 holds down to false path.
142 ; CHECK-LABEL: @test8_neg(
143 define void @test8_neg(i32 %a) {
144 entry:
145   %cmp.1 = icmp sge i32 %a, 100
146   %cmp.2 = icmp sle i32 %a, 0
147   %cmp = and i1 %cmp.1, %cmp.2
148   br i1 %cmp, label %exit, label %bb
151 ; CHECK: %add = add i32 %a, 1
152   %add = add i32 %a, 1
153   br label %exit
155 exit:
156   ret void
159 ; Check that we can gather information for conditions is the form of
160 ;   and ( i s< 100, and (i s> 0, Unknown )
161 ; CHECK-LABEL: @test9(
162 define void @test9(i32 %a, i1 %flag) {
163 entry:
164   %cmp.1 = icmp slt i32 %a, 100
165   %cmp.2 = icmp sgt i32 %a, 0
166   %cmp.3 = and i1 %cmp.2, %flag
167   %cmp = and i1 %cmp.1, %cmp.3
168   br i1 %cmp, label %bb, label %exit
171 ; CHECK: %add = add nuw nsw i32 %a, 1
172   %add = add i32 %a, 1
173   br label %exit
175 exit:
176   ret void
179 ; Check that we can gather information for conditions is the form of
180 ;   and ( i s< Unknown, ... )
181 ; CHECK-LABEL: @test10(
182 define void @test10(i32 %a, i32 %b, i1 %flag) {
183 entry:
184   %cmp.1 = icmp slt i32 %a, %b
185   %cmp = and i1 %cmp.1, %flag
186   br i1 %cmp, label %bb, label %exit
189 ; CHECK: %add = add nsw i32 %a, 1
190   %add = add i32 %a, 1
191   br label %exit
193 exit:
194   ret void
197 @limit = external global i32
198 ; CHECK-LABEL: @test11(
199 define i32 @test11(i32* %p, i32 %i) {
200   %limit = load i32, i32* %p, !range !{i32 0, i32 2147483647}
201   %within.1 = icmp ugt i32 %limit, %i
202   %i.plus.7 = add i32 %i, 7
203   %within.2 = icmp ugt i32 %limit, %i.plus.7
204   %within = and i1 %within.1, %within.2
205   br i1 %within, label %then, label %else
207 then:
208 ; CHECK: %i.plus.6 = add nuw nsw i32 %i, 6
209   %i.plus.6 = add i32 %i, 6
210   ret i32 %i.plus.6
212 else:
213   ret i32 0
216 ; Check that we can gather information for conditions is the form of
217 ;   or ( i s>= 100, Unknown )
218 ; CHECK-LABEL: @test12(
219 define void @test12(i32 %a, i1 %flag) {
220 entry:
221   %cmp.1 = icmp sge i32 %a, 100
222   %cmp = or i1 %cmp.1, %flag
223   br i1 %cmp, label %exit, label %bb
226 ; CHECK: %add = add nsw i32 %a, 1
227   %add = add i32 %a, 1
228   br label %exit
230 exit:
231   ret void
234 ; Check that we can gather information for conditions is the form of
235 ;   or ( i s>= 100, i s<= 0 )
236 ; CHECK-LABEL: @test13(
237 define void @test13(i32 %a) {
238 entry:
239   %cmp.1 = icmp sge i32 %a, 100
240   %cmp.2 = icmp sle i32 %a, 0
241   %cmp = or i1 %cmp.1, %cmp.2
242   br i1 %cmp, label %exit, label %bb
245 ; CHECK: %add = add nuw nsw i32 %a, 1
246   %add = add i32 %a, 1
247   br label %exit
249 exit:
250   ret void
253 ; Check that for conditions is the form of cond1 || cond2 we don't mistakenly
254 ; assume that cond1 || cond2 holds down to true path.
255 ; CHECK-LABEL: @test13_neg(
256 define void @test13_neg(i32 %a) {
257 entry:
258   %cmp.1 = icmp slt i32 %a, 100
259   %cmp.2 = icmp sgt i32 %a, 0
260   %cmp = or i1 %cmp.1, %cmp.2
261   br i1 %cmp, label %bb, label %exit
264 ; CHECK: %add = add i32 %a, 1
265   %add = add i32 %a, 1
266   br label %exit
268 exit:
269   ret void
272 ; Check that we can gather information for conditions is the form of
273 ;   or ( i s>=100, or (i s<= 0, Unknown )
274 ; CHECK-LABEL: @test14(
275 define void @test14(i32 %a, i1 %flag) {
276 entry:
277   %cmp.1 = icmp sge i32 %a, 100
278   %cmp.2 = icmp sle i32 %a, 0
279   %cmp.3 = or i1 %cmp.2, %flag
280   %cmp = or i1 %cmp.1, %cmp.3
281   br i1 %cmp, label %exit, label %bb
284 ; CHECK: %add = add nuw nsw i32 %a, 1
285   %add = add i32 %a, 1
286   br label %exit
288 exit:
289   ret void
292 ; Check that we can gather information for conditions is the form of
293 ;   or ( i s>= Unknown, ... )
294 ; CHECK-LABEL: @test15(
295 define void @test15(i32 %a, i32 %b, i1 %flag) {
296 entry:
297   %cmp.1 = icmp sge i32 %a, %b
298   %cmp = or i1 %cmp.1, %flag
299   br i1 %cmp, label %exit, label %bb
302 ; CHECK: %add = add nsw i32 %a, 1
303   %add = add i32 %a, 1
304   br label %exit
306 exit:
307   ret void
310 ; single basic block loop
311 ; because the loop exit condition is SLT, we can supplement the iv add
312 ; (iv.next def) with an nsw.
313 ; CHECK-LABEL: @test16(
314 define i32 @test16(i32* %n, i32* %a) {
315 preheader:
316   br label %loop
318 loop:
319 ; CHECK: %iv.next = add nsw i32 %iv, 1
320   %iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ]
321   %acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ]
322   %x = load atomic i32, i32* %a unordered, align 8
323   fence acquire
324   %acc.curr = add i32 %acc, %x
325   %iv.next = add i32 %iv, 1
326   %nval = load atomic i32, i32* %n unordered, align 8
327   %cmp = icmp slt i32 %iv.next, %nval
328   br i1 %cmp, label %loop, label %exit
330 exit:
331   ret i32 %acc.curr