1 ; RUN: opt < %s -correlated-propagation -cvp-dont-add-nowrap-flags=false -S | FileCheck %s
4 define void @test0(i32 %a) {
6 %cmp = icmp slt i32 %a, 100
7 br i1 %cmp, label %bb, label %exit
10 ; CHECK: %add = add nsw i32 %a, 1
18 ; CHECK-LABEL: @test1(
19 define void @test1(i32 %a) {
21 %cmp = icmp ult i32 %a, 100
22 br i1 %cmp, label %bb, label %exit
25 ; CHECK: %add = add nuw nsw i32 %a, 1
33 ; CHECK-LABEL: @test2(
34 define void @test2(i32 %a) {
36 %cmp = icmp ult i32 %a, -1
37 br i1 %cmp, label %bb, label %exit
40 ; CHECK: %add = add nuw i32 %a, 1
48 ; CHECK-LABEL: @test3(
49 define void @test3(i32 %a) {
51 %cmp = icmp ule i32 %a, -1
52 br i1 %cmp, label %bb, label %exit
55 ; CHECK: %add = add i32 %a, 1
63 ; CHECK-LABEL: @test4(
64 define void @test4(i32 %a) {
66 %cmp = icmp slt i32 %a, 2147483647
67 br i1 %cmp, label %bb, label %exit
70 ; CHECK: %add = add nsw i32 %a, 1
78 ; CHECK-LABEL: @test5(
79 define void @test5(i32 %a) {
81 %cmp = icmp sle i32 %a, 2147483647
82 br i1 %cmp, label %bb, label %exit
85 ; CHECK: %add = add i32 %a, 1
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) {
99 %add = add i32 %a, ptrtoint (i32* @b to i32)
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) {
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
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) {
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
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) {
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
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) {
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
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) {
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
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
208 ; CHECK: %i.plus.6 = add nuw nsw i32 %i, 6
209 %i.plus.6 = add i32 %i, 6
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) {
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
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) {
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
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) {
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
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) {
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
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) {
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
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) {
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
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