diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 10488ecb747a48..34c9e0fde4f428 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4018,6 +4018,16 @@ foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I, NewPredicate = ICmpInst::ICMP_ULE; break; + case ICmpInst::ICMP_ULT: + if (C.ugt(1)) + NewPredicate = ICmpInst::ICMP_UGE; + break; + + case ICmpInst::ICMP_UGT: + if (!C.isZero() && !C.isAllOnes()) + NewPredicate = ICmpInst::ICMP_ULT; + break; + default: break; } diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll index 2523872562cad9..460ea96b16fcfa 100644 --- a/llvm/test/Transforms/InstCombine/scmp.ll +++ b/llvm/test/Transforms/InstCombine/scmp.ll @@ -157,6 +157,31 @@ define i1 @scmp_sle_neg_1(i32 %x, i32 %y) { ret i1 %2 } +; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1 +define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[TMP1]] +; + %1 = call i8 @llvm.scmp(i32 %x, i32 %y) + %2 = icmp ult i8 %1, 4 + ret i1 %2 +} + +; scmp(x, y) s> C => x s< y when C != 0 and C != -1 +define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[TMP2]] +; + %1 = call i8 @llvm.scmp(i32 %x, i32 %y) + %2 = icmp ugt i8 %1, 12 + ret i1 %2 +} + + ; ========== Fold -scmp(x, y) => scmp(y, x) ========== define i8 @scmp_negated(i32 %x, i32 %y) { ; CHECK-LABEL: define i8 @scmp_negated( diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll index 7210455094baac..8690e23ea2e0e5 100644 --- a/llvm/test/Transforms/InstCombine/ucmp.ll +++ b/llvm/test/Transforms/InstCombine/ucmp.ll @@ -157,6 +157,30 @@ define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) { ret i1 %2 } +; ucmp(x, y) u< C => x u>= y when C u> 1 and C != -1 +define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @ucmp_ult_positive_const_gt_than_1_lt_than_umax( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[TMP1]] +; + %1 = call i8 @llvm.ucmp(i32 %x, i32 %y) + %2 = icmp ult i8 %1, 4 + ret i1 %2 +} + +; ucmp(x, y) u> C => x u< y when C != 0 and C != -1 +define i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[TMP2]] +; + %1 = call i8 @llvm.ucmp(i32 %x, i32 %y) + %2 = icmp ugt i8 %1, 12 + ret i1 %2 +} + ; ========== Fold -ucmp(x, y) => ucmp(y, x) ========== define i8 @ucmp_negated(i32 %x, i32 %y) { ; CHECK-LABEL: define i8 @ucmp_negated(