; 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]], 0.000000e+00 ; CHECK-NEXT: [[TMP3:%.*]] = fcmp one half [[Y]], 0.000000e+00 ; 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 }