[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / add-nsw.ll
blob5127e92a7c345b7d983dcb7cf7360cff2a22a683
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 declare void @use(i1)
5 declare void @llvm.assume(i1)
7 define void @test.not.uge.ult(i8 %start, i8 %high) {
8 ; CHECK-LABEL: @test.not.uge.ult(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
11 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
12 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
13 ; CHECK:       if.then:
14 ; CHECK-NEXT:    ret void
15 ; CHECK:       if.end:
16 ; CHECK-NEXT:    [[T_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
17 ; CHECK-NEXT:    call void @use(i1 [[T_0]])
18 ; CHECK-NEXT:    [[START_1:%.*]] = add nsw i8 [[START]], 1
19 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 [[START_1]], [[HIGH]]
20 ; CHECK-NEXT:    call void @use(i1 [[T_1]])
21 ; CHECK-NEXT:    [[START_2:%.*]] = add nsw i8 [[START]], 2
22 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8 [[START_2]], [[HIGH]]
23 ; CHECK-NEXT:    call void @use(i1 [[T_2]])
24 ; CHECK-NEXT:    [[START_3:%.*]] = add nsw i8 [[START]], 3
25 ; CHECK-NEXT:    [[T_3:%.*]] = icmp ult i8 [[START_3]], [[HIGH]]
26 ; CHECK-NEXT:    call void @use(i1 [[T_3]])
27 ; CHECK-NEXT:    [[START_4:%.*]] = add nsw i8 [[START]], 4
28 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]
29 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
30 ; CHECK-NEXT:    ret void
32 entry:
33   %add.ptr.i = add nsw i8 %start, 3
34   %c.1 = icmp uge i8 %add.ptr.i, %high
35   br i1 %c.1, label %if.then, label %if.end
37 if.then:                                          ; preds = %entry
38   ret void
40 if.end:                                           ; preds = %entry
41   %t.0 = icmp ult i8 %start, %high
42   call void @use(i1 %t.0)
43   %start.1 = add nsw i8 %start, 1
44   %t.1 = icmp ult i8 %start.1, %high
45   call void @use(i1 %t.1)
46   %start.2 = add nsw i8 %start, 2
47   %t.2 = icmp ult i8 %start.2, %high
48   call void @use(i1 %t.2)
49   %start.3 = add nsw i8 %start, 3
50   %t.3 = icmp ult i8 %start.3, %high
51   call void @use(i1 %t.3)
52   %start.4 = add nsw i8 %start, 4
53   %c.4 = icmp ult i8 %start.4, %high
54   call void @use(i1 %c.4)
55   ret void
58 define void @test.not.sge.slt(i8 %start, i8 %high) {
59 ; CHECK-LABEL: @test.not.sge.slt(
60 ; CHECK-NEXT:  entry:
61 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], 3
62 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[ADD_PTR_I]], [[HIGH:%.*]]
63 ; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
64 ; CHECK:       if.then:
65 ; CHECK-NEXT:    ret void
66 ; CHECK:       if.end:
67 ; CHECK-NEXT:    call void @use(i1 true)
68 ; CHECK-NEXT:    [[START_1:%.*]] = add nsw i8 [[START]], 1
69 ; CHECK-NEXT:    call void @use(i1 true)
70 ; CHECK-NEXT:    [[START_2:%.*]] = add nsw i8 [[START]], 2
71 ; CHECK-NEXT:    call void @use(i1 true)
72 ; CHECK-NEXT:    [[START_3:%.*]] = add nsw i8 [[START]], 3
73 ; CHECK-NEXT:    call void @use(i1 true)
74 ; CHECK-NEXT:    [[START_4:%.*]] = add nsw i8 [[START]], 4
75 ; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_4]], [[HIGH]]
76 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
77 ; CHECK-NEXT:    ret void
79 entry:
80   %add.ptr.i = add nsw i8 %start, 3
81   %c.1 = icmp sge i8 %add.ptr.i, %high
82   br i1 %c.1, label %if.then, label %if.end
84 if.then:                                          ; preds = %entry
85   ret void
87 if.end:                                           ; preds = %entry
88   %t.0 = icmp slt i8 %start, %high
89   call void @use(i1 %t.0)
90   %start.1 = add nsw i8 %start, 1
91   %t.1 = icmp slt i8 %start.1, %high
92   call void @use(i1 %t.1)
93   %start.2 = add nsw i8 %start, 2
94   %t.2 = icmp slt i8 %start.2, %high
95   call void @use(i1 %t.2)
96   %start.3 = add nsw i8 %start, 3
97   %t.3 = icmp slt i8 %start.3, %high
98   call void @use(i1 %t.3)
99   %start.4 = add nsw i8 %start, 4
100   %c.4 = icmp slt i8 %start.4, %high
101   call void @use(i1 %c.4)
102   ret void
105 define void @test.decompose.nonconst(i8 %a, i8 %b, i8 %c, i8 %d) {
106 ; CHECK-LABEL: @test.decompose.nonconst(
107 ; CHECK-NEXT:  entry:
108 ; CHECK-NEXT:    [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]]
109 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]]
110 ; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
111 ; CHECK-NEXT:    br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
112 ; CHECK:       if.then:
113 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[A]], 0
114 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[B]], 0
115 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[C_2]], [[C_3]]
116 ; CHECK-NEXT:    br i1 [[AND_1]], label [[IF_THEN_2:%.*]], label [[IF_END]]
117 ; CHECK:       if.then.2:
118 ; CHECK-NEXT:    [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]]
119 ; CHECK-NEXT:    call void @use(i1 true)
120 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]]
121 ; CHECK-NEXT:    call void @use(i1 true)
122 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]]
123 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]]
124 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
125 ; CHECK-NEXT:    ret void
126 ; CHECK:       if.end:
127 ; CHECK-NEXT:    ret void
129 entry:
130   %c.0 = icmp sge i8 %a, %c
131   %c.1 = icmp sge i8 %b, %c
132   %and.0 = and i1 %c.0, %c.1
133   br i1 %and.0, label %if.then, label %if.end
135 if.then:                                          ; preds = %entry
136   %c.2 = icmp sge i8 %a, 0
137   %c.3 = icmp sge i8 %b, 0
138   %and.1 = and i1 %c.2, %c.3
139   br i1 %and.1, label %if.then.2, label %if.end
141 if.then.2:
142   %add.0 = add nsw i8 %a, %b
143   %t.0 = icmp sge i8 %add.0, %c
144   call void @use(i1 %t.0)
145   %add.1 = add nsw i8 %a, %a
146   %t.1 = icmp sge i8 %add.0, %c
147   call void @use(i1 %t.1)
148   %add.2 = add nsw i8 %a, %d
149   %c.4 = icmp sge i8 %add.2, %c
150   call void @use(i1 %c.4)
151   ret void
153 if.end:                                           ; preds = %entry
154   ret void
157 define void @test.decompose.nonconst.no.null.check(i8 %a, i8 %b, i8 %c, i8 %d) {
158 ; CHECK-LABEL: @test.decompose.nonconst.no.null.check(
159 ; CHECK-NEXT:  entry:
160 ; CHECK-NEXT:    [[C_0:%.*]] = icmp sge i8 [[A:%.*]], [[C:%.*]]
161 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[B:%.*]], [[C]]
162 ; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[C_0]], [[C_1]]
163 ; CHECK-NEXT:    br i1 [[AND_0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
164 ; CHECK:       if.then:
165 ; CHECK-NEXT:    [[ADD_0:%.*]] = add nsw i8 [[A]], [[B]]
166 ; CHECK-NEXT:    [[T_0:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
167 ; CHECK-NEXT:    call void @use(i1 [[T_0]])
168 ; CHECK-NEXT:    [[ADD_1:%.*]] = add nsw i8 [[A]], [[A]]
169 ; CHECK-NEXT:    [[T_1:%.*]] = icmp sge i8 [[ADD_0]], [[C]]
170 ; CHECK-NEXT:    call void @use(i1 [[T_1]])
171 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i8 [[A]], [[D:%.*]]
172 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[ADD_2]], [[C]]
173 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
174 ; CHECK-NEXT:    ret void
175 ; CHECK:       if.end:
176 ; CHECK-NEXT:    ret void
178 entry:
179   %c.0 = icmp sge i8 %a, %c
180   %c.1 = icmp sge i8 %b, %c
181   %and.0 = and i1 %c.0, %c.1
182   br i1 %and.0, label %if.then, label %if.end
184 if.then:                                          ; preds = %entry
185   %add.0 = add nsw i8 %a, %b
186   %t.0 = icmp sge i8 %add.0, %c
187   call void @use(i1 %t.0)
188   %add.1 = add nsw i8 %a, %a
189   %t.1 = icmp sge i8 %add.0, %c
190   call void @use(i1 %t.1)
191   %add.2 = add nsw i8 %a, %d
192   %c.4 = icmp sge i8 %add.2, %c
193   call void @use(i1 %c.4)
194   ret void
196 if.end:                                           ; preds = %entry
197   ret void
200 define void @test.sge.slt.add.neg(i8 %start, i8 %high) {
201 ; CHECK-LABEL: @test.sge.slt.add.neg(
202 ; CHECK-NEXT:  entry:
203 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = add nsw i8 [[START:%.*]], -3
204 ; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i8 [[ADD_PTR_I]], [[HIGH:%.*]]
205 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
206 ; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i8 [[START]], [[HIGH]]
207 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
208 ; CHECK-NEXT:    [[START_1:%.*]] = add nsw i8 [[START]], 1
209 ; CHECK-NEXT:    [[C_3:%.*]] = icmp slt i8 [[START_1]], [[HIGH]]
210 ; CHECK-NEXT:    call void @use(i1 [[C_3]])
211 ; CHECK-NEXT:    [[START_2:%.*]] = add nsw i8 [[START]], -2
212 ; CHECK-NEXT:    [[C_4:%.*]] = icmp slt i8 [[START_2]], [[HIGH]]
213 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
214 ; CHECK-NEXT:    [[START_3:%.*]] = add nsw i8 [[START]], -3
215 ; CHECK-NEXT:    call void @use(i1 true)
216 ; CHECK-NEXT:    [[START_4:%.*]] = add nsw i8 [[START]], -4
217 ; CHECK-NEXT:    call void @use(i1 true)
218 ; CHECK-NEXT:    ret void
220 entry:
221   %add.ptr.i = add nsw i8 %start, -3
222   %c.1 = icmp slt i8 %add.ptr.i, %high
223   call void @llvm.assume(i1 %c.1)
224   %c.2 = icmp slt i8 %start, %high
225   call void @use(i1 %c.2)
226   %start.1 = add nsw i8 %start,  1
227   %c.3 = icmp slt i8 %start.1, %high
228   call void @use(i1 %c.3)
229   %start.2 = add nsw i8 %start, -2
230   %c.4 = icmp slt i8 %start.2, %high
231   call void @use(i1 %c.4)
232   %start.3 = add nsw i8 %start, -3
233   %t.1 = icmp slt i8 %start.3, %high
234   call void @use(i1 %t.1)
235   %start.4 = add nsw i8 %start, -4
236   %t.2 = icmp slt i8 %start.4, %high
237   call void @use(i1 %t.2)
238   ret void
241 define i1 @test_ult_add_nsw_pos_1(i8 %start, i8 %high) {
242 ; CHECK-LABEL: @test_ult_add_nsw_pos_1(
243 ; CHECK-NEXT:  entry:
244 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
245 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
246 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
247 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
248 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
249 ; CHECK-NEXT:    ret i1 true
251 entry:
252   %high.ext = zext i8 %high to i16
253   %start.ext = zext i8 %start to i16
254   %add.ext = add nsw i16 %start.ext, 3
255   %c.1 = icmp ult i16 %add.ext, %high.ext
256   call void @llvm.assume(i1 %c.1)
258   %t = icmp ult i16 %start.ext, %high.ext
259   ret i1 %t
262 define i1 @test_ult_add_nsw_pos_1_assume_pos(i8 %start, i8 %high) {
263 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_assume_pos(
264 ; CHECK-NEXT:  entry:
265 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
266 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
267 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], 3
268 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
269 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
270 ; CHECK-NEXT:    ret i1 true
272 entry:
273   %start.pos = icmp sge i8 %start, 0
274   call void @llvm.assume(i1 %start.pos)
275   %add = add nsw i8 %start, 3
276   %c.1 = icmp ult i8 %add, %high
277   call void @llvm.assume(i1 %c.1)
279   %t = icmp ult i8 %start, %high
280   ret i1 %t
283 define i1 @test_ult_add_nsw_pos_1_no_assume_pos(i8 %start, i8 %high) {
284 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_no_assume_pos(
285 ; CHECK-NEXT:  entry:
286 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START:%.*]], 3
287 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
288 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
289 ; CHECK-NEXT:    [[T:%.*]] = icmp ult i8 [[START]], [[HIGH]]
290 ; CHECK-NEXT:    ret i1 [[T]]
292 entry:
293   %add = add nsw i8 %start, 3
294   %c.1 = icmp ult i8 %add, %high
295   call void @llvm.assume(i1 %c.1)
297   %t = icmp ult i8 %start, %high
298   ret i1 %t
301 define i1 @test_ult_add_nsw_pos_1_cmp_no_ext(i8 %start, i8 %high) {
302 ; CHECK-LABEL: @test_ult_add_nsw_pos_1_cmp_no_ext(
303 ; CHECK-NEXT:  entry:
304 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
305 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
306 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
307 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
308 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
309 ; CHECK-NEXT:    ret i1 true
311 entry:
312   %high.ext = zext i8 %high to i16
313   %start.ext = zext i8 %start to i16
314   %add.ext = add nsw i16 %start.ext, 3
315   %c.1 = icmp ult i16 %add.ext, %high.ext
316   call void @llvm.assume(i1 %c.1)
318   %t = icmp ult i8 %start, %high
319   ret i1 %t
322 define i1 @test_ult_add_nsw_pos_2(i8 %start, i8 %high) {
323 ; CHECK-LABEL: @test_ult_add_nsw_pos_2(
324 ; CHECK-NEXT:  entry:
325 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
326 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
327 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
328 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
329 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
330 ; CHECK-NEXT:    ret i1 false
332 entry:
333   %high.ext = zext i8 %high to i16
334   %start.ext = zext i8 %start to i16
335   %add.ext = add nsw i16 %start.ext, 3
336   %c.1 = icmp ult i16 %add.ext, %high.ext
337   call void @llvm.assume(i1 %c.1)
339   %f = icmp uge i16 %start.ext, %high.ext
340   ret i1 %f
343 define i1 @test_ult_add_nsw_pos_2_assume_pos(i8 %start, i8 %high) {
344 ; CHECK-LABEL: @test_ult_add_nsw_pos_2_assume_pos(
345 ; CHECK-NEXT:  entry:
346 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
347 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
348 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], 3
349 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
350 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
351 ; CHECK-NEXT:    ret i1 false
353 entry:
354   %start.pos = icmp sge i8 %start, 0
355   call void @llvm.assume(i1 %start.pos)
356   %add = add nsw i8 %start, 3
357   %c.1 = icmp ult i8 %add, %high
358   call void @llvm.assume(i1 %c.1)
360   %f = icmp uge i8 %start, %high
361   ret i1 %f
364 define i1 @test_ult_add_nsw_pos_2_cmp_no_ext(i8 %start, i8 %high) {
365 ; CHECK-LABEL: @test_ult_add_nsw_pos_2_cmp_no_ext(
366 ; CHECK-NEXT:  entry:
367 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
368 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
369 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
370 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
371 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
372 ; CHECK-NEXT:    ret i1 false
374 entry:
375   %high.ext = zext i8 %high to i16
376   %start.ext = zext i8 %start to i16
377   %add.ext = add nsw i16 %start.ext, 3
378   %c.1 = icmp ult i16 %add.ext, %high.ext
379   call void @llvm.assume(i1 %c.1)
381   %c = icmp uge i8 %start, %high
382   ret i1 %c
385 define i1 @test_ult_add_nsw_pos_3(i8 %start, i8 %high) {
386 ; CHECK-LABEL: @test_ult_add_nsw_pos_3(
387 ; CHECK-NEXT:  entry:
388 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
389 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
390 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
391 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
392 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
393 ; CHECK-NEXT:    [[ADD_4:%.*]] = add nsw i16 [[START_EXT]], 4
394 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i16 [[ADD_4]], [[HIGH_EXT]]
395 ; CHECK-NEXT:    ret i1 [[C]]
397 entry:
398   %high.ext = zext i8 %high to i16
399   %start.ext = zext i8 %start to i16
400   %add.ext = add nsw i16 %start.ext, 3
401   %c.1 = icmp ult i16 %add.ext, %high.ext
402   call void @llvm.assume(i1 %c.1)
404   %add.4 = add nsw i16 %start.ext, 4
405   %c = icmp ult i16 %add.4, %high.ext
406   ret i1 %c
409 define i1 @test_ult_add_nsw_pos_3_assume_pos(i8 %start, i8 %high) {
410 ; CHECK-LABEL: @test_ult_add_nsw_pos_3_assume_pos(
411 ; CHECK-NEXT:  entry:
412 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
413 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
414 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], 3
415 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
416 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
417 ; CHECK-NEXT:    [[ADD_4:%.*]] = add nsw i8 [[START]], 4
418 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[ADD_4]], [[HIGH]]
419 ; CHECK-NEXT:    ret i1 [[C]]
421 entry:
422   %start.pos = icmp sge i8 %start, 0
423   call void @llvm.assume(i1 %start.pos)
424   %add = add nsw i8 %start, 3
425   %c.1 = icmp ult i8 %add, %high
426   call void @llvm.assume(i1 %c.1)
428   %add.4 = add nsw i8 %start, 4
429   %c = icmp ult i8 %add.4, %high
430   ret i1 %c
433 define i1 @test_ult_add_nsw_pos_4(i8 %start, i8 %high) {
434 ; CHECK-LABEL: @test_ult_add_nsw_pos_4(
435 ; CHECK-NEXT:  entry:
436 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
437 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
438 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
439 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
440 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
441 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i16 [[START_EXT]], 2
442 ; CHECK-NEXT:    ret i1 true
444 entry:
445   %high.ext = zext i8 %high to i16
446   %start.ext = zext i8 %start to i16
447   %add.ext = add nsw i16 %start.ext, 3
448   %c.1 = icmp ult i16 %add.ext, %high.ext
449   call void @llvm.assume(i1 %c.1)
451   %add.2 = add nsw i16 %start.ext, 2
452   %c = icmp ult i16 %add.2, %high.ext
453   ret i1 %c
456 define i1 @test_ult_add_nsw_pos_4_assume_pos(i8 %start, i8 %high) {
457 ; CHECK-LABEL: @test_ult_add_nsw_pos_4_assume_pos(
458 ; CHECK-NEXT:  entry:
459 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
460 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
461 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], 3
462 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
463 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
464 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i8 [[START]], 2
465 ; CHECK-NEXT:    ret i1 true
467 entry:
468   %start.pos = icmp sge i8 %start, 0
469   call void @llvm.assume(i1 %start.pos)
470   %add = add nsw i8 %start, 3
471   %c.1 = icmp ult i8 %add, %high
472   call void @llvm.assume(i1 %c.1)
474   %add.2 = add nsw i8 %start, 2
475   %c = icmp ult i8 %add.2, %high
476   ret i1 %c
479 define i1 @test_ult_add_nsw_neg_5(i8 %start, i8 %high) {
480 ; CHECK-LABEL: @test_ult_add_nsw_neg_5(
481 ; CHECK-NEXT:  entry:
482 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
483 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
484 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add nsw i16 [[START_EXT]], 3
485 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
486 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
487 ; CHECK-NEXT:    [[SUB_2:%.*]] = add nsw i16 [[START_EXT]], -2
488 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i16 [[SUB_2]], [[HIGH_EXT]]
489 ; CHECK-NEXT:    ret i1 [[C]]
491 entry:
492   %high.ext = zext i8 %high to i16
493   %start.ext = zext i8 %start to i16
494   %add.ext = add nsw i16 %start.ext, 3
495   %c.1 = icmp ult i16 %add.ext, %high.ext
496   call void @llvm.assume(i1 %c.1)
498   %sub.2 = add nsw i16 %start.ext, -2
499   %c = icmp ult i16 %sub.2, %high.ext
500   ret i1 %c
503 define i1 @test_ult_add_nsw_neg_5_assume_pos(i8 %start, i8 %high) {
504 ; CHECK-LABEL: @test_ult_add_nsw_neg_5_assume_pos(
505 ; CHECK-NEXT:  entry:
506 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
507 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
508 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], 3
509 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
510 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
511 ; CHECK-NEXT:    [[SUB_2:%.*]] = add nsw i8 [[START]], -2
512 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[SUB_2]], [[HIGH]]
513 ; CHECK-NEXT:    ret i1 [[C]]
515 entry:
516   %start.pos = icmp sge i8 %start, 0
517   call void @llvm.assume(i1 %start.pos)
518   %add = add nsw i8 %start, 3
519   %c.1 = icmp ult i8 %add, %high
520   call void @llvm.assume(i1 %c.1)
522   %sub.2 = add nsw i8 %start, -2
523   %c = icmp ult i8 %sub.2, %high
524   ret i1 %c
527 define i1 @test_ult_add_no_nsw_pos_6(i8 %start, i8 %high) {
528 ; CHECK-LABEL: @test_ult_add_no_nsw_pos_6(
529 ; CHECK-NEXT:  entry:
530 ; CHECK-NEXT:    [[HIGH_EXT:%.*]] = zext i8 [[HIGH:%.*]] to i16
531 ; CHECK-NEXT:    [[START_EXT:%.*]] = zext i8 [[START:%.*]] to i16
532 ; CHECK-NEXT:    [[ADD_EXT:%.*]] = add i16 [[START_EXT]], 3
533 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i16 [[ADD_EXT]], [[HIGH_EXT]]
534 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
535 ; CHECK-NEXT:    [[ADD_2:%.*]] = add i16 [[START_EXT]], 2
536 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i16 [[ADD_2]], [[HIGH_EXT]]
537 ; CHECK-NEXT:    ret i1 [[C]]
539 entry:
540   %high.ext = zext i8 %high to i16
541   %start.ext = zext i8 %start to i16
542   %add.ext = add i16 %start.ext, 3
543   %c.1 = icmp ult i16 %add.ext, %high.ext
544   call void @llvm.assume(i1 %c.1)
546   %add.2 = add i16 %start.ext, 2
547   %c = icmp ult i16 %add.2, %high.ext
548   ret i1 %c
551 define i1 @test_ult_add_no_nsw_pos_6_assume_pos(i8 %start, i8 %high) {
552 ; CHECK-LABEL: @test_ult_add_no_nsw_pos_6_assume_pos(
553 ; CHECK-NEXT:  entry:
554 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
555 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
556 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[START]], 3
557 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
558 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
559 ; CHECK-NEXT:    [[ADD_2:%.*]] = add i8 [[START]], 2
560 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[ADD_2]], [[HIGH]]
561 ; CHECK-NEXT:    ret i1 [[C]]
563 entry:
564   %start.pos = icmp sge i8 %start, 0
565   call void @llvm.assume(i1 %start.pos)
566   %add = add i8 %start, 3
567   %c.1 = icmp ult i8 %add, %high
568   call void @llvm.assume(i1 %c.1)
570   %add.2 = add i8 %start, 2
571   %c = icmp ult i8 %add.2, %high
572   ret i1 %c
575 define i1 @test_ult_add_nsw_var_7(i8 %start, i8 %off, i8 %high) {
576 ; CHECK-LABEL: @test_ult_add_nsw_var_7(
577 ; CHECK-NEXT:  entry:
578 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF:%.*]]
579 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
580 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
581 ; CHECK-NEXT:    [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0
582 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_POS]])
583 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]]
584 ; CHECK-NEXT:    ret i1 [[C]]
586 entry:
587   %add = add nsw i8 %start, %off
588   %c.1 = icmp ult i8 %add, %high
589   call void @llvm.assume(i1 %c.1)
590   %off.pos = icmp sge i8 %off, 0
591   call void @llvm.assume(i1 %off.pos)
593   %c = icmp ult i8 %start, %high
594   ret i1 %c
597 define i1 @test_ult_add_no_nsw_var_7(i8 %start, i8 %off, i8 %high) {
598 ; CHECK-LABEL: @test_ult_add_no_nsw_var_7(
599 ; CHECK-NEXT:  entry:
600 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[START:%.*]], [[OFF:%.*]]
601 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
602 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
603 ; CHECK-NEXT:    [[OFF_POS:%.*]] = icmp sge i8 [[OFF]], 0
604 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_POS]])
605 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[START]], [[HIGH]]
606 ; CHECK-NEXT:    ret i1 [[C]]
608 entry:
609   %add = add i8 %start, %off
610   %c.1 = icmp ult i8 %add, %high
611   call void @llvm.assume(i1 %c.1)
612   %off.pos = icmp sge i8 %off, 0
613   call void @llvm.assume(i1 %off.pos)
615   %c = icmp ult i8 %start, %high
616   ret i1 %c
619 define i1 @test_ult_add_nsw_var_8(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
620 ; CHECK-LABEL: @test_ult_add_nsw_var_8(
621 ; CHECK-NEXT:  entry:
622 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START:%.*]], [[OFF_2:%.*]]
623 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
624 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
625 ; CHECK-NEXT:    [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
626 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_POS]])
627 ; CHECK-NEXT:    [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
628 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_2_POS]])
629 ; CHECK-NEXT:    [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
630 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_ULT]])
631 ; CHECK-NEXT:    [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
632 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
633 ; CHECK-NEXT:    ret i1 [[C]]
635 entry:
636   %add = add nsw i8 %start, %off.2
637   %c.1 = icmp ult i8 %add, %high
638   call void @llvm.assume(i1 %c.1)
639   %off.1.pos = icmp sge i8 %off.1, 0
640   call void @llvm.assume(i1 %off.1.pos)
641   %off.2.pos = icmp sge i8 %off.2, 0
642   call void @llvm.assume(i1 %off.2.pos)
643   %off.1.ult = icmp ult i8 %off.1, %off.2
644   call void @llvm.assume(i1 %off.1.ult)
646   %add.off.2 = add nsw i8 %start, %off.1
647   %c = icmp ult i8 %add.off.2, %high
648   ret i1 %c
651 define i1 @test_ult_add_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
652 ; CHECK-LABEL: @test_ult_add_nsw_var_8_all_pos(
653 ; CHECK-NEXT:  entry:
654 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
655 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
656 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
657 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
658 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
659 ; CHECK-NEXT:    [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
660 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_POS]])
661 ; CHECK-NEXT:    [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
662 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_2_POS]])
663 ; CHECK-NEXT:    [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
664 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_ULT]])
665 ; CHECK-NEXT:    [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
666 ; CHECK-NEXT:    ret i1 true
668 entry:
669   %start.pos = icmp sge i8 %start, 0
670   call void @llvm.assume(i1 %start.pos)
671   %add = add nsw i8 %start, %off.2
672   %c.1 = icmp ult i8 %add, %high
673   call void @llvm.assume(i1 %c.1)
674   %off.1.pos = icmp sge i8 %off.1, 0
675   call void @llvm.assume(i1 %off.1.pos)
676   %off.2.pos = icmp sge i8 %off.2, 0
677   call void @llvm.assume(i1 %off.2.pos)
678   %off.1.ult = icmp ult i8 %off.1, %off.2
679   call void @llvm.assume(i1 %off.1.ult)
681   %add.off.2 = add nsw i8 %start, %off.1
682   %c = icmp ult i8 %add.off.2, %high
683   ret i1 %c
686 define i1 @test_ult_add_no_nsw_var_8_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
687 ; CHECK-LABEL: @test_ult_add_no_nsw_var_8_all_pos(
688 ; CHECK-NEXT:  entry:
689 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
690 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
691 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[START]], [[OFF_2:%.*]]
692 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
693 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
694 ; CHECK-NEXT:    [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
695 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_POS]])
696 ; CHECK-NEXT:    [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
697 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_2_POS]])
698 ; CHECK-NEXT:    [[OFF_1_ULT:%.*]] = icmp ult i8 [[OFF_1]], [[OFF_2]]
699 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_ULT]])
700 ; CHECK-NEXT:    [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
701 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
702 ; CHECK-NEXT:    ret i1 [[C]]
704 entry:
705   %start.pos = icmp sge i8 %start, 0
706   call void @llvm.assume(i1 %start.pos)
707   %add = add i8 %start, %off.2
708   %c.1 = icmp ult i8 %add, %high
709   call void @llvm.assume(i1 %c.1)
710   %off.1.pos = icmp sge i8 %off.1, 0
711   call void @llvm.assume(i1 %off.1.pos)
712   %off.2.pos = icmp sge i8 %off.2, 0
713   call void @llvm.assume(i1 %off.2.pos)
714   %off.1.ult = icmp ult i8 %off.1, %off.2
715   call void @llvm.assume(i1 %off.1.ult)
717   %add.off.2 = add nsw i8 %start, %off.1
718   %c = icmp ult i8 %add.off.2, %high
719   ret i1 %c
722 define i1 @test_ult_add_nsw_var_9_all_pos(i8 %start, i8 %off.1, i8 %off.2, i8 %high) {
723 ; CHECK-LABEL: @test_ult_add_nsw_var_9_all_pos(
724 ; CHECK-NEXT:  entry:
725 ; CHECK-NEXT:    [[START_POS:%.*]] = icmp sge i8 [[START:%.*]], 0
726 ; CHECK-NEXT:    call void @llvm.assume(i1 [[START_POS]])
727 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[START]], [[OFF_2:%.*]]
728 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[ADD]], [[HIGH:%.*]]
729 ; CHECK-NEXT:    call void @llvm.assume(i1 [[C_1]])
730 ; CHECK-NEXT:    [[OFF_1_POS:%.*]] = icmp sge i8 [[OFF_1:%.*]], 0
731 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_1_POS]])
732 ; CHECK-NEXT:    [[OFF_2_POS:%.*]] = icmp sge i8 [[OFF_2]], 0
733 ; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_2_POS]])
734 ; CHECK-NEXT:    [[ADD_OFF_2:%.*]] = add nsw i8 [[START]], [[OFF_1]]
735 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[ADD_OFF_2]], [[HIGH]]
736 ; CHECK-NEXT:    ret i1 [[C]]
738 entry:
739   %start.pos = icmp sge i8 %start, 0
740   call void @llvm.assume(i1 %start.pos)
741   %add = add nsw i8 %start, %off.2
742   %c.1 = icmp ult i8 %add, %high
743   call void @llvm.assume(i1 %c.1)
744   %off.1.pos = icmp sge i8 %off.1, 0
745   call void @llvm.assume(i1 %off.1.pos)
746   %off.2.pos = icmp sge i8 %off.2, 0
747   call void @llvm.assume(i1 %off.2.pos)
749   %add.off.2 = add nsw i8 %start, %off.1
750   %c = icmp ult i8 %add.off.2, %high
751   ret i1 %c
754 define i1 @add_neg_1_known_sge_ult_1(i32 %a) {
755 ; CHECK-LABEL: @add_neg_1_known_sge_ult_1(
756 ; CHECK-NEXT:  entry:
757 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1
758 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
759 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -1
760 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
761 ; CHECK-NEXT:    ret i1 [[C]]
763 entry:
764   %a.sge = icmp sge i32 %a, 1
765   call void @llvm.assume(i1 %a.sge)
766   %sub = add nsw i32 %a, -1
767   %c = icmp ult i32 %sub, %a
768   ret i1 %c
771 define i1 @add_neg_1_known_sge_uge_1(i32 %a) {
772 ; CHECK-LABEL: @add_neg_1_known_sge_uge_1(
773 ; CHECK-NEXT:  entry:
774 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 1
775 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
776 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -1
777 ; CHECK-NEXT:    ret i1 true
779 entry:
780   %a.sge = icmp sge i32 %a, 1
781   call void @llvm.assume(i1 %a.sge)
782   %sub = add nsw i32 %a, -1
783   %c = icmp uge i32 %sub, 0
784   ret i1 %c
787 define i1 @add_neg_1_not_known_sge_ult_1(i32 %a) {
788 ; CHECK-LABEL: @add_neg_1_not_known_sge_ult_1(
789 ; CHECK-NEXT:  entry:
790 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0
791 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
792 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -1
793 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
794 ; CHECK-NEXT:    ret i1 [[C]]
796 entry:
797   %a.sge = icmp sge i32 %a, 0
798   call void @llvm.assume(i1 %a.sge)
799   %sub = add nsw i32 %a, -1
800   %c = icmp ult i32 %sub, %a
801   ret i1 %c
804 define i1 @add_neg_1_not_known_sge_uge_1(i32 %a) {
805 ; CHECK-LABEL: @add_neg_1_not_known_sge_uge_1(
806 ; CHECK-NEXT:  entry:
807 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 0
808 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
809 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -1
810 ; CHECK-NEXT:    ret i1 true
812 entry:
813   %a.sge = icmp sge i32 %a, 0
814   call void @llvm.assume(i1 %a.sge)
815   %sub = add nsw i32 %a, -1
816   %c = icmp uge i32 %sub, 0
817   ret i1 %c
820 define i1 @add_neg_3_known_sge_ult_1(i32 %a) {
821 ; CHECK-LABEL: @add_neg_3_known_sge_ult_1(
822 ; CHECK-NEXT:  entry:
823 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 3
824 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
825 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -3
826 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
827 ; CHECK-NEXT:    ret i1 [[C]]
829 entry:
830   %a.sge = icmp sge i32 %a, 3
831   call void @llvm.assume(i1 %a.sge)
832   %sub = add nsw i32 %a, -3
833   %c = icmp ult i32 %sub, %a
834   ret i1 %c
837 define i1 @add_neg_3_known_sge_uge_1(i32 %a) {
838 ; CHECK-LABEL: @add_neg_3_known_sge_uge_1(
839 ; CHECK-NEXT:  entry:
840 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 4
841 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
842 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -3
843 ; CHECK-NEXT:    ret i1 true
845 entry:
846   %a.sge = icmp sge i32 %a, 4
847   call void @llvm.assume(i1 %a.sge)
848   %sub = add nsw i32 %a, -3
849   %c = icmp uge i32 %sub, 0
850   ret i1 %c
853 define i1 @add_neg_3_not_known_sge_ult_1(i32 %a) {
854 ; CHECK-LABEL: @add_neg_3_not_known_sge_ult_1(
855 ; CHECK-NEXT:  entry:
856 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2
857 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
858 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -3
859 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
860 ; CHECK-NEXT:    ret i1 [[C]]
862 entry:
863   %a.sge = icmp sge i32 %a, 2
864   call void @llvm.assume(i1 %a.sge)
865   %sub = add nsw i32 %a, -3
866   %c = icmp ult i32 %sub, %a
867   ret i1 %c
870 define i1 @add_neg_3_not_known_sge_uge_1(i32 %a) {
871 ; CHECK-LABEL: @add_neg_3_not_known_sge_uge_1(
872 ; CHECK-NEXT:  entry:
873 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], 2
874 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
875 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -3
876 ; CHECK-NEXT:    ret i1 true
878 entry:
879   %a.sge = icmp sge i32 %a, 2
880   call void @llvm.assume(i1 %a.sge)
881   %sub = add nsw i32 %a, -3
882   %c = icmp uge i32 %sub, 0
883   ret i1 %c
886 define i1 @add_neg_3_not_known_sge_ult_2(i32 %a, i32 %b) {
887 ; CHECK-LABEL: @add_neg_3_not_known_sge_ult_2(
888 ; CHECK-NEXT:  entry:
889 ; CHECK-NEXT:    [[A_SGE:%.*]] = icmp sge i32 [[A:%.*]], [[B:%.*]]
890 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_SGE]])
891 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[A]], -3
892 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[SUB]], [[A]]
893 ; CHECK-NEXT:    ret i1 [[C]]
895 entry:
896   %a.sge = icmp sge i32 %a, %b
897   call void @llvm.assume(i1 %a.sge)
898   %sub = add nsw i32 %a, -3
899   %c = icmp ult i32 %sub, %a
900   ret i1 %c