
This PR folds: `A == MIN_INT ? B != MIN_INT : A < B` to `A < B` `A == MAX_INT ? B != MAX_INT : A > B` to `A > B` Proof: https://alive2.llvm.org/ce/z/bR6E2s This helps in optimizing comparison of optional unsigned non-zero types in https://github.com/rust-lang/rust/issues/49892. Rust compiler's current output: https://rust.godbolt.org/z/9fxfq3Gn8
458 lines
14 KiB
LLVM
458 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
define i1 @compare_unsigned_min(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_unsigned_min(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP2]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_signed_min(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_signed_min(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, -128
|
|
%cmp2 = icmp ne i8 %y, -128
|
|
%cmp3 = icmp slt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_unsigned_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_unsigned_max(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 255
|
|
%cmp2 = icmp ne i8 %y, 255
|
|
%cmp3 = icmp ugt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_signed_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_signed_max(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 127
|
|
%cmp2 = icmp ne i8 %y, 127
|
|
%cmp3 = icmp sgt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @relational_cmp_unsigned_min(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @relational_cmp_unsigned_min(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp ule i8 %x, 0
|
|
%cmp2 = icmp ugt i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @relational_cmp_signed_min(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @relational_cmp_signed_min(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp sle i8 %x, -128
|
|
%cmp2 = icmp sgt i8 %y, -128
|
|
%cmp3 = icmp slt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @relational_cmp_unsigned_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @relational_cmp_unsigned_max(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp uge i8 %x, 255
|
|
%cmp2 = icmp ult i8 %y, 255
|
|
%cmp3 = icmp ugt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @relational_cmp_signed_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @relational_cmp_signed_max(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp sge i8 %x, 127
|
|
%cmp2 = icmp slt i8 %y, 127
|
|
%cmp3 = icmp sgt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
declare void @use(i1)
|
|
|
|
define i1 @compare_signed_max_multiuse(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_signed_max_multiuse(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: call void @use(i1 [[TMP4]])
|
|
; CHECK-NEXT: [[RESULT:%.*]] = icmp sgt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 127
|
|
%cmp2 = icmp ne i8 %y, 127
|
|
%cmp3 = icmp sgt i8 %x, %y
|
|
call void @use(i1 %cmp3)
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_signed_min_samesign(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_signed_min_samesign(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = icmp slt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, -128
|
|
%cmp2 = icmp ne i8 %y, -128
|
|
%cmp3 = icmp samesign slt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_flipped(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_flipped(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ugt i8 %y, %x
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_swapped(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_swapped(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp ne i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp3, i1 %cmp2
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_swapped_flipped_unsigned_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_swapped_flipped_unsigned_max(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = icmp ugt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp ne i8 %x, 255
|
|
%cmp2 = icmp ne i8 %y, 255
|
|
%cmp3 = icmp ult i8 %y, %x
|
|
%result = select i1 %cmp1, i1 %cmp3, i1 %cmp2
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_unsigned_min_illegal_type(i9 %x, i9 %y) {
|
|
; CHECK-LABEL: define i1 @compare_unsigned_min_illegal_type(
|
|
; CHECK-SAME: i9 [[X:%.*]], i9 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i9 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[TMP2]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i9 %x, 0
|
|
%cmp2 = icmp ne i9 %y, 0
|
|
%cmp3 = icmp ult i9 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_true_poison(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_true_poison(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: ret i1 [[CMP3]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 poison, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define <2 x i1> @compare_vector(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: define <2 x i1> @compare_vector(
|
|
; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i8> [[X]], [[Y]]
|
|
; CHECK-NEXT: ret <2 x i1> [[TMP1]]
|
|
;
|
|
%cmp1 = icmp eq <2 x i8> %x, zeroinitializer
|
|
%cmp2 = icmp ne <2 x i8> %y, zeroinitializer
|
|
%cmp3 = icmp ult <2 x i8> %x, %y
|
|
%result = select <2 x i1> %cmp1, <2 x i1> %cmp2, <2 x i1> %cmp3
|
|
ret <2 x i1> %result
|
|
}
|
|
|
|
define i1 @compare_pointer_negative(ptr %x, ptr %y) {
|
|
; CHECK-LABEL: define i1 @compare_pointer_negative(
|
|
; CHECK-SAME: ptr [[X:%.*]], ptr [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[X]], inttoptr (i8 127 to ptr)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne ptr [[Y]], inttoptr (i8 127 to ptr)
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt ptr [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%X = inttoptr i8 127 to ptr
|
|
%cmp1 = icmp eq ptr %x, %X
|
|
%cmp2 = icmp ne ptr %y, %X
|
|
%cmp3 = icmp sgt ptr %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_float_negative(half %x, half %y) {
|
|
; CHECK-LABEL: define i1 @compare_float_negative(
|
|
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fcmp one half [[Y]], 0xH0000
|
|
; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult half [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = fcmp oeq half %x, 0.0
|
|
%cmp2 = fcmp one half %y, 0.0
|
|
%cmp3 = fcmp ult half %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_unsigned_max_swapped_lhs_rhs_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_unsigned_max_swapped_lhs_rhs_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X]], -1
|
|
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp ne i8 [[Y]], -1
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[DOTNOT]], i1 [[TMP2]], i1 false
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 255
|
|
%cmp2 = icmp ne i8 %y, 255
|
|
%cmp3 = icmp ugt i8 %x, %y
|
|
%result = select i1 %cmp2, i1 %cmp1, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_signed_min_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_signed_min_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X]], -127
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[Y]], -127
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp slt i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, -127
|
|
%cmp2 = icmp ne i8 %y, -127
|
|
%cmp3 = icmp slt i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_unsigned_max_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_unsigned_max_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X]], -1
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[Y]], -1
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 255
|
|
%cmp2 = icmp ne i8 %y, 255
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @non_strict_op_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @non_strict_op_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X]], 0
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[Y]], 0
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ule i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_poison_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_poison_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Y]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP2]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 poison
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @mismatched_cond_lhs_negative(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: define i1 @mismatched_cond_lhs_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Y]], 0
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[Z]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %z, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @mismatched_trueval_lhs_negative(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: define i1 @mismatched_trueval_lhs_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Y]], 0
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[X]], [[Z]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %z
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @mismatched_constant_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @mismatched_constant_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Y]], 2
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp ne i8 %y, 2
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @mismatched_constant_two_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @mismatched_constant_two_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 2
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[Y]], 0
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 2
|
|
%cmp2 = icmp ne i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|
|
|
|
define i1 @compare_eq_eq_negative(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: define i1 @compare_eq_eq_negative(
|
|
; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[START:.*:]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[Y]], 0
|
|
; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
|
|
; CHECK-NEXT: ret i1 [[RESULT]]
|
|
;
|
|
start:
|
|
%cmp1 = icmp eq i8 %x, 0
|
|
%cmp2 = icmp eq i8 %y, 0
|
|
%cmp3 = icmp ult i8 %x, %y
|
|
%result = select i1 %cmp1, i1 %cmp2, i1 %cmp3
|
|
ret i1 %result
|
|
}
|