[llvm] And sub combine (PR #119316)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 9 19:15:12 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: fengfeng (fengfeng09)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/119316.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp (+9) 
- (added) llvm/test/Transforms/InstCombine/X86/and-sub-combine.ll (+14) 


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index ea7942ef978110..51831bba9c423b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2280,6 +2280,15 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
   if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes()))))
     return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X);
 
+  const APInt *C1, *C2;
+  // if (C1 & C2) == C2 then (X & C1) - (X & C2) -> X & (C1 ^ C2)
+  if (match(Op0, m_And(m_Value(X), m_APInt(C1))) &&
+      match(Op1, m_And(m_Specific(X), m_APInt(C2)))) {
+    if (C2->eq(*C1 & *C2))
+      return BinaryOperator::CreateAnd(
+          X, ConstantInt::get(I.getType(), *C1 ^ *C2));
+  }
+
   // Reassociate sub/add sequences to create more add instructions and
   // reduce dependency chains:
   // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1)
diff --git a/llvm/test/Transforms/InstCombine/X86/and-sub-combine.ll b/llvm/test/Transforms/InstCombine/X86/and-sub-combine.ll
new file mode 100644
index 00000000000000..5120717bf1481a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/X86/and-sub-combine.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -mtriple=x86_64-unknown-unknown -S | FileCheck %s
+
+define i8 @and_sub(i8 %a) {
+; CHECK-LABEL: @and_sub(
+; CHECK-NEXT:    [[RET:%.*]] = and i8 [[A:%.*]], 12
+; CHECK-NEXT:    ret i8 [[RET]]
+;
+  %and1 = and i8 %a, 15
+  %and2 = and i8 %a, 3
+
+  %ret = sub i8 %and1, %and2
+  ret i8 %ret
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/119316


More information about the llvm-commits mailing list