-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SelectionDAG] Add initial plumbing for the disjoint flag. #76751
Conversation
This copies the flag from IR to the SDNode in SelectionDAGBuilder, clear the flag in SimplifyDemandedBits, and adds it to canCreateUndefOrPoison. Uses of the flag will come in later patches.
@llvm/pr-subscribers-llvm-selectiondag Author: Craig Topper (topperc) ChangesThis copies the flag from IR to the SDNode in SelectionDAGBuilder, clear the flag in SimplifyDemandedBits, and adds it to canCreateUndefOrPoison. Uses of the flag will come in later patches. Full diff: https://github.com/llvm/llvm-project/pull/76751.diff 5 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 5c44538fe69974..7f957878343a65 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -381,6 +381,7 @@ struct SDNodeFlags {
bool NoUnsignedWrap : 1;
bool NoSignedWrap : 1;
bool Exact : 1;
+ bool Disjoint : 1;
bool NonNeg : 1;
bool NoNaNs : 1;
bool NoInfs : 1;
@@ -402,10 +403,11 @@ struct SDNodeFlags {
public:
/// Default constructor turns off all optimization flags.
SDNodeFlags()
- : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), NonNeg(false),
- NoNaNs(false), NoInfs(false), NoSignedZeros(false),
- AllowReciprocal(false), AllowContract(false), ApproximateFuncs(false),
- AllowReassociation(false), NoFPExcept(false), Unpredictable(false) {}
+ : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false),
+ Disjoint(false), NonNeg(false), NoNaNs(false), NoInfs(false),
+ NoSignedZeros(false), AllowReciprocal(false), AllowContract(false),
+ ApproximateFuncs(false), AllowReassociation(false), NoFPExcept(false),
+ Unpredictable(false) {}
/// Propagate the fast-math-flags from an IR FPMathOperator.
void copyFMF(const FPMathOperator &FPMO) {
@@ -422,6 +424,7 @@ struct SDNodeFlags {
void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
void setNoSignedWrap(bool b) { NoSignedWrap = b; }
void setExact(bool b) { Exact = b; }
+ void setDisjoint(bool b) { Disjoint = b; }
void setNonNeg(bool b) { NonNeg = b; }
void setNoNaNs(bool b) { NoNaNs = b; }
void setNoInfs(bool b) { NoInfs = b; }
@@ -437,6 +440,7 @@ struct SDNodeFlags {
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
bool hasNoSignedWrap() const { return NoSignedWrap; }
bool hasExact() const { return Exact; }
+ bool hasDisjoint() const { return Disjoint; }
bool hasNonNeg() const { return NonNeg; }
bool hasNoNaNs() const { return NoNaNs; }
bool hasNoInfs() const { return NoInfs; }
@@ -454,6 +458,7 @@ struct SDNodeFlags {
NoUnsignedWrap &= Flags.NoUnsignedWrap;
NoSignedWrap &= Flags.NoSignedWrap;
Exact &= Flags.Exact;
+ Disjoint &= Flags.Disjoint;
NonNeg &= Flags.NonNeg;
NoNaNs &= Flags.NoNaNs;
NoInfs &= Flags.NoInfs;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0e17bba2398ed2..75c10a74cdc44c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5022,7 +5022,6 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
case ISD::CONCAT_VECTORS:
case ISD::INSERT_SUBVECTOR:
case ISD::AND:
- case ISD::OR:
case ISD::XOR:
case ISD::ROTL:
case ISD::ROTR:
@@ -5062,6 +5061,10 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() ||
Op->getFlags().hasNoUnsignedWrap());
+ // Matches hasPoisonGeneratingFlags().
+ case ISD::OR:
+ return ConsiderFlags && Op->getFlags().hasDisjoint();
+
case ISD::INSERT_VECTOR_ELT:{
// Ensure that the element index is in bounds.
EVT VecVT = Op.getOperand(0).getValueType();
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 3c4b285cb06747..192f7bc8d2aa1b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3354,6 +3354,8 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
}
if (auto *ExactOp = dyn_cast<PossiblyExactOperator>(&I))
Flags.setExact(ExactOp->isExact());
+ if (auto *DisjointOp = dyn_cast<PossiblyDisjointInst>(&I))
+ Flags.setDisjoint(DisjointOp->isDisjoint());
if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
Flags.copyFMF(*FPOp);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 78cc60084068a5..4ae30000015e17 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -597,6 +597,9 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
if (getFlags().hasExact())
OS << " exact";
+ if (getFlags().hasDisjoint())
+ OS << " disjoint";
+
if (getFlags().hasNonNeg())
OS << " nneg";
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index c5977546828f63..4581bb19e97ec3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1468,14 +1468,24 @@ bool TargetLowering::SimplifyDemandedBits(
case ISD::OR: {
SDValue Op0 = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1);
-
+ SDNodeFlags Flags = Op.getNode()->getFlags();
if (SimplifyDemandedBits(Op1, DemandedBits, DemandedElts, Known, TLO,
- Depth + 1))
+ Depth + 1)) {
+ if (Flags.hasDisjoint()) {
+ Flags.setDisjoint(false);
+ Op->setFlags(Flags);
+ }
return true;
+ }
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
if (SimplifyDemandedBits(Op0, ~Known.One & DemandedBits, DemandedElts,
- Known2, TLO, Depth + 1))
+ Known2, TLO, Depth + 1)) {
+ if (Flags.hasDisjoint()) {
+ Flags.setDisjoint(false);
+ Op->setFlags(Flags);
+ }
return true;
+ }
assert(!Known2.hasConflict() && "Bits known to be one AND zero?");
// If all of the demanded bits are known zero on one side, return the other.
|
@@ -381,6 +381,7 @@ struct SDNodeFlags { | |||
bool NoUnsignedWrap : 1; | |||
bool NoSignedWrap : 1; | |||
bool Exact : 1; | |||
bool Disjoint : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was unioned with the wrap flags. I guess we don't have enough of these bits to matter yet
This copies the flag from IR to the SDNode in SelectionDAGBuilder, clear the flag in SimplifyDemandedBits, and adds it to canCreateUndefOrPoison.
Uses of the flag will come in later patches.