diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-04-22 16:01:11 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-05-03 14:10:24 -0500 |
commit | f561daf989cfe011dd0edafc4621fac5ed421435 (patch) | |
tree | f31d6db4f5afa5d9d6a1d85b3c53ccae910b1023 | |
parent | 1708788d2d1091d1663cd859c5913121463a6b73 (diff) |
[InstCombine] Add example usage for new Checked matcher API
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
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/icmp-div-constant.ll | 16 |
2 files changed, 12 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index d16878064110..c60a290ce72e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -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())); } diff --git a/llvm/test/Transforms/InstCombine/icmp-div-constant.ll b/llvm/test/Transforms/InstCombine/icmp-div-constant.ll index d815e093a33f..f667e1aa105d 100644 --- a/llvm/test/Transforms/InstCombine/icmp-div-constant.ll +++ b/llvm/test/Transforms/InstCombine/icmp-div-constant.ll @@ -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 @@ -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 @@ -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> @@ -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> |