| ; 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 | |
| } | |