Skip to content

Commit

Permalink
[InstCombine] Add example usage for new Checked matcher API
Browse files Browse the repository at this point in the history
There is no real motivation for this change other than to highlight a
case where the new `Checked` matcher API can handle non-splat-vecs
without increasing code complexity.

Closes #85676
  • Loading branch information
goldsteinn committed May 3, 2024
1 parent 1708788 commit f561daf
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 20 deletions.
16 changes: 6 additions & 10 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7128,34 +7128,30 @@ Instruction *InstCombinerImpl::foldICmpCommutative(ICmpInst::Predicate Pred,
return replaceInstUsesWith(CxtI, V);

// Folding (X / Y) pred X => X swap(pred) 0 for constant Y other than 0 or 1
auto CheckUGT1 = [](const APInt &Divisor) { return Divisor.ugt(1); };
{
const APInt *Divisor;
if (match(Op0, m_UDiv(m_Specific(Op1), m_APInt(Divisor))) &&
Divisor->ugt(1)) {
if (match(Op0, m_UDiv(m_Specific(Op1), m_CheckedInt(CheckUGT1)))) {
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1,
Constant::getNullValue(Op1->getType()));
}

if (!ICmpInst::isUnsigned(Pred) &&
match(Op0, m_SDiv(m_Specific(Op1), m_APInt(Divisor))) &&
Divisor->ugt(1)) {
match(Op0, m_SDiv(m_Specific(Op1), m_CheckedInt(CheckUGT1)))) {
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1,
Constant::getNullValue(Op1->getType()));
}
}

// Another case of this fold is (X >> Y) pred X => X swap(pred) 0 if Y != 0
auto CheckNE0 = [](const APInt &Shift) { return !Shift.isZero(); };
{
const APInt *Shift;
if (match(Op0, m_LShr(m_Specific(Op1), m_APInt(Shift))) &&
!Shift->isZero()) {
if (match(Op0, m_LShr(m_Specific(Op1), m_CheckedInt(CheckNE0)))) {
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1,
Constant::getNullValue(Op1->getType()));
}

if ((Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SGE) &&
match(Op0, m_AShr(m_Specific(Op1), m_APInt(Shift))) &&
!Shift->isZero()) {
match(Op0, m_AShr(m_Specific(Op1), m_CheckedInt(CheckNE0)))) {
return new ICmpInst(ICmpInst::getSwappedPredicate(Pred), Op1,
Constant::getNullValue(Op1->getType()));
}
Expand Down
16 changes: 6 additions & 10 deletions llvm/test/Transforms/InstCombine/icmp-div-constant.ll
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,8 @@ define i1 @udiv_x_by_const_cmp_x(i32 %x) {

define <2 x i1> @udiv_x_by_const_cmp_x_non_splat(<2 x i32> %x) {
; CHECK-LABEL: @udiv_x_by_const_cmp_x_non_splat(
; CHECK-NEXT: [[TMP1:%.*]] = udiv <2 x i32> [[X:%.*]], <i32 123, i32 -123>
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[TMP1]], [[X]]
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%1 = udiv <2 x i32> %x, <i32 123, i32 -123>
%2 = icmp slt <2 x i32> %1, %x
Expand All @@ -413,9 +412,8 @@ define <2 x i1> @udiv_x_by_const_cmp_x_non_splat(<2 x i32> %x) {

define <2 x i1> @sdiv_x_by_const_cmp_x_non_splat(<2 x i32> %x) {
; CHECK-LABEL: @sdiv_x_by_const_cmp_x_non_splat(
; CHECK-NEXT: [[TMP1:%.*]] = sdiv <2 x i32> [[X:%.*]], <i32 2, i32 3>
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], [[X]]
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%1 = sdiv <2 x i32> %x, <i32 2, i32 3>
%2 = icmp eq <2 x i32> %1, %x
Expand Down Expand Up @@ -446,8 +444,7 @@ define <4 x i1> @lshr_by_const_cmp_sle_value(<4 x i32> %x) {

define <4 x i1> @lshr_by_const_cmp_sle_value_non_splat(<4 x i32> %x) {
; CHECK-LABEL: @lshr_by_const_cmp_sle_value_non_splat(
; CHECK-NEXT: [[V:%.*]] = lshr <4 x i32> [[X:%.*]], <i32 3, i32 3, i32 3, i32 5>
; CHECK-NEXT: [[R:%.*]] = icmp sle <4 x i32> [[V]], [[X]]
; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[X:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1>
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%v = lshr <4 x i32> %x, <i32 3, i32 3, i32 3, i32 5>
Expand All @@ -458,8 +455,7 @@ define <4 x i1> @lshr_by_const_cmp_sle_value_non_splat(<4 x i32> %x) {

define <4 x i1> @ashr_by_const_cmp_sge_value_non_splat(<4 x i32> %x) {
; CHECK-LABEL: @ashr_by_const_cmp_sge_value_non_splat(
; CHECK-NEXT: [[V:%.*]] = ashr <4 x i32> [[X:%.*]], <i32 1, i32 2, i32 3, i32 4>
; CHECK-NEXT: [[R:%.*]] = icmp sge <4 x i32> [[V]], [[X]]
; CHECK-NEXT: [[R:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 1, i32 1, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i1> [[R]]
;
%v = ashr <4 x i32> %x, <i32 1, i32 2, i32 3, i32 4>
Expand Down

0 comments on commit f561daf

Please sign in to comment.