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