[llvm] [InstCombine] Explicitly set disjoint flag when converting xor to or. (PR #74229)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 5 11:04:41 PST 2023


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/74229

>From ff8e0c372bd56242db0806833ce8e93393e8b32f Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Sat, 2 Dec 2023 23:36:53 -0800
Subject: [PATCH 1/3] [InstCombine] Explicitly set disjoint flag when
 converting xor to or.

---
 llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 732a3a13daccc..4f00ce661215d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -315,6 +315,7 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     if (DemandedMask.isSubsetOf(RHSKnown.Zero | LHSKnown.Zero)) {
       Instruction *Or =
           BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1));
+      cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
       Or->takeName(I);
       return InsertNewInstWith(Or, I->getIterator());
     }

>From 0027fc3ff042462cc74847fbab66b77d0fbd19c8 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Sun, 3 Dec 2023 00:01:22 -0800
Subject: [PATCH 2/3] Update another xor->or transform

---
 llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 481fcdf181946..51098f79b92d0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4462,8 +4462,11 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   Value *M;
   if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(M)), m_Value()),
-                        m_c_And(m_Deferred(M), m_Value()))))
-    return BinaryOperator::CreateOr(Op0, Op1);
+                        m_c_And(m_Deferred(M), m_Value())))) {
+    auto *Or = BinaryOperator::CreateOr(Op0, Op1);
+    cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
+    return Or;
+  }
 
   if (Instruction *Xor = visitMaskedMerge(I, Builder))
     return Xor;

>From d0e87a738709f488d031107dfa3eb560f20b51b1 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Tue, 5 Dec 2023 11:04:12 -0800
Subject: [PATCH 3/3] fixup! Address review comments.

---
 llvm/include/llvm/IR/InstrTypes.h             | 31 +++++++++++++++++++
 .../InstCombine/InstCombineAddSub.cpp         |  7 ++---
 .../InstCombine/InstCombineAndOrXor.cpp       |  4 +--
 .../InstCombineSimplifyDemanded.cpp           |  3 +-
 4 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index ddae3e4f43f48..d708a13ad69b1 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -336,6 +336,14 @@ class BinaryOperator : public Instruction {
     return BO;
   }
 
+  static inline BinaryOperator *
+  CreateDisjoint(BinaryOps Opc, Value *V1, Value *V2, const Twine &Name = "");
+  static inline BinaryOperator *CreateDisjoint(BinaryOps Opc, Value *V1,
+                                               Value *V2, const Twine &Name,
+                                               BasicBlock *BB);
+  static inline BinaryOperator *CreateDisjoint(BinaryOps Opc, Value *V1,
+                                               Value *V2, const Twine &Name,
+                                               Instruction *I);
 #define DEFINE_HELPERS(OPC, NUWNSWEXACT)                                       \
   static BinaryOperator *Create##NUWNSWEXACT##OPC(Value *V1, Value *V2,        \
                                                   const Twine &Name = "") {    \
@@ -364,6 +372,8 @@ class BinaryOperator : public Instruction {
   DEFINE_HELPERS(AShr, Exact)  // CreateExactAShr
   DEFINE_HELPERS(LShr, Exact)  // CreateExactLShr
 
+  DEFINE_HELPERS(Or, Disjoint) // CreateDisjointOr
+
 #undef DEFINE_HELPERS
 
   /// Helper functions to construct and inspect unary operations (NEG and NOT)
@@ -438,6 +448,27 @@ class PossiblyDisjointInst : public BinaryOperator {
   }
 };
 
+BinaryOperator *BinaryOperator::CreateDisjoint(BinaryOps Opc, Value *V1,
+                                               Value *V2, const Twine &Name) {
+  BinaryOperator *BO = Create(Opc, V1, V2, Name);
+  cast<PossiblyDisjointInst>(BO)->setIsDisjoint(true);
+  return BO;
+}
+BinaryOperator *BinaryOperator::CreateDisjoint(BinaryOps Opc, Value *V1,
+                                               Value *V2, const Twine &Name,
+                                               BasicBlock *BB) {
+  BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+  cast<PossiblyDisjointInst>(BO)->setIsDisjoint(true);
+  return BO;
+}
+BinaryOperator *BinaryOperator::CreateDisjoint(BinaryOps Opc, Value *V1,
+                                               Value *V2, const Twine &Name,
+                                               Instruction *I) {
+  BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+  cast<PossiblyDisjointInst>(BO)->setIsDisjoint(true);
+  return BO;
+}
+
 //===----------------------------------------------------------------------===//
 //                               CastInst Class
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index c6d19c9cabc28..719a2678fc189 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1582,11 +1582,8 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
 
   // A+B --> A|B iff A and B have no bits set in common.
   WithCache<const Value *> LHSCache(LHS), RHSCache(RHS);
-  if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I))) {
-    auto *Or = BinaryOperator::CreateOr(LHS, RHS);
-    cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
-    return Or;
-  }
+  if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I)))
+    return BinaryOperator::CreateDisjointOr(LHS, RHS);
 
   if (Instruction *Ext = narrowMathIfNoOverflow(I))
     return Ext;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 51098f79b92d0..6544e61e2d7c5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4463,9 +4463,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
   Value *M;
   if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(M)), m_Value()),
                         m_c_And(m_Deferred(M), m_Value())))) {
-    auto *Or = BinaryOperator::CreateOr(Op0, Op1);
-    cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
-    return Or;
+    return BinaryOperator::CreateDisjointOr(Op0, Op1);
   }
 
   if (Instruction *Xor = visitMaskedMerge(I, Builder))
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 4f00ce661215d..046ce9d1207e8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -315,7 +315,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     if (DemandedMask.isSubsetOf(RHSKnown.Zero | LHSKnown.Zero)) {
       Instruction *Or =
           BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1));
-      cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
+      if (DemandedMask.isAllOnes())
+        cast<PossiblyDisjointInst>(Or)->setIsDisjoint(true);
       Or->takeName(I);
       return InsertNewInstWith(Or, I->getIterator());
     }



More information about the llvm-commits mailing list