[llvm] [Instsimplify] lshr&icmp adds support for the or instruction (PR #69445)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 18 03:52:21 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: DianQK (DianQK)
<details>
<summary>Changes</summary>
Closes #<!-- -->69333.
---
Full diff: https://github.com/llvm/llvm-project/pull/69445.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+33-7)
- (modified) llvm/test/Transforms/InstSimplify/compare.ll (+128)
``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index b3feb2470e58efd..1665d6d63ab6e34 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3103,6 +3103,23 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
return nullptr;
}
+static bool existOrChain(const Value *From, const Value *To) {
+ const Value *LVal;
+ const Value *RVal;
+ SmallVector<const Value *, 10> WorkList;
+ WorkList.push_back(From);
+ while (!WorkList.empty() && WorkList.size() < 16) {
+ From = WorkList.pop_back_val();
+ if (match(From, m_Or(m_Value(LVal), m_Value(RVal)))) {
+ if (LVal == To || RVal == To)
+ return true;
+ WorkList.push_back(LVal);
+ WorkList.push_back(RVal);
+ }
+ }
+ return false;
+}
+
static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
BinaryOperator *LBO, Value *RHS,
const SimplifyQuery &Q,
@@ -3174,16 +3191,25 @@ static Value *simplifyICmpWithBinOpOnLHS(CmpInst::Predicate Pred,
}
// x >>u y <=u x --> true.
+ // x >>u y <=u x | z --> true.
// x >>u y >u x --> false.
+ // x >>u y >u x | z --> false.
// x udiv y <=u x --> true.
+ // x udiv y <=u x | z --> true.
// x udiv y >u x --> false.
- if (match(LBO, m_LShr(m_Specific(RHS), m_Value())) ||
- match(LBO, m_UDiv(m_Specific(RHS), m_Value()))) {
- // icmp pred (X op Y), X
- if (Pred == ICmpInst::ICMP_UGT)
- return getFalse(ITy);
- if (Pred == ICmpInst::ICMP_ULE)
- return getTrue(ITy);
+ // x udiv y >u x | z --> false.
+ const Value *RHS0;
+ if (match(LBO, m_LShr(m_Value(RHS0), m_Value())) ||
+ match(LBO, m_UDiv(m_Value(RHS0), m_Value()))) {
+ if (RHS0 == RHS || existOrChain(RHS, RHS0)) {
+ // icmp pred (X op Y), X
+ if (Pred == ICmpInst::ICMP_UGT) {
+ return getFalse(ITy);
+ }
+ if (Pred == ICmpInst::ICMP_ULE) {
+ return getTrue(ITy);
+ }
+ }
}
// If x is nonzero:
diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll
index ac2ebf52ed6296e..75c9a69b26245d4 100644
--- a/llvm/test/Transforms/InstSimplify/compare.ll
+++ b/llvm/test/Transforms/InstSimplify/compare.ll
@@ -565,6 +565,134 @@ define i1 @lshr7(i32 %X, i32 %Y) {
ret i1 %C
}
+define i1 @or_lshr1(i32 %X, i32 %Y, i32 %Z) {
+; CHECK-LABEL: @or_lshr1(
+; CHECK-NEXT: ret i1 false
+;
+ %A = lshr i32 %X, %Y
+ %B = or i32 %X, %Z
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_lshr2(i32 %X, i32 %Y, i32 %Z) {
+; CHECK-LABEL: @or_lshr2(
+; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B:%.*]] = or i32 [[Y]], [[Z:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = lshr i32 %X, %Y
+ %B = or i32 %Y, %Z
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_lshr3(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_lshr3(
+; CHECK-NEXT: ret i1 false
+;
+ %A = lshr i32 %X, %Y
+ %B0 = or i32 %X, %Z
+ %B = or i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_lshr4(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_lshr4(
+; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B0:%.*]] = or i32 [[Y]], [[Z:%.*]]
+; CHECK-NEXT: [[B:%.*]] = or i32 [[B0]], [[Z1:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = lshr i32 %X, %Y
+ %B0 = or i32 %Y, %Z
+ %B = or i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_lshr5(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_lshr5(
+; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B0:%.*]] = or i32 [[X]], [[Z:%.*]]
+; CHECK-NEXT: [[B:%.*]] = and i32 [[B0]], [[Z1:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = lshr i32 %X, %Y
+ %B0 = or i32 %X, %Z
+ %B = and i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_udiv1(i32 %X, i32 %Y, i32 %Z) {
+; CHECK-LABEL: @or_udiv1(
+; CHECK-NEXT: ret i1 false
+;
+ %A = udiv i32 %X, %Y
+ %B = or i32 %X, %Z
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_udiv2(i32 %X, i32 %Y, i32 %Z) {
+; CHECK-LABEL: @or_udiv2(
+; CHECK-NEXT: [[A:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B:%.*]] = or i32 [[Y]], [[Z:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = udiv i32 %X, %Y
+ %B = or i32 %Y, %Z
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_udiv3(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_udiv3(
+; CHECK-NEXT: ret i1 false
+;
+ %A = udiv i32 %X, %Y
+ %B0 = or i32 %X, %Z
+ %B = or i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_udiv4(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_udiv4(
+; CHECK-NEXT: [[A:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B0:%.*]] = or i32 [[Y]], [[Z:%.*]]
+; CHECK-NEXT: [[B:%.*]] = or i32 [[B0]], [[Z1:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = udiv i32 %X, %Y
+ %B0 = or i32 %Y, %Z
+ %B = or i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
+define i1 @or_udiv5(i32 %X, i32 %Y, i32 %Z, i32 %Z1) {
+; CHECK-LABEL: @or_udiv5(
+; CHECK-NEXT: [[A:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[B0:%.*]] = or i32 [[X]], [[Z:%.*]]
+; CHECK-NEXT: [[B:%.*]] = and i32 [[B0]], [[Z1:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[B]], [[A]]
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %A = udiv i32 %X, %Y
+ %B0 = or i32 %X, %Z
+ %B = and i32 %B0, %Z1
+ %C = icmp ult i32 %B, %A
+ ret i1 %C
+}
+
define i1 @lshr_nonzero_eq(i32 %x) {
; CHECK-LABEL: @lshr_nonzero_eq(
; CHECK-NEXT: [[X_NE_0:%.*]] = icmp ne i32 [[X:%.*]], 0
``````````
</details>
https://github.com/llvm/llvm-project/pull/69445
More information about the llvm-commits
mailing list