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(
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:%.*]]
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]]
19 ; CHECK-NEXT: ret i1 false
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
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
41 define i1 @len_known_positive_via_idx_2(i8 %len, i8 %idx) {
42 ; CHECK-LABEL: @len_known_positive_via_idx_2(
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:%.*]]
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]]
56 ; CHECK-NEXT: ret i1 false
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
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
78 define i1 @len_not_known_positive1(i8 %len, i8 %idx) {
79 ; CHECK-LABEL: @len_not_known_positive1(
81 ; CHECK-NEXT: [[IDX_SLT_LEN:%.*]] = icmp slt i8 [[IDX:%.*]], [[LEN:%.*]]
82 ; CHECK-NEXT: br i1 [[IDX_SLT_LEN]], label [[THEN_1:%.*]], label [[ELSE:%.*]]
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]]
93 ; CHECK-NEXT: ret i1 false
96 %idx.slt.len = icmp slt i8 %idx, %len
97 br i1 %idx.slt.len, label %then.1, label %else
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
113 define i1 @len_not_known_positive2(i8 %len, i8 %idx) {
114 ; CHECK-LABEL: @len_not_known_positive2(
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:%.*]]
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]]
129 ; CHECK-NEXT: ret i1 false
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
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
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(
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:%.*]]
162 ; CHECK-NEXT: ret i1 false
164 ; CHECK-NEXT: ret i1 true
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
180 define i1 @cnt_not_known_positive_sgt_against_base(ptr %p, i32 %cnt) {
181 ; CHECK-LABEL: @cnt_not_known_positive_sgt_against_base(
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:%.*]]
189 ; CHECK-NEXT: ret i1 false
191 ; CHECK-NEXT: ret i1 true
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
207 define i1 @cnt_not_known_positive_uge_against_base(ptr %p, i32 %cnt) {
208 ; CHECK-LABEL: @cnt_not_known_positive_uge_against_base(
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:%.*]]
216 ; CHECK-NEXT: ret i1 false
218 ; CHECK-NEXT: ret i1 true
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
234 define i1 @cnt_positive_sgt_against_base_with_zext(ptr %p, i32 %cnt) {
235 ; CHECK-LABEL: @cnt_positive_sgt_against_base_with_zext(
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:%.*]]
243 ; CHECK-NEXT: ret i1 false
245 ; CHECK-NEXT: ret i1 true
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
262 define i1 @cnt_positive_sge_against_base_with_zext(ptr %p, i32 %cnt) {
263 ; CHECK-LABEL: @cnt_positive_sge_against_base_with_zext(
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:%.*]]
271 ; CHECK-NEXT: ret i1 false
273 ; CHECK-NEXT: ret i1 true
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
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(
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:%.*]]
299 ; CHECK-NEXT: ret i1 false
301 ; CHECK-NEXT: ret i1 true
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
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(
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:%.*]]
327 ; CHECK-NEXT: ret i1 false
329 ; CHECK-NEXT: ret i1 true
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
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(
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:%.*]]
357 ; CHECK-NEXT: ret i1 false
359 ; CHECK-NEXT: ret i1 true
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
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(
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:%.*]]
386 ; CHECK-NEXT: ret i1 false
388 ; CHECK-NEXT: tail call void @sink(ptr nonnull [[P]])
389 ; CHECK-NEXT: ret i1 true
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
403 tail call void @sink(ptr nonnull %p)
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(
410 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -1
411 ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK:%.*]], label [[ELSE:%.*]]
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]]
417 ; CHECK-NEXT: ret i1 false
419 ; CHECK-NEXT: tail call void @sink(ptr nonnull [[P]])
420 ; CHECK-NEXT: ret i1 true
423 %cmp = icmp sgt i32 %cnt, -1
424 br i1 %cmp, label %check, label %else
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
436 tail call void @sink(ptr nonnull %p)
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(
444 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CNT:%.*]], -2
445 ; CHECK-NEXT: br i1 [[CMP]], label [[CHECK:%.*]], label [[ELSE:%.*]]
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]]
451 ; CHECK-NEXT: ret i1 false
453 ; CHECK-NEXT: tail call void @sink(ptr nonnull [[P]])
454 ; CHECK-NEXT: ret i1 true
457 %cmp = icmp sgt i32 %cnt, -2
458 br i1 %cmp, label %check, label %else
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
470 tail call void @sink(ptr nonnull %p)
474 define i1 @sge_2(i8 %idx) {
475 ; CHECK-LABEL: @sge_2(
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]]
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
498 define i32 @sge_2_gep(i32 %idx, ptr %src, i32 %idx.2) {
499 ; CHECK-LABEL: @sge_2_gep(
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:%.*]]
511 ; CHECK-NEXT: ret i32 0
513 ; CHECK-NEXT: ret i32 10
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
535 define i1 @sgt_known_neg(i8 %idx) {
536 ; CHECK-LABEL: @sgt_known_neg(
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]]
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
557 define i1 @sgt_known_pos(i8 %idx) {
558 ; CHECK-LABEL: @sgt_known_pos(
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]]
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
578 define i1 @sgt_to_ugt(i8 %a) {
579 ; CHECK-LABEL: @sgt_to_ugt(
581 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 2
582 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
583 ; CHECK-NEXT: ret i1 true
586 %cmp = icmp sgt i8 %a, 2
587 call void @llvm.assume(i1 %cmp)
588 %t.1 = icmp ugt i8 %a, 2
592 define i1 @sgt_to_ugt_less(i8 %a) {
593 ; CHECK-LABEL: @sgt_to_ugt_less(
595 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], 2
596 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
597 ; CHECK-NEXT: ret i1 true
600 %cmp = icmp sgt i8 %a, 2
601 call void @llvm.assume(i1 %cmp)
602 %t.1 = icmp ugt i8 %a, 1
606 define i1 @sgt_to_ugt_var(i8 %a, i8 %b) {
607 ; CHECK-LABEL: @sgt_to_ugt_var(
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
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
624 define i1 @sgt_to_ugt_no_range_info(i8 %a, i8 %b) {
625 ; CHECK-LABEL: @sgt_to_ugt_no_range_info(
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]]
633 %cmp = icmp sgt i8 %a, %b
634 call void @llvm.assume(i1 %cmp)
635 %c.1 = icmp ugt i8 %a, %b
639 define i1 @sgt_to_ugt_neg(i8 %a) {
640 ; CHECK-LABEL: @sgt_to_ugt_neg(
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]]
648 %cmp = icmp sgt i8 %a, -1
649 call void @llvm.assume(i1 %cmp)
650 %c.1 = icmp ugt i8 %a, -1
654 define i1 @sgt_to_ugt_neg2(i8 %a) {
655 ; CHECK-LABEL: @sgt_to_ugt_neg2(
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]]
663 %cmp = icmp sgt i8 %a, -2
664 call void @llvm.assume(i1 %cmp)
665 %c.1 = icmp ugt i8 %a, -2
669 define i1 @sgt_to_ugt_var_neg(i8 %a, i8 %b) {
670 ; CHECK-LABEL: @sgt_to_ugt_var_neg(
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]]
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
688 define i1 @slt_first_op_known_pos(i8 %idx) {
689 ; CHECK-LABEL: @slt_first_op_known_pos(
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]]
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
709 define i1 @slt_first_op_known_neg(i8 %idx) {
710 ; CHECK-LABEL: @slt_first_op_known_neg(
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]]
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