Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / monotonic-int-phis-wrapping.ll
blob17aa4d54abfbab5fda2499125617bcc32f95a434
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
7 declare void @use(i8)
8 declare void @use.i1(i1)
9 declare void @llvm.assume(i1)
10 declare i1 @cond()
12 define void @test_iv_wraps_1(i8 %len.n, i8 %a) {
13 ; CHECK-LABEL: @test_iv_wraps_1(
14 ; CHECK-NEXT:  loop.ph:
15 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
16 ; CHECK:       loop.header:
17 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
18 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
19 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
20 ; CHECK:       loop.latch:
21 ; CHECK-NEXT:    [[T_1:%.*]] = icmp uge i8 [[IV]], -1
22 ; CHECK-NEXT:    call void @use.i1(i1 [[T_1]])
23 ; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
24 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
25 ; CHECK:       exit:
26 ; CHECK-NEXT:    ret void
28 loop.ph:
29   br label %loop.header
31 loop.header:
32   %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
33   %c = icmp eq i8 %iv, 1
34   br i1 %c, label %exit, label %loop.latch
36 loop.latch:
37   %t.1 = icmp uge i8 %iv, 255
38   call void @use.i1(i1 %t.1)
39   %iv.next = add i8 %iv, 1
40   br label %loop.header
42 exit:
43   ret void
46 define void @test_iv_nuw_nsw_1_uge_start(i8 %len.n, i8 %a) {
47 ; CHECK-LABEL: @test_iv_nuw_nsw_1_uge_start(
48 ; CHECK-NEXT:  loop.ph:
49 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
50 ; CHECK:       loop.header:
51 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -1, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
52 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
53 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
54 ; CHECK:       for.body:
55 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
56 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
57 ; CHECK:       loop.latch:
58 ; CHECK-NEXT:    call void @use.i1(i1 true)
59 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
60 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
61 ; CHECK:       exit:
62 ; CHECK-NEXT:    ret void
64 loop.ph:
65   br label %loop.header
67 loop.header:
68   %iv = phi i8 [ 255, %loop.ph ], [ %iv.next, %loop.latch ]
69   %c = icmp eq i8 %iv, 1
70   br i1 %c, label %exit, label %for.body
72 for.body:
73   %c.2 = call i1 @cond()
74   br i1 %c.2, label %loop.latch, label %exit
76 loop.latch:
77   %t.1 = icmp uge i8 %iv, 255
78   call void @use.i1(i1 %t.1)
79   %iv.next = add nsw nuw i8 %iv, 1
80   br label %loop.header
82 exit:
83   ret void
86 define void @test_iv_nuw_nsw_2_uge_start(i8 %len.n, i8 %a) {
87 ; CHECK-LABEL: @test_iv_nuw_nsw_2_uge_start(
88 ; CHECK-NEXT:  loop.ph:
89 ; CHECK-NEXT:    [[START:%.*]] = add i8 -2, 1
90 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
91 ; CHECK:       loop.header:
92 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
93 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
94 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
95 ; CHECK:       for.body:
96 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
97 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
98 ; CHECK:       loop.latch:
99 ; CHECK-NEXT:    call void @use.i1(i1 true)
100 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
101 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
102 ; CHECK:       exit:
103 ; CHECK-NEXT:    ret void
105 loop.ph:
106   %start = add i8 254, 1
107   br label %loop.header
109 loop.header:
110   %iv = phi i8 [ %start, %loop.ph ], [ %iv.next, %loop.latch ]
111   %c = icmp eq i8 %iv, 1
112   br i1 %c, label %exit, label %for.body
114 for.body:
115   %c.2 = call i1 @cond()
116   br i1 %c.2, label %loop.latch, label %exit
118 loop.latch:
119   %t.1 = icmp uge i8 %iv, 255
120   call void @use.i1(i1 %t.1)
121   %iv.next = add nsw nuw i8 %iv, 1
122   br label %loop.header
124 exit:
125   ret void
128 define void @test_iv_nsw_nuw_1_ult_end(i8 %len.n, i8 %a) {
129 ; CHECK-LABEL: @test_iv_nsw_nuw_1_ult_end(
130 ; CHECK-NEXT:  loop.ph:
131 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
132 ; CHECK:       loop.header:
133 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ -2, [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
134 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], 1
135 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
136 ; CHECK:       for.body:
137 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
138 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
139 ; CHECK:       loop.latch:
140 ; CHECK-NEXT:    call void @use.i1(i1 false)
141 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
142 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
143 ; CHECK:       exit:
144 ; CHECK-NEXT:    ret void
146 loop.ph:
147   br label %loop.header
149 loop.header:
150   %iv = phi i8 [ 254, %loop.ph ], [ %iv.next, %loop.latch ]
151   %c = icmp eq i8 %iv, 1
152   br i1 %c, label %exit, label %for.body
154 for.body:
155   %c.2 = call i1 @cond()
156   br i1 %c.2, label %loop.latch, label %exit
158 loop.latch:
159   %t.1 = icmp ult i8 %iv, 1
160   call void @use.i1(i1 %t.1)
161   %iv.next = add nsw nuw i8 %iv, 1
162   br label %loop.header
164 exit:
165   ret void
169 define void @test_iv_nsw_nuw_2_ult_end(i8 %len.n, i8 %a, i8 %b) {
170 ; CHECK-LABEL: @test_iv_nsw_nuw_2_ult_end(
171 ; CHECK-NEXT:  loop.ph:
172 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
173 ; CHECK:       loop.header:
174 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
175 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
176 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
177 ; CHECK:       for.body:
178 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
179 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
180 ; CHECK:       loop.latch:
181 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 [[IV]], [[B]]
182 ; CHECK-NEXT:    call void @use.i1(i1 [[T_1]])
183 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
184 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
185 ; CHECK:       exit:
186 ; CHECK-NEXT:    ret void
188 loop.ph:
189   br label %loop.header
191 loop.header:
192   %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
193   %c = icmp eq i8 %iv, %b
194   br i1 %c, label %exit, label %for.body
196 for.body:
197   %c.2 = call i1 @cond()
198   br i1 %c.2, label %loop.latch, label %exit
200 loop.latch:
201   %t.1 = icmp ult i8 %iv, %b
202   call void @use.i1(i1 %t.1)
203   %iv.next = add nsw nuw i8 %iv, 1
204   br label %loop.header
206 exit:
207   ret void
210 define void @test_iv_nsw_nuw_3_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
211 ; CHECK-LABEL: @test_iv_nsw_nuw_3_ult_start_var(
212 ; CHECK-NEXT:  loop.ph:
213 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
214 ; CHECK:       loop.header:
215 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
216 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
217 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
218 ; CHECK:       for.body:
219 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
220 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
221 ; CHECK:       loop.latch:
222 ; CHECK-NEXT:    call void @use.i1(i1 false)
223 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1
224 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
225 ; CHECK:       exit:
226 ; CHECK-NEXT:    ret void
228 loop.ph:
229   br label %loop.header
231 loop.header:
232   %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
233   %c = icmp eq i8 %iv, %b
234   br i1 %c, label %exit, label %for.body
236 for.body:
237   %c.2 = call i1 @cond()
238   br i1 %c.2, label %loop.latch, label %exit
240 loop.latch:
241   %t.1 = icmp ult i8 %iv, %a
242   call void @use.i1(i1 %t.1)
243   %iv.next = add nsw nuw i8 %iv, 1
244   br label %loop.header
246 exit:
247   ret void
250 define void @test_iv_nsw_nuw_inc_2_ult_start_var(i8 %len.n, i8 %a, i8 %b) {
251 ; CHECK-LABEL: @test_iv_nsw_nuw_inc_2_ult_start_var(
252 ; CHECK-NEXT:  loop.ph:
253 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
254 ; CHECK:       loop.header:
255 ; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[A:%.*]], [[LOOP_PH:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
256 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[IV]], [[B:%.*]]
257 ; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]]
258 ; CHECK:       for.body:
259 ; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
260 ; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_LATCH]], label [[EXIT]]
261 ; CHECK:       loop.latch:
262 ; CHECK-NEXT:    call void @use.i1(i1 false)
263 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i8 [[IV]], 2
264 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
265 ; CHECK:       exit:
266 ; CHECK-NEXT:    ret void
268 loop.ph:
269   br label %loop.header
271 loop.header:
272   %iv = phi i8 [ %a, %loop.ph ], [ %iv.next, %loop.latch ]
273   %c = icmp eq i8 %iv, %b
274   br i1 %c, label %exit, label %for.body
276 for.body:
277   %c.2 = call i1 @cond()
278   br i1 %c.2, label %loop.latch, label %exit
280 loop.latch:
281   %t.1 = icmp ult i8 %iv, %a
282   call void @use.i1(i1 %t.1)
283   %iv.next = add nsw nuw i8 %iv, 2
284   br label %loop.header
286 exit:
287   ret void