| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s |
| |
| ; Test that comparisons with -1 and 1 are transformed to equivalent |
| ; comparisons with 0, enabling simplifyICmpWithZero optimizations. |
| |
| ; ============================================================================ |
| ; Tests for icmp sgt X, -1 --> icmp sge X, 0 |
| ; ============================================================================ |
| |
| define i1 @sgt_minus1_nonnegative(i32 %x) { |
| ; CHECK-LABEL: @sgt_minus1_nonnegative( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %nonneg = and i32 %x, 2147483647 ; Clear sign bit, making x non-negative |
| %cmp = icmp sgt i32 %nonneg, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @sgt_minus1_positive(i32 %x) { |
| ; CHECK-LABEL: @sgt_minus1_positive( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %pos = or i32 %x, 1 ; Set bit 0 |
| %masked = and i32 %pos, 2147483647 ; Clear sign bit, making it non-negative and non-zero |
| %cmp = icmp sgt i32 %masked, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @sgt_minus1_negative(i32 %x) { |
| ; CHECK-LABEL: @sgt_minus1_negative( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %neg = or i32 %x, -2147483648 ; Set sign bit, making x negative |
| %cmp = icmp sgt i32 %neg, -1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp sle X, -1 --> icmp slt X, 0 |
| ; ============================================================================ |
| |
| define i1 @sle_minus1_nonnegative(i32 %x) { |
| ; CHECK-LABEL: @sle_minus1_nonnegative( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %nonneg = and i32 %x, 2147483647 ; Clear sign bit |
| %cmp = icmp sle i32 %nonneg, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @sle_minus1_negative(i32 %x) { |
| ; CHECK-LABEL: @sle_minus1_negative( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %neg = or i32 %x, -2147483648 ; Set sign bit |
| %cmp = icmp sle i32 %neg, -1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp ugt X, -1 --> icmp ult X, 0 |
| ; ============================================================================ |
| ; Note: -1 in unsigned is the maximum value (all bits set), so ugt X, -1 is always false |
| |
| define i1 @ugt_minus1_any(i32 %x) { |
| ; CHECK-LABEL: @ugt_minus1_any( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %cmp = icmp ugt i32 %x, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @ugt_minus1_zero(i32 %x) { |
| ; CHECK-LABEL: @ugt_minus1_zero( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %zero = and i32 %x, 0 ; Make x = 0 |
| %cmp = icmp ugt i32 %zero, -1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp ule X, -1 --> icmp uge X, 0 |
| ; ============================================================================ |
| ; Note: -1 in unsigned is the maximum value, so ule X, -1 is always true |
| |
| define i1 @ule_minus1_any(i32 %x) { |
| ; CHECK-LABEL: @ule_minus1_any( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %cmp = icmp ule i32 %x, -1 |
| ret i1 %cmp |
| } |
| |
| define i1 @ule_minus1_nonzero(i32 %x) { |
| ; CHECK-LABEL: @ule_minus1_nonzero( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %nonzero = or i32 %x, 1 ; Make x non-zero |
| %cmp = icmp ule i32 %nonzero, -1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp sge X, 1 --> icmp sgt X, 0 |
| ; ============================================================================ |
| |
| define i1 @sge_1_positive(i32 %x) { |
| ; CHECK-LABEL: @sge_1_positive( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %pos = or i32 %x, 1 ; Set bit 0 |
| %masked = and i32 %pos, 2147483647 ; Clear sign bit, making it positive |
| %cmp = icmp sge i32 %masked, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @sge_1_zero(i32 %x) { |
| ; CHECK-LABEL: @sge_1_zero( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %zero = and i32 %x, 0 ; Make x = 0 |
| %cmp = icmp sge i32 %zero, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @sge_1_negative(i32 %x) { |
| ; CHECK-LABEL: @sge_1_negative( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %neg = or i32 %x, -2147483648 ; Set sign bit |
| %cmp = icmp sge i32 %neg, 1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp uge X, 1 --> icmp ugt X, 0 |
| ; ============================================================================ |
| |
| define i1 @uge_1_nonzero(i32 %x) { |
| ; CHECK-LABEL: @uge_1_nonzero( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %nonzero = or i32 %x, 1 ; Make x non-zero (at least 1) |
| %cmp = icmp uge i32 %nonzero, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @uge_1_zero(i32 %x) { |
| ; CHECK-LABEL: @uge_1_zero( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %zero = and i32 %x, 0 ; Make x = 0 |
| %cmp = icmp uge i32 %zero, 1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp slt X, 1 --> icmp sle X, 0 |
| ; ============================================================================ |
| |
| define i1 @slt_1_zero(i32 %x) { |
| ; CHECK-LABEL: @slt_1_zero( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %zero = and i32 %x, 0 ; Make x = 0 |
| %cmp = icmp slt i32 %zero, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @slt_1_negative(i32 %x) { |
| ; CHECK-LABEL: @slt_1_negative( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %neg = or i32 %x, -2147483648 ; Set sign bit |
| %cmp = icmp slt i32 %neg, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @slt_1_positive(i32 %x) { |
| ; CHECK-LABEL: @slt_1_positive( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %pos = or i32 %x, 1 ; Set bit 0 |
| %masked = and i32 %pos, 2147483647 ; Clear sign bit, making it positive |
| %cmp = icmp slt i32 %masked, 1 |
| ret i1 %cmp |
| } |
| |
| ; ============================================================================ |
| ; Tests for icmp ult X, 1 --> icmp ule X, 0 |
| ; ============================================================================ |
| |
| define i1 @ult_1_zero(i32 %x) { |
| ; CHECK-LABEL: @ult_1_zero( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %zero = and i32 %x, 0 ; Make x = 0 |
| %cmp = icmp ult i32 %zero, 1 |
| ret i1 %cmp |
| } |
| |
| define i1 @ult_1_nonzero(i32 %x) { |
| ; CHECK-LABEL: @ult_1_nonzero( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %nonzero = or i32 %x, 1 ; Make x non-zero (at least 1) |
| %cmp = icmp ult i32 %nonzero, 1 |
| ret i1 %cmp |
| } |
| |