[llvm] [InstCombine] Loosen one-use restriction if common operand is constant (PR #79767)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 22:26:06 PST 2024


https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/79767

>From c34b5fb34cfb59d1f01e2b070303ab8b38976e2e Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sun, 28 Jan 2024 15:32:44 -0500
Subject: [PATCH 1/2] [InstCombine] pre-commit tests (NFC)

---
 llvm/test/Transforms/InstCombine/xor-and-or.ll | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/xor-and-or.ll b/llvm/test/Transforms/InstCombine/xor-and-or.ll
index feba47912b1da..c159dec430975 100644
--- a/llvm/test/Transforms/InstCombine/xor-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll
@@ -241,4 +241,17 @@ define i1 @xor_and_or_negative_oneuse(i1 %c, i1 %x, i1 %y) {
   ret i1 %r
 }
 
+define i32 @xor_and_or_constant(i32 %B, i32 %C, i32 %D) {
+; CHECK-LABEL: @xor_and_or_constant(
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[D:%.*]], 10
+; CHECK-NEXT:    ret i32 [[ADD]]
+;
+  %A = add i32 0, 10
+  %or1 = or i32 %A, %B
+  %or2 = or i32 %A, %C
+  %xor = xor i32 %or1, %or2
+  %add = add i32 %A, %D
+  ret i32 %add
+}
+
 declare void @use(i1)

>From e9f11db624ad2685a0c5951571803e2e5853d653 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sun, 28 Jan 2024 13:30:29 -0500
Subject: [PATCH 2/2] [InstCombine] Loosen one-use restriction if common
 operand is constant

Add a new version that checks if A is a constant instead of one-use.
---
 .../Transforms/InstCombine/InstCombineAndOrXor.cpp    | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 6a827e2f3a963..9436329e87dee 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4837,7 +4837,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
     return BinaryOperator::CreateNot(Builder.CreateAnd(Op0, B));
 
   // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
-  // TODO: Loosen one-use restriction if common operand is a constant.
   Value *D;
   if (match(Op0, m_OneUse(m_Or(m_Value(A), m_Value(B)))) &&
       match(Op1, m_OneUse(m_Or(m_Value(C), m_Value(D))))) {
@@ -4851,6 +4850,16 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
     }
   }
 
+  // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
+  // We do this if common operand is a constant.
+  if (match(Op0, m_c_Or(m_Value(A), m_Value(B))) &&
+      match(Op1, m_c_Or(m_Specific(A), m_Value(C)))) {
+    if (match(A, m_ImmConstant())) {
+      Value *NotA = Builder.CreateNot(A);
+      return BinaryOperator::CreateAnd(Builder.CreateXor(B, C), NotA);
+    }
+  }
+
   // (A & B) ^ (A | C) --> A ? ~B : C -- There are 4 commuted variants.
   if (I.getType()->isIntOrIntVectorTy(1) &&
       match(Op0, m_OneUse(m_LogicalAnd(m_Value(A), m_Value(B)))) &&



More information about the llvm-commits mailing list