[llvm] [InstCombine] Fold bool (((A & B) ^ 1) & C) & A into ((B ^ 1) & A) & C (PR #78150)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 15 03:48:03 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: None (adamszilagyi)
<details>
<summary>Changes</summary>
Issue #<!-- -->75004
Proof: https://alive2.llvm.org/ce/z/fQ62US
---
Full diff: https://github.com/llvm/llvm-project/pull/78150.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+10)
- (modified) llvm/test/Transforms/InstCombine/and.ll (+16)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 0620752e321394..21b2a6f181fe7a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2539,6 +2539,16 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(C));
}
+ // (((A & B) ^ 1) & C) & A -> ((B ^ 1) & A) & C
+ if (match(&I, m_And(m_And(m_Xor(m_And(m_Value(A), m_Value(B)), m_One()),
+ m_Value(C)),
+ m_Value(A))) &&
+ A->getType()->isIntOrIntVectorTy(1) &&
+ B->getType()->isIntOrIntVectorTy(1) &&
+ C->getType()->isIntOrIntVectorTy(1))
+ return BinaryOperator::CreateAnd(
+ Builder.CreateAnd(Builder.CreateXor(B, 1), A), C);
+
// (A | B) & (~A ^ B) -> A & B
// (A | B) & (B ^ ~A) -> A & B
// (B | A) & (~A ^ B) -> A & B
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 2e37fee07cc47b..ee7d4ecf18f576 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -2411,6 +2411,22 @@ define i8 @negate_lowbitmask_use1(i8 %x, i8 %y) {
ret i8 %r
}
+define i32 @fold_and_and_xor1_and(i1 %k, i1 %c, i1 %c1) {
+; CHECK-LABEL: @fold_and_and_xor1_and(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT: [[NARROW:%.*]] = and i1 [[TMP2]], [[C1:%.*]]
+; CHECK-NEXT: [[COND:%.*]] = zext i1 [[NARROW]] to i32
+; CHECK-NEXT: ret i32 [[COND]]
+;
+ %and12 = and i1 %k, %c
+ %not.and12 = xor i1 %and12, true
+ %1 = and i1 %not.and12, %c1
+ %narrow = and i1 %k, %1
+ %cond = zext i1 %narrow to i32
+ ret i32 %cond
+}
+
; negative test
define i8 @negate_lowbitmask_use2(i8 %x, i8 %y) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/78150
More information about the llvm-commits
mailing list