|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| 2 | +; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s |
| 3 | + |
| 4 | + |
| 5 | +define i1 @infer_nuw(i8 range(i8 0, 2) %A, i8 range(i8 0, 2) %B) { |
| 6 | +; CHECK-LABEL: define i1 @infer_nuw( |
| 7 | +; CHECK-SAME: i8 range(i8 0, 2) [[A:%.*]], i8 range(i8 0, 2) [[B:%.*]]) { |
| 8 | +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[B]], [[A]] |
| 9 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[XOR]] to i1 |
| 10 | +; CHECK-NEXT: ret i1 [[TRUNC]] |
| 11 | +; |
| 12 | + %xor = xor i8 %B, %A |
| 13 | + %trunc = trunc i8 %xor to i1 |
| 14 | + ret i1 %trunc |
| 15 | +} |
| 16 | + |
| 17 | + |
| 18 | +define i4 @infer_nsw(i8 %A) { |
| 19 | +; CHECK-LABEL: define range(i4 -4, 4) i4 @infer_nsw( |
| 20 | +; CHECK-SAME: i8 [[A:%.*]]) { |
| 21 | +; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[A]], 5 |
| 22 | +; CHECK-NEXT: [[B:%.*]] = trunc nsw i8 [[ASHR]] to i4 |
| 23 | +; CHECK-NEXT: ret i4 [[B]] |
| 24 | +; |
| 25 | + %ashr = ashr i8 %A, 5 |
| 26 | + %result = trunc i8 %ashr to i4 |
| 27 | + ret i4 %result |
| 28 | +} |
| 29 | + |
| 30 | + |
| 31 | +define i8 @infer_nuw_nsw(i16 range(i16 -5, -3) %A, i16 range(i16 -5, -3) %B) { |
| 32 | +; CHECK-LABEL: define range(i8 0, 8) i8 @infer_nuw_nsw( |
| 33 | +; CHECK-SAME: i16 range(i16 -5, -3) [[A:%.*]], i16 range(i16 -5, -3) [[B:%.*]]) { |
| 34 | +; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[B]], [[A]] |
| 35 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw nsw i16 [[XOR]] to i8 |
| 36 | +; CHECK-NEXT: ret i8 [[TRUNC]] |
| 37 | +; |
| 38 | + %xor = xor i16 %B, %A |
| 39 | + %trunc = trunc i16 %xor to i8 |
| 40 | + ret i8 %trunc |
| 41 | +} |
| 42 | + |
| 43 | + |
| 44 | +define i8 @infer_nsw_from_assume(i16 %x) { |
| 45 | +; CHECK-LABEL: define i8 @infer_nsw_from_assume( |
| 46 | +; CHECK-SAME: i16 [[X:%.*]]) { |
| 47 | +; CHECK-NEXT: [[ADD:%.*]] = add i16 [[X]], 128 |
| 48 | +; CHECK-NEXT: [[OR_COND_I:%.*]] = icmp ult i16 [[ADD]], 256 |
| 49 | +; CHECK-NEXT: tail call void @llvm.assume(i1 [[OR_COND_I]]) |
| 50 | +; CHECK-NEXT: [[CONV1:%.*]] = trunc nsw i16 [[X]] to i8 |
| 51 | +; CHECK-NEXT: ret i8 [[CONV1]] |
| 52 | +; |
| 53 | + %add = add i16 %x, 128 |
| 54 | + %or.cond.i = icmp ult i16 %add, 256 |
| 55 | + tail call void @llvm.assume(i1 %or.cond.i) |
| 56 | + %conv1 = trunc i16 %x to i8 |
| 57 | + ret i8 %conv1 |
| 58 | +} |
| 59 | + |
| 60 | + |
| 61 | +define i1 @rust_issue_122734(i8 range(i8 0, 3) %A, i8 range(i8 0, 3) %B) { |
| 62 | +; CHECK-LABEL: define i1 @rust_issue_122734( |
| 63 | +; CHECK-SAME: i8 range(i8 0, 3) [[A:%.*]], i8 range(i8 0, 3) [[B:%.*]]) { |
| 64 | +; CHECK-NEXT: [[START:.*]]: |
| 65 | +; CHECK-NEXT: [[LHS:%.*]] = icmp eq i8 [[A]], 2 |
| 66 | +; CHECK-NEXT: [[RHS:%.*]] = icmp eq i8 [[B]], 2 |
| 67 | +; CHECK-NEXT: [[OR:%.*]] = or i1 [[LHS]], [[RHS]] |
| 68 | +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] |
| 69 | +; CHECK-NEXT: br i1 [[OR]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]] |
| 70 | +; CHECK: [[IFTRUE]]: |
| 71 | +; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ [[XOR2:%.*]], %[[IFFALSE]] ], [ [[AND]], %[[START]] ] |
| 72 | +; CHECK-NEXT: ret i1 [[PHI]] |
| 73 | +; CHECK: [[IFFALSE]]: |
| 74 | +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]] |
| 75 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[XOR]] to i1 |
| 76 | +; CHECK-NEXT: [[XOR2]] = xor i1 [[TRUNC]], true |
| 77 | +; CHECK-NEXT: br label %[[IFTRUE]] |
| 78 | +; |
| 79 | +start: |
| 80 | + %lhs = icmp eq i8 %A, 2 |
| 81 | + %rhs = icmp eq i8 %B, 2 |
| 82 | + %or = or i1 %lhs, %rhs |
| 83 | + %and = and i1 %lhs, %rhs |
| 84 | + br i1 %or, label %iftrue, label %iffalse |
| 85 | + |
| 86 | +iftrue: |
| 87 | + %phi = phi i1 [ %xor2, %iffalse], [ %and, %start ] |
| 88 | + ret i1 %phi |
| 89 | + |
| 90 | +iffalse: |
| 91 | + %xor = xor i8 %A, %B |
| 92 | + %trunc = trunc i8 %xor to i1 |
| 93 | + %xor2 = xor i1 %trunc, true |
| 94 | + br label %iftrue |
| 95 | +} |
| 96 | + |
| 97 | + |
| 98 | +define i1 @overdefined_range_negative(i8 %A, i8 %B) { |
| 99 | +; CHECK-LABEL: define i1 @overdefined_range_negative( |
| 100 | +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) { |
| 101 | +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]] |
| 102 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[XOR]] to i1 |
| 103 | +; CHECK-NEXT: ret i1 [[TRUNC]] |
| 104 | +; |
| 105 | + %xor = xor i8 %A, %B |
| 106 | + %trunc = trunc i8 %xor to i1 |
| 107 | + ret i1 %trunc |
| 108 | +} |
0 commit comments