[llvm] [InstCombine] Improve handling of `not` and free inversion. (PR #66787)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 12:14:41 PST 2023


================
@@ -1662,6 +1662,24 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
                                     m_c_UMin(m_Deferred(A), m_Deferred(B))))))
     return BinaryOperator::CreateWithCopiedFlags(Instruction::Add, A, B, &I);
 
+  // (~X) + (~Y) --> (-2 - Y) - X
+  {
+    // To ensure we can save instructions we need to ensure that we either
+    // consume both LHS/RHS (i.e they have a `not`).
+    bool ConsumesLHS, ConsumesRHS;
+    if (isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) &&
+        isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesLHS &&
+        ConsumesRHS) {
+      Value *NotLHS = getFreelyInverted(LHS, LHS->hasOneUse(), &Builder);
+      Value *NotRHS = getFreelyInverted(RHS, RHS->hasOneUse(), &Builder);
+      assert(NotLHS != nullptr && NotRHS != nullptr &&
+             "isFreeToInvert desynced with getFreelyInverted");
+      Value *RHSMinus2 =
+          Builder.CreateSub(ConstantInt::get(RHS->getType(), -2), NotRHS);
+      return BinaryOperator::CreateSub(RHSMinus2, NotLHS);
----------------
nikic wrote:

I believe InstCombine's canonical form for this is `-2 - (X + Y)` rather than `(-2 - X) - Y`.

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


More information about the llvm-commits mailing list