[llvm] [InstCombine] fold `(icmp eq/ne (or disjoint x, C0), C1)` -> `(icmp eq/ne x, C0^C1)` (PR #87734)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 4 19:20:11 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: None (goldsteinn)
<details>
<summary>Changes</summary>
- **[InstCombine] Add tests for folding `(icmp eq/ne (or disjoint x, C0), C1)`; NFC**
- **[InstCombine] fold `(icmp eq/ne (or disjoint x, C0), C1)` -> `(icmp eq/ne x, C0^C1)`**
Proof: https://alive2.llvm.org/ce/z/m3xoo_
---
Full diff: https://github.com/llvm/llvm-project/pull/87734.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp (+11)
- (modified) llvm/test/Transforms/InstCombine/icmp-or.ll (+46)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index db302d7e526844..03a6e7a555c3f7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -23,6 +23,7 @@
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
@@ -2049,6 +2050,16 @@ Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
}
Value *OrOp0 = Or->getOperand(0), *OrOp1 = Or->getOperand(1);
+
+ // (icmp eq/ne (or disjoint x, C0), C1)
+ // -> (icmp eq/ne x, C0^C1)
+ if (Cmp.isEquality() && match(OrOp1, m_ImmConstant()) &&
+ cast<PossiblyDisjointInst>(Or)->isDisjoint()) {
+ Constant *NewC = ConstantExpr::getXor(
+ cast<Constant>(OrOp1), ConstantInt::get(OrOp1->getType(), C));
+ return new ICmpInst(Pred, OrOp0, NewC);
+ }
+
const APInt *MaskC;
if (match(OrOp1, m_APInt(MaskC)) && Cmp.isEquality()) {
if (*MaskC == C && (C + 1).isPowerOf2()) {
diff --git a/llvm/test/Transforms/InstCombine/icmp-or.ll b/llvm/test/Transforms/InstCombine/icmp-or.ll
index 922845c1e7e2d8..65d90104cfeeee 100644
--- a/llvm/test/Transforms/InstCombine/icmp-or.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-or.ll
@@ -951,3 +951,49 @@ define i1 @icmp_or_xor_with_sub_3_6(i64 %x1, i64 %y1, i64 %x2, i64 %y2, i64 %x3,
%cmp = icmp eq i64 %or1, 0
ret i1 %cmp
}
+
+
+define i1 @or_disjoint_with_constants(i8 %x) {
+; CHECK-LABEL: @or_disjoint_with_constants(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1:%.*]], 18
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 1
+ %cmp = icmp eq i8 %or, 19
+ ret i1 %cmp
+}
+
+
+define i1 @or_disjoint_with_constants2(i8 %x) {
+; CHECK-LABEL: @or_disjoint_with_constants2(
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1:%.*]], 66
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 5
+ %cmp = icmp ne i8 %or, 71
+ ret i1 %cmp
+}
+
+
+define i1 @or_disjoint_with_constants_fail_missing_const1(i8 %x, i8 %y) {
+; CHECK-LABEL: @or_disjoint_with_constants_fail_missing_const1(
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 19
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, %y
+ %cmp = icmp eq i8 %or, 19
+ ret i1 %cmp
+}
+
+define i1 @or_disjoint_with_constants_fail_missing_const2(i8 %x, i8 %y) {
+; CHECK-LABEL: @or_disjoint_with_constants_fail_missing_const2(
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], 19
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], [[Y:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 19
+ %cmp = icmp eq i8 %or, %y
+ ret i1 %cmp
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/87734
More information about the llvm-commits
mailing list