|
| 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 i8 [[XOR]] to i1 |
| 10 | +; CHECK-NEXT: [[RESULT:%.*]] = xor i1 [[TRUNC]], true |
| 11 | +; CHECK-NEXT: ret i1 [[RESULT]] |
| 12 | +; |
| 13 | + %xor = xor i8 %B, %A |
| 14 | + %trunc = trunc i8 %xor to i1 |
| 15 | + %result = xor i1 %trunc, true |
| 16 | + ret i1 %result |
| 17 | +} |
| 18 | + |
| 19 | + |
| 20 | +define i4 @infer_nsw(i8 %A) { |
| 21 | +; CHECK-LABEL: define range(i4 -4, 4) i4 @infer_nsw( |
| 22 | +; CHECK-SAME: i8 [[A:%.*]]) { |
| 23 | +; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[A]], 5 |
| 24 | +; CHECK-NEXT: [[B:%.*]] = trunc i8 [[ASHR]] to i4 |
| 25 | +; CHECK-NEXT: ret i4 [[B]] |
| 26 | +; |
| 27 | + %ashr = ashr i8 %A, 5 |
| 28 | + %result = trunc i8 %ashr to i4 |
| 29 | + ret i4 %result |
| 30 | +} |
| 31 | + |
| 32 | + |
| 33 | +define i8 @infer_nuw_nsw(i16 range(i16 -5, -3) %A, i16 range(i16 -5, -3) %B) { |
| 34 | +; CHECK-LABEL: define range(i8 0, 8) i8 @infer_nuw_nsw( |
| 35 | +; CHECK-SAME: i16 range(i16 -5, -3) [[A:%.*]], i16 range(i16 -5, -3) [[B:%.*]]) { |
| 36 | +; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[B]], [[A]] |
| 37 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[XOR]] to i8 |
| 38 | +; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TRUNC]], 1 |
| 39 | +; CHECK-NEXT: ret i8 [[XOR2]] |
| 40 | +; |
| 41 | + %xor = xor i16 %B, %A |
| 42 | + %trunc = trunc i16 %xor to i8 |
| 43 | + %xor2 = xor i8 %trunc, 1 |
| 44 | + ret i8 %xor2 |
| 45 | +} |
| 46 | + |
| 47 | + |
| 48 | +define i1 @rust_issue_122734(i8 range(i8 0, 3) %A, i8 range(i8 0, 3) %B) { |
| 49 | +; CHECK-LABEL: define i1 @rust_issue_122734( |
| 50 | +; CHECK-SAME: i8 range(i8 0, 3) [[A:%.*]], i8 range(i8 0, 3) [[B:%.*]]) { |
| 51 | +; CHECK-NEXT: [[START:.*]]: |
| 52 | +; CHECK-NEXT: [[LHS:%.*]] = icmp eq i8 [[A]], 2 |
| 53 | +; CHECK-NEXT: [[RHS:%.*]] = icmp eq i8 [[B]], 2 |
| 54 | +; CHECK-NEXT: [[OR:%.*]] = or i1 [[LHS]], [[RHS]] |
| 55 | +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] |
| 56 | +; CHECK-NEXT: br i1 [[OR]], label %[[IFTRUE:.*]], label %[[IFFALSE:.*]] |
| 57 | +; CHECK: [[IFTRUE]]: |
| 58 | +; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ [[XOR2:%.*]], %[[IFFALSE]] ], [ [[AND]], %[[START]] ] |
| 59 | +; CHECK-NEXT: ret i1 [[PHI]] |
| 60 | +; CHECK: [[IFFALSE]]: |
| 61 | +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]] |
| 62 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[XOR]] to i1 |
| 63 | +; CHECK-NEXT: [[XOR2]] = xor i1 [[TRUNC]], true |
| 64 | +; CHECK-NEXT: br label %[[IFTRUE]] |
| 65 | +; |
| 66 | +start: |
| 67 | + %lhs = icmp eq i8 %A, 2 |
| 68 | + %rhs = icmp eq i8 %B, 2 |
| 69 | + %or = or i1 %lhs, %rhs |
| 70 | + %and = and i1 %lhs, %rhs |
| 71 | + br i1 %or, label %iftrue, label %iffalse |
| 72 | + |
| 73 | +iftrue: |
| 74 | + %phi = phi i1 [ %xor2, %iffalse], [ %and, %start ] |
| 75 | + ret i1 %phi |
| 76 | + |
| 77 | +iffalse: |
| 78 | + %xor = xor i8 %A, %B |
| 79 | + %trunc = trunc i8 %xor to i1 |
| 80 | + %xor2 = xor i1 %trunc, true |
| 81 | + br label %iftrue |
| 82 | +} |
| 83 | + |
| 84 | + |
| 85 | +define i1 @overdefined_range_negative(i8 %A, i8 %B) { |
| 86 | +; CHECK-LABEL: define i1 @overdefined_range_negative( |
| 87 | +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) { |
| 88 | +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A]], [[B]] |
| 89 | +; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[XOR]] to i1 |
| 90 | +; CHECK-NEXT: [[XOR2:%.*]] = xor i1 [[TRUNC]], true |
| 91 | +; CHECK-NEXT: ret i1 [[XOR2]] |
| 92 | +; |
| 93 | + %xor = xor i8 %A, %B |
| 94 | + %trunc = trunc i8 %xor to i1 |
| 95 | + %xor2 = xor i1 %trunc, true |
| 96 | + ret i1 %xor2 |
| 97 | +} |
0 commit comments