[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