[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / transfer-signed-facts-to-unsigned.ll
blob68e48c7d2944b18d2feae645d9a8175842f9a0d4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
4 define i1 @len_known_positive_via_idx_1(i8 %len, i8 %idx) {
5 ; CHECK-LABEL: @len_known_positive_via_idx_1(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i8 [[IDX:%.*]], 0
8 ; CHECK-NEXT:    [[IDX_SLT_LEN:%.*]] = icmp slt i8 [[IDX]], [[LEN:%.*]]
9 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[IDX_POS]], [[IDX_SLT_LEN]]
10 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
11 ; CHECK:       then.1:
12 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[LEN]], 2
13 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[LEN]], 2
14 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
15 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
16 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_2]]
17 ; CHECK-NEXT:    ret i1 [[RES_3]]
18 ; CHECK:       else:
19 ; CHECK-NEXT:    ret i1 false
21 entry:
22   %idx.pos = icmp sge i8 %idx, 0
23   %idx.slt.len  = icmp slt i8 %idx, %len
24   %and.1 = and i1 %idx.pos, %idx.slt.len
25   br i1 %and.1, label %then.1, label %else
27 then.1:
28   %t.1 = icmp ult i8 %idx, %len
29   %t.2 = icmp sge i8 %len, 0
30   %c.1 = icmp sge i8 %len, 2
31   %c.2 = icmp sge i8 %len, 2
32   %res.1 = xor i1 %t.1, %t.2
33   %res.2 = xor i1 %res.1, %c.1
34   %res.3 = xor i1 %res.2, %c.2
35   ret i1 %res.3
37 else:
38   ret i1 0
41 define i1 @len_known_positive_via_idx_2(i8 %len, i8 %idx) {
42 ; CHECK-LABEL: @len_known_positive_via_idx_2(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[IDX_SLT_LEN:%.*]] = icmp slt i8 [[IDX:%.*]], [[LEN:%.*]]
45 ; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i8 [[IDX]], 0
46 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[IDX_SLT_LEN]], [[IDX_POS]]
47 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
48 ; CHECK:       then.1:
49 ; CHECK-NEXT:    [[C_1:%.*]] = icmp sge i8 [[LEN]], 2
50 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[LEN]], 2
51 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
52 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
53 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_2]]
54 ; CHECK-NEXT:    ret i1 [[RES_3]]
55 ; CHECK:       else:
56 ; CHECK-NEXT:    ret i1 false
58 entry:
59   %idx.slt.len  = icmp slt i8 %idx, %len
60   %idx.pos = icmp sge i8 %idx, 0
61   %and.1 = and i1 %idx.slt.len, %idx.pos
62   br i1 %and.1, label %then.1, label %else
64 then.1:
65   %t.1 = icmp ult i8 %idx, %len
66   %t.2 = icmp sge i8 %len, 0
67   %c.1 = icmp sge i8 %len, 2
68   %c.2 = icmp sge i8 %len, 2
69   %res.1 = xor i1 %t.1, %t.2
70   %res.2 = xor i1 %res.1, %c.1
71   %res.3 = xor i1 %res.2, %c.2
72   ret i1 %res.3
74 else:
75   ret i1 0
78 define i1 @len_not_known_positive1(i8 %len, i8 %idx) {
79 ; CHECK-LABEL: @len_not_known_positive1(
80 ; CHECK-NEXT:  entry:
81 ; CHECK-NEXT:    [[IDX_SLT_LEN:%.*]] = icmp slt i8 [[IDX:%.*]], [[LEN:%.*]]
82 ; CHECK-NEXT:    br i1 [[IDX_SLT_LEN]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
83 ; CHECK:       then.1:
84 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[IDX]], [[LEN]]
85 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[LEN]], 0
86 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[LEN]], 2
87 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[LEN]], 2
88 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
89 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]
90 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_4]]
91 ; CHECK-NEXT:    ret i1 [[RES_3]]
92 ; CHECK:       else:
93 ; CHECK-NEXT:    ret i1 false
95 entry:
96   %idx.slt.len  = icmp slt i8 %idx, %len
97   br i1 %idx.slt.len, label %then.1, label %else
99 then.1:
100   %c.1 = icmp ult i8 %idx, %len
101   %c.2 = icmp sge i8 %len, 0
102   %c.3 = icmp sge i8 %len, 2
103   %c.4 = icmp sge i8 %len, 2
104   %res.1 = xor i1 %c.1, %c.2
105   %res.2 = xor i1 %res.1, %c.3
106   %res.3 = xor i1 %res.2, %c.4
107   ret i1 %res.3
109 else:
110   ret i1 0
113 define i1 @len_not_known_positive2(i8 %len, i8 %idx) {
114 ; CHECK-LABEL: @len_not_known_positive2(
115 ; CHECK-NEXT:  entry:
116 ; CHECK-NEXT:    [[IDX_SLT_LEN:%.*]] = icmp slt i8 [[IDX:%.*]], [[LEN:%.*]]
117 ; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[IDX_SLT_LEN]], true
118 ; CHECK-NEXT:    br i1 [[AND_1]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
119 ; CHECK:       then.1:
120 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 [[IDX]], [[LEN]]
121 ; CHECK-NEXT:    [[C_2:%.*]] = icmp sge i8 [[LEN]], 0
122 ; CHECK-NEXT:    [[C_3:%.*]] = icmp sge i8 [[LEN]], 2
123 ; CHECK-NEXT:    [[C_4:%.*]] = icmp sge i8 [[LEN]], 2
124 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
125 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]
126 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_4]]
127 ; CHECK-NEXT:    ret i1 [[RES_3]]
128 ; CHECK:       else:
129 ; CHECK-NEXT:    ret i1 false
131 entry:
132   %idx.slt.len  = icmp slt i8 %idx, %len
133   %idx.pos = icmp uge i8 %idx, 0
134   %and.1 = and i1 %idx.slt.len, %idx.pos
135   br i1 %and.1, label %then.1, label %else
137 then.1:
138   %c.1 = icmp ult i8 %idx, %len
139   %c.2 = icmp sge i8 %len, 0
140   %c.3 = icmp sge i8 %len, 2
141   %c.4 = icmp sge i8 %len, 2
142   %res.1 = xor i1 %c.1, %c.2
143   %res.2 = xor i1 %res.1, %c.3
144   %res.3 = xor i1 %res.2, %c.4
145   ret i1 %res.3
147 else:
148   ret i1 0
151 declare void @sink(ptr)
152 declare void @llvm.assume(i1)
154 define i1 @cnt_positive_sgt_against_base(ptr %p, i32 %cnt) {
155 ; CHECK-LABEL: @cnt_positive_sgt_against_base(
156 ; CHECK-NEXT:  entry:
157 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -1
158 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
159 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[CNT]]
160 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
161 ; CHECK:       then:
162 ; CHECK-NEXT:    ret i1 false
163 ; CHECK:       else:
164 ; CHECK-NEXT:    ret i1 true
166 entry:
167   %cmp = icmp sgt i32 %cnt, -1
168   tail call void @llvm.assume(i1 %cmp)
169   %add.ptr = getelementptr inbounds i32, ptr %p, i32 %cnt
170   %cmp.1 = icmp uge ptr %add.ptr, %p
171   br i1 %cmp.1, label %then, label %else
173 then:
174   ret i1 0
176 else:
177   ret i1 1
180 define i1 @cnt_not_known_positive_sgt_against_base(ptr %p, i32 %cnt) {
181 ; CHECK-LABEL: @cnt_not_known_positive_sgt_against_base(
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -2
184 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
185 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[CNT]]
186 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp uge ptr [[ADD_PTR]], [[P]]
187 ; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
188 ; CHECK:       then:
189 ; CHECK-NEXT:    ret i1 false
190 ; CHECK:       else:
191 ; CHECK-NEXT:    ret i1 true
193 entry:
194   %cmp = icmp sgt i32 %cnt, -2
195   tail call void @llvm.assume(i1 %cmp)
196   %add.ptr = getelementptr inbounds i32, ptr %p, i32 %cnt
197   %cmp.1 = icmp uge ptr %add.ptr, %p
198   br i1 %cmp.1, label %then, label %else
200 then:
201   ret i1 0
203 else:
204   ret i1 1
207 define i1 @cnt_not_known_positive_uge_against_base(ptr %p, i32 %cnt) {
208 ; CHECK-LABEL: @cnt_not_known_positive_uge_against_base(
209 ; CHECK-NEXT:  entry:
210 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[CNT:%.*]], 0
211 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
212 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[CNT]]
213 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp uge ptr [[ADD_PTR]], [[P]]
214 ; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
215 ; CHECK:       then:
216 ; CHECK-NEXT:    ret i1 false
217 ; CHECK:       else:
218 ; CHECK-NEXT:    ret i1 true
220 entry:
221   %cmp = icmp ugt i32 %cnt, 0
222   tail call void @llvm.assume(i1 %cmp)
223   %add.ptr = getelementptr inbounds i32, ptr %p, i32 %cnt
224   %cmp.1 = icmp uge ptr %add.ptr, %p
225   br i1 %cmp.1, label %then, label %else
227 then:
228   ret i1 0
230 else:
231   ret i1 1
234 define i1 @cnt_positive_sgt_against_base_with_zext(ptr %p, i32 %cnt) {
235 ; CHECK-LABEL: @cnt_positive_sgt_against_base_with_zext(
236 ; CHECK-NEXT:  entry:
237 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -1
238 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
239 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
240 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
241 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
242 ; CHECK:       then:
243 ; CHECK-NEXT:    ret i1 false
244 ; CHECK:       else:
245 ; CHECK-NEXT:    ret i1 true
247 entry:
248   %cmp = icmp sgt i32 %cnt, -1
249   tail call void @llvm.assume(i1 %cmp)
250   %ext = zext i32 %cnt to i64
251   %add.ptr = getelementptr inbounds i32, ptr %p, i64 %ext
252   %cmp.1 = icmp uge ptr %add.ptr, %p
253   br i1 %cmp.1, label %then, label %else
255 then:
256   ret i1 0
258 else:
259   ret i1 1
262 define i1 @cnt_positive_sge_against_base_with_zext(ptr %p, i32 %cnt) {
263 ; CHECK-LABEL: @cnt_positive_sge_against_base_with_zext(
264 ; CHECK-NEXT:  entry:
265 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CNT:%.*]], 0
266 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
267 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
268 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
269 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
270 ; CHECK:       then:
271 ; CHECK-NEXT:    ret i1 false
272 ; CHECK:       else:
273 ; CHECK-NEXT:    ret i1 true
275 entry:
276   %cmp = icmp sge i32 %cnt, 0
277   tail call void @llvm.assume(i1 %cmp)
278   %ext = zext i32 %cnt to i64
279   %add.ptr = getelementptr inbounds i32, ptr %p, i64 %ext
280   %cmp.1 = icmp uge ptr %add.ptr, %p
281   br i1 %cmp.1, label %then, label %else
283 then:
284   ret i1 0
286 else:
287   ret i1 1
290 define i1 @cnt_not_known_positive_sgt_against_base_with_zext(ptr %p, i32 %cnt) {
291 ; CHECK-LABEL: @cnt_not_known_positive_sgt_against_base_with_zext(
292 ; CHECK-NEXT:  entry:
293 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -2
294 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
295 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
296 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
297 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
298 ; CHECK:       then:
299 ; CHECK-NEXT:    ret i1 false
300 ; CHECK:       else:
301 ; CHECK-NEXT:    ret i1 true
303 entry:
304   %cmp = icmp sgt i32 %cnt, -2
305   tail call void @llvm.assume(i1 %cmp)
306   %ext = zext i32 %cnt to i64
307   %add.ptr = getelementptr inbounds i32, ptr %p, i64 %ext
308   %cmp.1 = icmp uge ptr %add.ptr, %p
309   br i1 %cmp.1, label %then, label %else
311 then:
312   ret i1 0
314 else:
315   ret i1 1
318 define i1 @cnt_not_known_positive_sge_against_base_with_zext(ptr %p, i32 %cnt) {
319 ; CHECK-LABEL: @cnt_not_known_positive_sge_against_base_with_zext(
320 ; CHECK-NEXT:  entry:
321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[CNT:%.*]], -1
322 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
323 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
324 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[EXT]]
325 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
326 ; CHECK:       then:
327 ; CHECK-NEXT:    ret i1 false
328 ; CHECK:       else:
329 ; CHECK-NEXT:    ret i1 true
331 entry:
332   %cmp = icmp sge i32 %cnt, -1
333   tail call void @llvm.assume(i1 %cmp)
334   %ext = zext i32 %cnt to i64
335   %add.ptr = getelementptr inbounds i32, ptr %p, i64 %ext
336   %cmp.1 = icmp uge ptr %add.ptr, %p
337   br i1 %cmp.1, label %then, label %else
339 then:
340   ret i1 0
342 else:
343   ret i1 1
346 ; TODO: Even though %cnt is not known signed positive %cmp can be simplified
347 ; because %add.ptr uses it zero-extended.
348 define i1 @cnt_not_signed_positive_uge_against_base_with_zext(ptr %p, i32 %cnt) {
349 ; CHECK-LABEL: @cnt_not_signed_positive_uge_against_base_with_zext(
350 ; CHECK-NEXT:  entry:
351 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[CNT:%.*]], 0
352 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
353 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i32 [[CNT]]
354 ; CHECK-NEXT:    [[CMP_1:%.*]] = icmp uge ptr [[ADD_PTR]], [[P]]
355 ; CHECK-NEXT:    br i1 [[CMP_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
356 ; CHECK:       then:
357 ; CHECK-NEXT:    ret i1 false
358 ; CHECK:       else:
359 ; CHECK-NEXT:    ret i1 true
361 entry:
362   %cmp = icmp uge i32 %cnt, 0
363   tail call void @llvm.assume(i1 %cmp)
364   %add.ptr = getelementptr inbounds i32, ptr %p, i32 %cnt
365   %cmp.1 = icmp uge ptr %add.ptr, %p
366   br i1 %cmp.1, label %then, label %else
368 then:
369   ret i1 0
371 else:
372   ret i1 1
375 %t = type { i32, [10 x i32] }
377 define i1 @cnt_positive_from_assume_check_against_base_struct_ugt_with_zext(ptr %p, i32 %cnt) {
378 ; CHECK-LABEL: @cnt_positive_from_assume_check_against_base_struct_ugt_with_zext(
379 ; CHECK-NEXT:  entry:
380 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -1
381 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP]])
382 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
383 ; CHECK-NEXT:    [[GEP_EXT:%.*]] = getelementptr inbounds [[T:%.*]], ptr [[P:%.*]], i64 0, i32 1, i64 [[EXT]]
384 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE:%.*]]
385 ; CHECK:       then:
386 ; CHECK-NEXT:    ret i1 false
387 ; CHECK:       else:
388 ; CHECK-NEXT:    tail call void @sink(ptr nonnull [[P]])
389 ; CHECK-NEXT:    ret i1 true
391 entry:
392   %cmp = icmp sgt i32 %cnt, -1
393   tail call void @llvm.assume(i1 %cmp)
394   %ext = zext i32 %cnt to i64
395   %gep.ext = getelementptr inbounds %t, ptr %p, i64 0, i32 1, i64 %ext
396   %cmp.1 = icmp ugt ptr %gep.ext, %p
397   br i1 %cmp.1, label %then, label %else
399 then:
400   ret i1 0
402 else:
403   tail call void @sink(ptr nonnull %p)
404   ret i1 1
407 define i1 @cnt_positive_from_branch_check_against_base_struct_ugt_with_zext(ptr %p, i32 %cnt) {
408 ; CHECK-LABEL: @cnt_positive_from_branch_check_against_base_struct_ugt_with_zext(
409 ; CHECK-NEXT:  entry:
410 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -1
411 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK:%.*]], label [[ELSE:%.*]]
412 ; CHECK:       check:
413 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
414 ; CHECK-NEXT:    [[GEP_EXT:%.*]] = getelementptr inbounds [[T:%.*]], ptr [[P:%.*]], i64 0, i32 1, i64 [[EXT]]
415 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE]]
416 ; CHECK:       then:
417 ; CHECK-NEXT:    ret i1 false
418 ; CHECK:       else:
419 ; CHECK-NEXT:    tail call void @sink(ptr nonnull [[P]])
420 ; CHECK-NEXT:    ret i1 true
422 entry:
423   %cmp = icmp sgt i32 %cnt, -1
424   br i1 %cmp, label %check, label %else
426 check:
427   %ext = zext i32 %cnt to i64
428   %gep.ext = getelementptr inbounds %t, ptr %p, i64 0, i32 1, i64 %ext
429   %cmp.1 = icmp ugt ptr %gep.ext, %p
430   br i1 %cmp.1, label %then, label %else
432 then:
433   ret i1 0
435 else:
436   tail call void @sink(ptr nonnull %p)
437   ret i1 1
440 ; because %add.ptr uses it zero-extended.
441 define i1 @cnt_not_known_positive_from_branch_check_against_base_struct_ugt_with_zext(ptr %p, i32 %cnt) {
442 ; CHECK-LABEL: @cnt_not_known_positive_from_branch_check_against_base_struct_ugt_with_zext(
443 ; CHECK-NEXT:  entry:
444 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -2
445 ; CHECK-NEXT:    br i1 [[CMP]], label [[CHECK:%.*]], label [[ELSE:%.*]]
446 ; CHECK:       check:
447 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[CNT]] to i64
448 ; CHECK-NEXT:    [[GEP_EXT:%.*]] = getelementptr inbounds [[T:%.*]], ptr [[P:%.*]], i64 0, i32 1, i64 [[EXT]]
449 ; CHECK-NEXT:    br i1 true, label [[THEN:%.*]], label [[ELSE]]
450 ; CHECK:       then:
451 ; CHECK-NEXT:    ret i1 false
452 ; CHECK:       else:
453 ; CHECK-NEXT:    tail call void @sink(ptr nonnull [[P]])
454 ; CHECK-NEXT:    ret i1 true
456 entry:
457   %cmp = icmp sgt i32 %cnt, -2
458   br i1 %cmp, label %check, label %else
460 check:
461   %ext = zext i32 %cnt to i64
462   %gep.ext = getelementptr inbounds %t, ptr %p, i64 0, i32 1, i64 %ext
463   %cmp.1 = icmp ugt ptr %gep.ext, %p
464   br i1 %cmp.1, label %then, label %else
466 then:
467   ret i1 0
469 else:
470   tail call void @sink(ptr nonnull %p)
471   ret i1 1
474 define i1 @sge_2(i8 %idx) {
475 ; CHECK-LABEL: @sge_2(
476 ; CHECK-NEXT:  entry:
477 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[IDX:%.*]], 2
478 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
479 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
480 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[IDX]], 3
481 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
482 ; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], false
483 ; CHECK-NEXT:    ret i1 [[RES_3]]
485 entry:
486   %cmp = icmp sge i8 %idx, 2
487   call void @llvm.assume(i1 %cmp)
488   %t.1 = icmp uge i8 %idx, 2
489   %t.2 = icmp uge i8 %idx, 1
490   %res.1 = xor i1 %t.1, %t.2
491   %c.1 = icmp uge i8 %idx, 3
492   %res.2 = xor i1 %res.1, %c.1
493   %f.1 = icmp ult i8 %idx, 2
494   %res.3 = xor i1 %res.2, %f.1
495   ret i1 %res.3
498 define i32 @sge_2_gep(i32 %idx, ptr %src, i32 %idx.2) {
499 ; CHECK-LABEL: @sge_2_gep(
500 ; CHECK-NEXT:  entry:
501 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = sext i32 [[IDX:%.*]] to i64
502 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[IDX_EXT]]
503 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[IDX]], 2
504 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
505 ; CHECK-NEXT:    [[ADD_PTR_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[IDX_2:%.*]]
506 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[SRC]], [[ADD_PTR_2]]
507 ; CHECK-NEXT:    [[X_1:%.*]] = xor i1 true, [[C_1]]
508 ; CHECK-NEXT:    [[X_2:%.*]] = xor i1 [[X_1]], false
509 ; CHECK-NEXT:    br i1 [[X_2]], label [[THEN:%.*]], label [[ELSE:%.*]]
510 ; CHECK:       then:
511 ; CHECK-NEXT:    ret i32 0
512 ; CHECK:       else:
513 ; CHECK-NEXT:    ret i32 10
515 entry:
516   %idx.ext = sext i32 %idx to i64
517   %add.ptr = getelementptr inbounds i32, ptr %src, i64 %idx.ext
518   %cmp = icmp sge i32 %idx, 2
519   call void @llvm.assume(i1 %cmp)
520   %add.ptr.2 = getelementptr inbounds i32, ptr %src, i32 %idx.2
521   %t.1 = icmp ult ptr %src, %add.ptr
522   %c.1 = icmp ult ptr %src, %add.ptr.2
523   %x.1 = xor i1 %t.1, %c.1
524   %f.1 = icmp uge ptr %src, %add.ptr
525   %x.2 = xor i1 %x.1, %f.1
526   br i1 %x.2, label %then, label %else
528 then:
529   ret i32 0
531 else:
532   ret i32 10
535 define i1 @sgt_known_neg(i8 %idx) {
536 ; CHECK-LABEL: @sgt_known_neg(
537 ; CHECK-NEXT:  entry:
538 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[IDX:%.*]], -1
539 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
540 ; CHECK-NEXT:    [[T_2:%.*]] = icmp uge i8 [[IDX]], 1
541 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[T_2]]
542 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[IDX]], -1
543 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
544 ; CHECK-NEXT:    ret i1 [[RES_2]]
546 entry:
547   %cmp = icmp sgt i8 %idx, -1
548   call void @llvm.assume(i1 %cmp)
549   %t.1 = icmp uge i8 %idx, 0
550   %t.2 = icmp uge i8 %idx, 1
551   %res.1 = xor i1 %t.1, %t.2
552   %c.1 = icmp ugt i8 %idx, -1
553   %res.2 = xor i1 %res.1, %c.1
554   ret i1 %res.2
557 define i1 @sgt_known_pos(i8 %idx) {
558 ; CHECK-LABEL: @sgt_known_pos(
559 ; CHECK-NEXT:  entry:
560 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[IDX:%.*]], 2
561 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
562 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
563 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[IDX]], 3
564 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
565 ; CHECK-NEXT:    ret i1 [[RES_2]]
567 entry:
568   %cmp = icmp sgt i8 %idx, 2
569   call void @llvm.assume(i1 %cmp)
570   %t.1 = icmp ugt i8 %idx, 2
571   %t.2 = icmp ugt i8 %idx, 1
572   %res.1 = xor i1 %t.1, %t.2
573   %c.1 = icmp ugt i8 %idx, 3
574   %res.2 = xor i1 %res.1, %c.1
575   ret i1 %res.2
578 define i1 @sgt_to_ugt(i8 %a) {
579 ; CHECK-LABEL: @sgt_to_ugt(
580 ; CHECK-NEXT:  entry:
581 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 2
582 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
583 ; CHECK-NEXT:    ret i1 true
585 entry:
586   %cmp = icmp sgt i8 %a, 2
587   call void @llvm.assume(i1 %cmp)
588   %t.1 = icmp ugt i8 %a, 2
589   ret i1 %t.1
592 define i1 @sgt_to_ugt_less(i8 %a) {
593 ; CHECK-LABEL: @sgt_to_ugt_less(
594 ; CHECK-NEXT:  entry:
595 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 2
596 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
597 ; CHECK-NEXT:    ret i1 true
599 entry:
600   %cmp = icmp sgt i8 %a, 2
601   call void @llvm.assume(i1 %cmp)
602   %t.1 = icmp ugt i8 %a, 1
603   ret i1 %t.1
606 define i1 @sgt_to_ugt_var(i8 %a, i8 %b) {
607 ; CHECK-LABEL: @sgt_to_ugt_var(
608 ; CHECK-NEXT:  entry:
609 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
610 ; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sgt i8 [[B]], 0
611 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
612 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_2]])
613 ; CHECK-NEXT:    ret i1 true
615 entry:
616   %cmp = icmp sgt i8 %a, %b
617   %cmp.2 = icmp sgt i8 %b, 0
618   call void @llvm.assume(i1 %cmp)
619   call void @llvm.assume(i1 %cmp.2)
620   %t.1 = icmp ugt i8 %a, %b
621   ret i1 %t.1
624 define i1 @sgt_to_ugt_no_range_info(i8 %a, i8 %b) {
625 ; CHECK-LABEL: @sgt_to_ugt_no_range_info(
626 ; CHECK-NEXT:  entry:
627 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
628 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
629 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[A]], [[B]]
630 ; CHECK-NEXT:    ret i1 [[C_1]]
632 entry:
633   %cmp = icmp sgt i8 %a, %b
634   call void @llvm.assume(i1 %cmp)
635   %c.1 = icmp ugt i8 %a, %b
636   ret i1 %c.1
639 define i1 @sgt_to_ugt_neg(i8 %a) {
640 ; CHECK-LABEL: @sgt_to_ugt_neg(
641 ; CHECK-NEXT:  entry:
642 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -1
643 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
644 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[A]], -1
645 ; CHECK-NEXT:    ret i1 [[C_1]]
647 entry:
648   %cmp = icmp sgt i8 %a, -1
649   call void @llvm.assume(i1 %cmp)
650   %c.1 = icmp ugt i8 %a, -1
651   ret i1 %c.1
654 define i1 @sgt_to_ugt_neg2(i8 %a) {
655 ; CHECK-LABEL: @sgt_to_ugt_neg2(
656 ; CHECK-NEXT:  entry:
657 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], -2
658 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
659 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[A]], -2
660 ; CHECK-NEXT:    ret i1 [[C_1]]
662 entry:
663   %cmp = icmp sgt i8 %a, -2
664   call void @llvm.assume(i1 %cmp)
665   %c.1 = icmp ugt i8 %a, -2
666   ret i1 %c.1
669 define i1 @sgt_to_ugt_var_neg(i8 %a, i8 %b) {
670 ; CHECK-LABEL: @sgt_to_ugt_var_neg(
671 ; CHECK-NEXT:  entry:
672 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
673 ; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sgt i8 [[B]], -2
674 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
675 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_2]])
676 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i8 [[A]], [[B]]
677 ; CHECK-NEXT:    ret i1 [[C_1]]
679 entry:
680   %cmp = icmp sgt i8 %a, %b
681   %cmp.2 = icmp sgt i8 %b, -2
682   call void @llvm.assume(i1 %cmp)
683   call void @llvm.assume(i1 %cmp.2)
684   %c.1 = icmp ugt i8 %a, %b
685   ret i1 %c.1
688 define i1 @slt_first_op_known_pos(i8 %idx) {
689 ; CHECK-LABEL: @slt_first_op_known_pos(
690 ; CHECK-NEXT:  entry:
691 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 2, [[IDX:%.*]]
692 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
693 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
694 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 3, [[IDX]]
695 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
696 ; CHECK-NEXT:    ret i1 [[RES_2]]
698 entry:
699   %cmp = icmp slt i8 2, %idx
700   call void @llvm.assume(i1 %cmp)
701   %t.1 = icmp ult i8 2, %idx
702   %t.2 = icmp ult i8 1, %idx
703   %res.1 = xor i1 %t.1, %t.2
704   %c.1 = icmp ult i8 3, %idx
705   %res.2 = xor i1 %res.1, %c.1
706   ret i1 %res.2
709 define i1 @slt_first_op_known_neg(i8 %idx) {
710 ; CHECK-LABEL: @slt_first_op_known_neg(
711 ; CHECK-NEXT:  entry:
712 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 -2, [[IDX:%.*]]
713 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
714 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult i8 2, [[IDX]]
715 ; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i8 1, [[IDX]]
716 ; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
717 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i8 3, [[IDX]]
718 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
719 ; CHECK-NEXT:    ret i1 [[RES_2]]
721 entry:
722   %cmp = icmp slt i8 -2, %idx
723   call void @llvm.assume(i1 %cmp)
724   %t.1 = icmp ult i8 2, %idx
725   %t.2 = icmp ult i8 1, %idx
726   %res.1 = xor i1 %t.1, %t.2
727   %c.1 = icmp ult i8 3, %idx
728   %res.2 = xor i1 %res.1, %c.1
729   ret i1 %res.2