[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