[PATCH] D154139: [InstCombine] Transform `(icmp eq/ne (or x, C), x)` -> `(icmp eq/ne (and x, C), C)`
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 30 13:58:31 PDT 2023
goldstein.w.n updated this revision to Diff 536415.
goldstein.w.n added a comment.
Add check for undef
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D154139/new/
https://reviews.llvm.org/D154139
Files:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
Index: llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
+++ llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
@@ -5,8 +5,8 @@
define i1 @fold_or_eq(i8 %x) {
; CHECK-LABEL: define i1 @fold_or_eq
; CHECK-SAME: (i8 [[X:%.*]]) {
-; CHECK-NEXT: [[XO:%.*]] = or i8 [[X]], 123
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XO]], [[X]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], 123
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 123
; CHECK-NEXT: ret i1 [[R]]
;
%xo = or i8 %x, 123
@@ -18,8 +18,8 @@
; CHECK-LABEL: define <2 x i1> @fold_or_ne
; CHECK-SAME: (<2 x i8> [[XX:%.*]]) {
; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[XX]], [[XX]]
-; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], <i8 123, i8 12>
-; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], [[XO]]
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], <i8 123, i8 12>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], <i8 123, i8 12>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%x = mul <2 x i8> %xx, %xx
@@ -98,8 +98,8 @@
define <2 x i1> @fold_or_eq_with_poison(<2 x i8> %x) {
; CHECK-LABEL: define <2 x i1> @fold_or_eq_with_poison
; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], <i8 poison, i8 12>
-; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[XO]], [[X]]
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], <i8 poison, i8 12>
+; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 poison, i8 12>
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%xo = or <2 x i8> %x, <i8 poison, i8 12>
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4878,17 +4878,29 @@
// canoncalize:
// (icmp eq/ne (and X, C), X)
// -> (icmp eq/ne (and X, ~C), 0)
- {
+ // (icmp eq/ne (or X, C), X)
+ // -> (icmp eq/ne (and X, C), C)
+ auto SimplifyBitwiseAndOrBitwiseOr =
+ [this, Pred](Value *BitwiseOp, Value *Operand) -> Instruction * {
Constant *CMask;
- A = nullptr;
- if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_ImmConstant(CMask)))))
- A = Op1;
- else if (match(Op1, m_OneUse(m_And(m_Specific(Op0), m_ImmConstant(CMask)))))
- A = Op0;
- if (A)
- return new ICmpInst(Pred, Builder.CreateAnd(A, Builder.CreateNot(CMask)),
- Constant::getNullValue(A->getType()));
- }
+ if (!BitwiseOp->hasOneUse())
+ return nullptr;
+
+ if (match(BitwiseOp, m_And(m_Specific(Operand), m_ImmConstant(CMask))) &&
+ !CMask->containsUndefElement())
+ return new ICmpInst(Pred,
+ Builder.CreateAnd(Operand, Builder.CreateNot(CMask)),
+ Constant::getNullValue(Operand->getType()));
+ if (match(BitwiseOp, m_Or(m_Specific(Operand), m_ImmConstant(CMask))) &&
+ !CMask->containsUndefElement())
+ return new ICmpInst(Pred, Builder.CreateAnd(Operand, CMask), CMask);
+ return nullptr;
+ };
+
+ if (Instruction *R = SimplifyBitwiseAndOrBitwiseOr(Op0, Op1))
+ return R;
+ if (Instruction *R = SimplifyBitwiseAndOrBitwiseOr(Op1, Op0))
+ return R;
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) {
// A == (A^B) -> B == 0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154139.536415.patch
Type: text/x-patch
Size: 3465 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230630/10fbd3f3/attachment.bin>
More information about the llvm-commits
mailing list