mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
Generalize the specialized flag-carrying SDNodes by moving flags into SDNode.
This removes BinaryWithFlagsSDNode, and flags are now all passed by value. Differential Revision: https://reviews.llvm.org/D32527 llvm-svn: 301803
This commit is contained in:
parent
0c2a55ce06
commit
7b62022bef
@ -774,7 +774,7 @@ public:
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDUse> Ops);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr);
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
|
||||
ArrayRef<SDValue> Ops);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
|
||||
@ -782,9 +782,10 @@ public:
|
||||
|
||||
// Specialize based on number of operands.
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N,
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
SDValue N2, const SDNodeFlags *Flags = nullptr);
|
||||
SDValue N2, const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
SDValue N2, SDValue N3);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
@ -1104,7 +1105,7 @@ public:
|
||||
|
||||
/// Get the specified node if it's already available, or else return NULL.
|
||||
SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
|
||||
/// Creates a SDDbgValue node.
|
||||
SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R,
|
||||
@ -1267,7 +1268,7 @@ public:
|
||||
|
||||
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
|
||||
/// Constant fold a setcc to true or false.
|
||||
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
|
||||
@ -1438,10 +1439,6 @@ private:
|
||||
|
||||
void allnodes_clear();
|
||||
|
||||
SDNode *GetBinarySDNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
|
||||
SDValue N1, SDValue N2,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
|
||||
/// Look up the node specified by ID in CSEMap. If it exists, return it. If
|
||||
/// not, return the insertion token that will make insertion faster. This
|
||||
/// overload is for nodes other than Constant or ConstantFP, use the other one
|
||||
|
@ -341,6 +341,11 @@ template<> struct simplify_type<SDUse> {
|
||||
/// the backend.
|
||||
struct SDNodeFlags {
|
||||
private:
|
||||
// This bit is used to determine if the flags are in a defined state.
|
||||
// Flag bits can only be masked out during intersection if the masking flags
|
||||
// are defined.
|
||||
bool AnyDefined : 1;
|
||||
|
||||
bool NoUnsignedWrap : 1;
|
||||
bool NoSignedWrap : 1;
|
||||
bool Exact : 1;
|
||||
@ -355,22 +360,57 @@ private:
|
||||
public:
|
||||
/// Default constructor turns off all optimization flags.
|
||||
SDNodeFlags()
|
||||
: NoUnsignedWrap(false), NoSignedWrap(false), Exact(false),
|
||||
UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
|
||||
: AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false),
|
||||
Exact(false), UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
|
||||
NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
|
||||
AllowContract(false) {}
|
||||
|
||||
/// Sets the state of the flags to the defined state.
|
||||
void setDefined() { AnyDefined = true; }
|
||||
/// Returns true if the flags are in a defined state.
|
||||
bool isDefined() const { return AnyDefined; }
|
||||
|
||||
// These are mutators for each flag.
|
||||
void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
|
||||
void setNoSignedWrap(bool b) { NoSignedWrap = b; }
|
||||
void setExact(bool b) { Exact = b; }
|
||||
void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; }
|
||||
void setNoNaNs(bool b) { NoNaNs = b; }
|
||||
void setNoInfs(bool b) { NoInfs = b; }
|
||||
void setNoSignedZeros(bool b) { NoSignedZeros = b; }
|
||||
void setAllowReciprocal(bool b) { AllowReciprocal = b; }
|
||||
void setVectorReduction(bool b) { VectorReduction = b; }
|
||||
void setAllowContract(bool b) { AllowContract = b; }
|
||||
void setNoUnsignedWrap(bool b) {
|
||||
setDefined();
|
||||
NoUnsignedWrap = b;
|
||||
}
|
||||
void setNoSignedWrap(bool b) {
|
||||
setDefined();
|
||||
NoSignedWrap = b;
|
||||
}
|
||||
void setExact(bool b) {
|
||||
setDefined();
|
||||
Exact = b;
|
||||
}
|
||||
void setUnsafeAlgebra(bool b) {
|
||||
setDefined();
|
||||
UnsafeAlgebra = b;
|
||||
}
|
||||
void setNoNaNs(bool b) {
|
||||
setDefined();
|
||||
NoNaNs = b;
|
||||
}
|
||||
void setNoInfs(bool b) {
|
||||
setDefined();
|
||||
NoInfs = b;
|
||||
}
|
||||
void setNoSignedZeros(bool b) {
|
||||
setDefined();
|
||||
NoSignedZeros = b;
|
||||
}
|
||||
void setAllowReciprocal(bool b) {
|
||||
setDefined();
|
||||
AllowReciprocal = b;
|
||||
}
|
||||
void setVectorReduction(bool b) {
|
||||
setDefined();
|
||||
VectorReduction = b;
|
||||
}
|
||||
void setAllowContract(bool b) {
|
||||
setDefined();
|
||||
AllowContract = b;
|
||||
}
|
||||
|
||||
// These are accessors for each flag.
|
||||
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
|
||||
@ -385,17 +425,20 @@ public:
|
||||
bool hasAllowContract() const { return AllowContract; }
|
||||
|
||||
/// Clear any flags in this flag set that aren't also set in Flags.
|
||||
void intersectWith(const SDNodeFlags *Flags) {
|
||||
NoUnsignedWrap &= Flags->NoUnsignedWrap;
|
||||
NoSignedWrap &= Flags->NoSignedWrap;
|
||||
Exact &= Flags->Exact;
|
||||
UnsafeAlgebra &= Flags->UnsafeAlgebra;
|
||||
NoNaNs &= Flags->NoNaNs;
|
||||
NoInfs &= Flags->NoInfs;
|
||||
NoSignedZeros &= Flags->NoSignedZeros;
|
||||
AllowReciprocal &= Flags->AllowReciprocal;
|
||||
VectorReduction &= Flags->VectorReduction;
|
||||
AllowContract &= Flags->AllowContract;
|
||||
/// If the given Flags are undefined then don't do anything.
|
||||
void intersectWith(const SDNodeFlags Flags) {
|
||||
if (!Flags.isDefined())
|
||||
return;
|
||||
NoUnsignedWrap &= Flags.NoUnsignedWrap;
|
||||
NoSignedWrap &= Flags.NoSignedWrap;
|
||||
Exact &= Flags.Exact;
|
||||
UnsafeAlgebra &= Flags.UnsafeAlgebra;
|
||||
NoNaNs &= Flags.NoNaNs;
|
||||
NoInfs &= Flags.NoInfs;
|
||||
NoSignedZeros &= Flags.NoSignedZeros;
|
||||
AllowReciprocal &= Flags.AllowReciprocal;
|
||||
VectorReduction &= Flags.VectorReduction;
|
||||
AllowContract &= Flags.AllowContract;
|
||||
}
|
||||
};
|
||||
|
||||
@ -527,6 +570,8 @@ private:
|
||||
/// Return a pointer to the specified value type.
|
||||
static const EVT *getValueTypeList(EVT VT);
|
||||
|
||||
SDNodeFlags Flags;
|
||||
|
||||
public:
|
||||
/// Unique and persistent id per SDNode in the DAG.
|
||||
/// Used for debug printing.
|
||||
@ -799,12 +844,12 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// This could be defined as a virtual function and implemented more simply
|
||||
/// and directly, but it is not to avoid creating a vtable for this class.
|
||||
const SDNodeFlags *getFlags() const;
|
||||
const SDNodeFlags getFlags() const { return Flags; }
|
||||
void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
|
||||
|
||||
/// Clear any flags in this node that aren't also set in Flags.
|
||||
void intersectFlagsWith(const SDNodeFlags *Flags);
|
||||
/// If Flags is not in a defined state then this has no effect.
|
||||
void intersectFlagsWith(const SDNodeFlags Flags);
|
||||
|
||||
/// Return the number of values defined/returned by this operator.
|
||||
unsigned getNumValues() const { return NumValues; }
|
||||
@ -1032,43 +1077,6 @@ inline void SDUse::setNode(SDNode *N) {
|
||||
if (N) N->addUse(*this);
|
||||
}
|
||||
|
||||
/// Returns true if the opcode is a binary operation with flags.
|
||||
static bool isBinOpWithFlags(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
case ISD::SRA:
|
||||
case ISD::SRL:
|
||||
case ISD::MUL:
|
||||
case ISD::ADD:
|
||||
case ISD::SUB:
|
||||
case ISD::SHL:
|
||||
case ISD::FADD:
|
||||
case ISD::FDIV:
|
||||
case ISD::FMUL:
|
||||
case ISD::FREM:
|
||||
case ISD::FSUB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// This class is an extension of BinarySDNode
|
||||
/// used from those opcodes that have associated extra flags.
|
||||
class BinaryWithFlagsSDNode : public SDNode {
|
||||
public:
|
||||
SDNodeFlags Flags;
|
||||
|
||||
BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
|
||||
SDVTList VTs, const SDNodeFlags &NodeFlags)
|
||||
: SDNode(Opc, Order, dl, VTs), Flags(NodeFlags) {}
|
||||
|
||||
static bool classof(const SDNode *N) {
|
||||
return isBinOpWithFlags(N->getOpcode());
|
||||
}
|
||||
};
|
||||
|
||||
/// This class is used to form a handle around another node that
|
||||
/// is persistent and is updated across invocations of replaceAllUsesWith on its
|
||||
/// operand. This node should be directly created by end-users and not added to
|
||||
|
@ -372,14 +372,14 @@ namespace {
|
||||
SDValue BuildSDIVPow2(SDNode *N);
|
||||
SDValue BuildUDIV(SDNode *N);
|
||||
SDValue BuildLogBase2(SDValue Op, const SDLoc &DL);
|
||||
SDValue BuildReciprocalEstimate(SDValue Op, SDNodeFlags *Flags);
|
||||
SDValue buildRsqrtEstimate(SDValue Op, SDNodeFlags *Flags);
|
||||
SDValue buildSqrtEstimate(SDValue Op, SDNodeFlags *Flags);
|
||||
SDValue buildSqrtEstimateImpl(SDValue Op, SDNodeFlags *Flags, bool Recip);
|
||||
SDValue BuildReciprocalEstimate(SDValue Op, SDNodeFlags Flags);
|
||||
SDValue buildRsqrtEstimate(SDValue Op, SDNodeFlags Flags);
|
||||
SDValue buildSqrtEstimate(SDValue Op, SDNodeFlags Flags);
|
||||
SDValue buildSqrtEstimateImpl(SDValue Op, SDNodeFlags Flags, bool Recip);
|
||||
SDValue buildSqrtNROneConst(SDValue Op, SDValue Est, unsigned Iterations,
|
||||
SDNodeFlags *Flags, bool Reciprocal);
|
||||
SDNodeFlags Flags, bool Reciprocal);
|
||||
SDValue buildSqrtNRTwoConst(SDValue Op, SDValue Est, unsigned Iterations,
|
||||
SDNodeFlags *Flags, bool Reciprocal);
|
||||
SDNodeFlags Flags, bool Reciprocal);
|
||||
SDValue MatchBSwapHWordLow(SDNode *N, SDValue N0, SDValue N1,
|
||||
bool DemandHighBits = true);
|
||||
SDValue MatchBSwapHWord(SDNode *N, SDValue N0, SDValue N1);
|
||||
@ -648,7 +648,7 @@ static char isNegatibleForFree(SDValue Op, bool LegalOperations,
|
||||
case ISD::FSUB:
|
||||
// We can't turn -(A-B) into B-A when we honor signed zeros.
|
||||
if (!Options->NoSignedZerosFPMath &&
|
||||
!Op.getNode()->getFlags()->hasNoSignedZeros())
|
||||
!Op.getNode()->getFlags().hasNoSignedZeros())
|
||||
return 0;
|
||||
|
||||
// fold (fneg (fsub A, B)) -> (fsub B, A)
|
||||
@ -686,7 +686,7 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
|
||||
|
||||
assert(Depth <= 6 && "GetNegatedExpression doesn't match isNegatibleForFree");
|
||||
|
||||
const SDNodeFlags *Flags = Op.getNode()->getFlags();
|
||||
const SDNodeFlags Flags = Op.getNode()->getFlags();
|
||||
|
||||
switch (Op.getOpcode()) {
|
||||
default: llvm_unreachable("Unknown code");
|
||||
@ -2185,13 +2185,13 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
|
||||
}
|
||||
|
||||
// 0 - X --> 0 if the sub is NUW.
|
||||
if (N->getFlags()->hasNoUnsignedWrap())
|
||||
if (N->getFlags().hasNoUnsignedWrap())
|
||||
return N0;
|
||||
|
||||
if (DAG.MaskedValueIsZero(N1, ~APInt::getSignMask(BitWidth))) {
|
||||
// N1 is either 0 or the minimum signed value. If the sub is NSW, then
|
||||
// N1 must be 0 because negating the minimum signed value is undefined.
|
||||
if (N->getFlags()->hasNoSignedWrap())
|
||||
if (N->getFlags().hasNoSignedWrap())
|
||||
return N0;
|
||||
|
||||
// 0 - X --> X if X is 0 or the minimum signed value.
|
||||
@ -2643,9 +2643,8 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
|
||||
// better results in that case. The target-specific lowering should learn how
|
||||
// to handle exact sdivs efficiently.
|
||||
if (N1C && !N1C->isNullValue() && !N1C->isOpaque() &&
|
||||
!cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact() &&
|
||||
(N1C->getAPIntValue().isPowerOf2() ||
|
||||
(-N1C->getAPIntValue()).isPowerOf2())) {
|
||||
!N->getFlags().hasExact() && (N1C->getAPIntValue().isPowerOf2() ||
|
||||
(-N1C->getAPIntValue()).isPowerOf2())) {
|
||||
// Target-specific implementation of sdiv x, pow2.
|
||||
if (SDValue Res = BuildSDIVPow2(N))
|
||||
return Res;
|
||||
@ -5376,7 +5375,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
|
||||
// fold (shl (sr[la] exact X, C1), C2) -> (shl X, (C2-C1)) if C1 <= C2
|
||||
// fold (shl (sr[la] exact X, C1), C2) -> (sr[la] X, (C2-C1)) if C1 > C2
|
||||
if (N1C && (N0.getOpcode() == ISD::SRL || N0.getOpcode() == ISD::SRA) &&
|
||||
cast<BinaryWithFlagsSDNode>(N0)->Flags.hasExact()) {
|
||||
N0->getFlags().hasExact()) {
|
||||
if (ConstantSDNode *N0C1 = isConstOrConstSplat(N0.getOperand(1))) {
|
||||
uint64_t C1 = N0C1->getZExtValue();
|
||||
uint64_t C2 = N1C->getZExtValue();
|
||||
@ -7906,7 +7905,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
|
||||
SDValue NewPtr = DAG.getNode(ISD::ADD, DL,
|
||||
PtrType, LN0->getBasePtr(),
|
||||
DAG.getConstant(PtrOff, DL, PtrType),
|
||||
&Flags);
|
||||
Flags);
|
||||
AddToWorklist(NewPtr.getNode());
|
||||
|
||||
SDValue Load;
|
||||
@ -8809,7 +8808,7 @@ ConstantFoldBITCASTofBUILD_VECTOR(SDNode *BV, EVT DstEltVT) {
|
||||
}
|
||||
|
||||
static bool isContractable(SDNode *N) {
|
||||
SDNodeFlags F = cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
SDNodeFlags F = N->getFlags();
|
||||
return F.hasAllowContract() || F.hasUnsafeAlgebra();
|
||||
}
|
||||
|
||||
@ -9395,7 +9394,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
SDLoc DL(N);
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
const SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
|
||||
// fold vector ops
|
||||
if (VT.isVector())
|
||||
@ -9426,7 +9425,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
||||
GetNegatedExpression(N0, DAG, LegalOperations), Flags);
|
||||
|
||||
// FIXME: Auto-upgrade the target/function-level option.
|
||||
if (Options.NoSignedZerosFPMath || N->getFlags()->hasNoSignedZeros()) {
|
||||
if (Options.NoSignedZerosFPMath || N->getFlags().hasNoSignedZeros()) {
|
||||
// fold (fadd A, 0) -> A
|
||||
if (ConstantFPSDNode *N1C = isConstOrConstSplatFP(N1))
|
||||
if (N1C->isZero())
|
||||
@ -9549,7 +9548,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
SDLoc DL(N);
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
const SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
|
||||
// fold vector ops
|
||||
if (VT.isVector())
|
||||
@ -9569,7 +9568,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
||||
GetNegatedExpression(N1, DAG, LegalOperations), Flags);
|
||||
|
||||
// FIXME: Auto-upgrade the target/function-level option.
|
||||
if (Options.NoSignedZerosFPMath || N->getFlags()->hasNoSignedZeros()) {
|
||||
if (Options.NoSignedZerosFPMath || N->getFlags().hasNoSignedZeros()) {
|
||||
// (fsub 0, B) -> -B
|
||||
if (N0CFP && N0CFP->isZero()) {
|
||||
if (isNegatibleForFree(N1, LegalOperations, TLI, &Options))
|
||||
@ -9620,7 +9619,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
SDLoc DL(N);
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
const SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
|
||||
// fold vector ops
|
||||
if (VT.isVector()) {
|
||||
@ -9764,7 +9763,7 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
|
||||
isConstantFPBuildVectorOrConstantFP(N2.getOperand(1))) {
|
||||
return DAG.getNode(ISD::FMUL, DL, VT, N0,
|
||||
DAG.getNode(ISD::FADD, DL, VT, N1, N2.getOperand(1),
|
||||
&Flags), &Flags);
|
||||
Flags), Flags);
|
||||
}
|
||||
|
||||
// (fma (fmul x, c1), c2, y) -> (fma x, c1*c2, y)
|
||||
@ -9774,7 +9773,7 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
|
||||
return DAG.getNode(ISD::FMA, DL, VT,
|
||||
N0.getOperand(0),
|
||||
DAG.getNode(ISD::FMUL, DL, VT, N1, N0.getOperand(1),
|
||||
&Flags),
|
||||
Flags),
|
||||
N2);
|
||||
}
|
||||
}
|
||||
@ -9800,16 +9799,16 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
|
||||
if (N1CFP && N0 == N2) {
|
||||
return DAG.getNode(ISD::FMUL, DL, VT, N0,
|
||||
DAG.getNode(ISD::FADD, DL, VT, N1,
|
||||
DAG.getConstantFP(1.0, DL, VT), &Flags),
|
||||
&Flags);
|
||||
DAG.getConstantFP(1.0, DL, VT), Flags),
|
||||
Flags);
|
||||
}
|
||||
|
||||
// (fma x, c, (fneg x)) -> (fmul x, (c-1))
|
||||
if (N1CFP && N2.getOpcode() == ISD::FNEG && N2.getOperand(0) == N0) {
|
||||
return DAG.getNode(ISD::FMUL, DL, VT, N0,
|
||||
DAG.getNode(ISD::FADD, DL, VT, N1,
|
||||
DAG.getConstantFP(-1.0, DL, VT), &Flags),
|
||||
&Flags);
|
||||
DAG.getConstantFP(-1.0, DL, VT), Flags),
|
||||
Flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9825,8 +9824,8 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
|
||||
// is the critical path is increased from "one FDIV" to "one FDIV + one FMUL".
|
||||
SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
|
||||
bool UnsafeMath = DAG.getTarget().Options.UnsafeFPMath;
|
||||
const SDNodeFlags *Flags = N->getFlags();
|
||||
if (!UnsafeMath && !Flags->hasAllowReciprocal())
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
if (!UnsafeMath && !Flags.hasAllowReciprocal())
|
||||
return SDValue();
|
||||
|
||||
// Skip if current node is a reciprocal.
|
||||
@ -9849,7 +9848,7 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
|
||||
if (U->getOpcode() == ISD::FDIV && U->getOperand(1) == N1) {
|
||||
// This division is eligible for optimization only if global unsafe math
|
||||
// is enabled or if this division allows reciprocal formation.
|
||||
if (UnsafeMath || U->getFlags()->hasAllowReciprocal())
|
||||
if (UnsafeMath || U->getFlags().hasAllowReciprocal())
|
||||
Users.insert(U);
|
||||
}
|
||||
}
|
||||
@ -9888,7 +9887,7 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
SDLoc DL(N);
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
SDNodeFlags Flags = N->getFlags();
|
||||
|
||||
// fold vector ops
|
||||
if (VT.isVector())
|
||||
@ -10002,8 +10001,7 @@ SDValue DAGCombiner::visitFREM(SDNode *N) {
|
||||
|
||||
// fold (frem c1, c2) -> fmod(c1,c2)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1,
|
||||
&cast<BinaryWithFlagsSDNode>(N)->Flags);
|
||||
return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1, N->getFlags());
|
||||
|
||||
if (SDValue NewSel = foldBinOpIntoSelect(N))
|
||||
return NewSel;
|
||||
@ -10023,7 +10021,7 @@ SDValue DAGCombiner::visitFSQRT(SDNode *N) {
|
||||
// For now, create a Flags object for use with all unsafe math transforms.
|
||||
SDNodeFlags Flags;
|
||||
Flags.setUnsafeAlgebra(true);
|
||||
return buildSqrtEstimate(N0, &Flags);
|
||||
return buildSqrtEstimate(N0, Flags);
|
||||
}
|
||||
|
||||
/// copysign(x, fp_extend(y)) -> copysign(x, y)
|
||||
@ -10455,10 +10453,10 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) {
|
||||
if (Level >= AfterLegalizeDAG &&
|
||||
(TLI.isFPImmLegal(CVal, VT) ||
|
||||
TLI.isOperationLegal(ISD::ConstantFP, VT)))
|
||||
return DAG.getNode(ISD::FMUL, SDLoc(N), VT, N0.getOperand(0),
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT,
|
||||
N0.getOperand(1)),
|
||||
&cast<BinaryWithFlagsSDNode>(N0)->Flags);
|
||||
return DAG.getNode(
|
||||
ISD::FMUL, SDLoc(N), VT, N0.getOperand(0),
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT, N0.getOperand(1)),
|
||||
N0->getFlags());
|
||||
}
|
||||
}
|
||||
|
||||
@ -15946,7 +15944,7 @@ SDValue DAGCombiner::BuildLogBase2(SDValue V, const SDLoc &DL) {
|
||||
/// =>
|
||||
/// X_{i+1} = X_i (2 - A X_i) = X_i + X_i (1 - A X_i) [this second form
|
||||
/// does not require additional intermediate precision]
|
||||
SDValue DAGCombiner::BuildReciprocalEstimate(SDValue Op, SDNodeFlags *Flags) {
|
||||
SDValue DAGCombiner::BuildReciprocalEstimate(SDValue Op, SDNodeFlags Flags) {
|
||||
if (Level >= AfterLegalizeDAG)
|
||||
return SDValue();
|
||||
|
||||
@ -16001,7 +15999,7 @@ SDValue DAGCombiner::BuildReciprocalEstimate(SDValue Op, SDNodeFlags *Flags) {
|
||||
/// As a result, we precompute A/2 prior to the iteration loop.
|
||||
SDValue DAGCombiner::buildSqrtNROneConst(SDValue Arg, SDValue Est,
|
||||
unsigned Iterations,
|
||||
SDNodeFlags *Flags, bool Reciprocal) {
|
||||
SDNodeFlags Flags, bool Reciprocal) {
|
||||
EVT VT = Arg.getValueType();
|
||||
SDLoc DL(Arg);
|
||||
SDValue ThreeHalves = DAG.getConstantFP(1.5, DL, VT);
|
||||
@ -16045,7 +16043,7 @@ SDValue DAGCombiner::buildSqrtNROneConst(SDValue Arg, SDValue Est,
|
||||
/// X_{i+1} = (-0.5 * X_i) * (A * X_i * X_i + (-3.0))
|
||||
SDValue DAGCombiner::buildSqrtNRTwoConst(SDValue Arg, SDValue Est,
|
||||
unsigned Iterations,
|
||||
SDNodeFlags *Flags, bool Reciprocal) {
|
||||
SDNodeFlags Flags, bool Reciprocal) {
|
||||
EVT VT = Arg.getValueType();
|
||||
SDLoc DL(Arg);
|
||||
SDValue MinusThree = DAG.getConstantFP(-3.0, DL, VT);
|
||||
@ -16090,7 +16088,7 @@ SDValue DAGCombiner::buildSqrtNRTwoConst(SDValue Arg, SDValue Est,
|
||||
/// Build code to calculate either rsqrt(Op) or sqrt(Op). In the latter case
|
||||
/// Op*rsqrt(Op) is actually computed, so additional postprocessing is needed if
|
||||
/// Op can be zero.
|
||||
SDValue DAGCombiner::buildSqrtEstimateImpl(SDValue Op, SDNodeFlags *Flags,
|
||||
SDValue DAGCombiner::buildSqrtEstimateImpl(SDValue Op, SDNodeFlags Flags,
|
||||
bool Reciprocal) {
|
||||
if (Level >= AfterLegalizeDAG)
|
||||
return SDValue();
|
||||
@ -16143,11 +16141,11 @@ SDValue DAGCombiner::buildSqrtEstimateImpl(SDValue Op, SDNodeFlags *Flags,
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue DAGCombiner::buildRsqrtEstimate(SDValue Op, SDNodeFlags *Flags) {
|
||||
SDValue DAGCombiner::buildRsqrtEstimate(SDValue Op, SDNodeFlags Flags) {
|
||||
return buildSqrtEstimateImpl(Op, Flags, true);
|
||||
}
|
||||
|
||||
SDValue DAGCombiner::buildSqrtEstimate(SDValue Op, SDNodeFlags *Flags) {
|
||||
SDValue DAGCombiner::buildSqrtEstimate(SDValue Op, SDNodeFlags Flags) {
|
||||
return buildSqrtEstimateImpl(Op, Flags, false);
|
||||
}
|
||||
|
||||
|
@ -3253,7 +3253,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
EVT VT = Node->getValueType(0);
|
||||
if (TLI.isOperationLegalOrCustom(ISD::FADD, VT) &&
|
||||
TLI.isOperationLegalOrCustom(ISD::FNEG, VT)) {
|
||||
const SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(Node)->Flags;
|
||||
const SDNodeFlags Flags = Node->getFlags();
|
||||
Tmp1 = DAG.getNode(ISD::FNEG, dl, VT, Node->getOperand(1));
|
||||
Tmp1 = DAG.getNode(ISD::FADD, dl, VT, Node->getOperand(0), Tmp1, Flags);
|
||||
Results.push_back(Tmp1);
|
||||
|
@ -730,7 +730,7 @@ void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo,
|
||||
GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
|
||||
SDLoc dl(N);
|
||||
|
||||
const SDNodeFlags *Flags = N->getFlags();
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
unsigned Opcode = N->getOpcode();
|
||||
Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Flags);
|
||||
Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Flags);
|
||||
@ -2219,7 +2219,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode *N) {
|
||||
EVT WidenEltVT = WidenVT.getVectorElementType();
|
||||
EVT VT = WidenVT;
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
const SDNodeFlags *Flags = N->getFlags();
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
while (!TLI.isTypeLegal(VT) && NumElts != 1) {
|
||||
NumElts = NumElts / 2;
|
||||
VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
|
||||
@ -2367,7 +2367,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
|
||||
|
||||
unsigned Opcode = N->getOpcode();
|
||||
unsigned InVTNumElts = InVT.getVectorNumElements();
|
||||
const SDNodeFlags *Flags = N->getFlags();
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
|
||||
InOp = GetWidenedVector(N->getOperand(0));
|
||||
InVT = InOp.getValueType();
|
||||
|
@ -811,8 +811,7 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDValue Op,
|
||||
AddNodeIDCustom(ID, N);
|
||||
SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
|
||||
if (Node)
|
||||
if (const SDNodeFlags *Flags = N->getFlags())
|
||||
Node->intersectFlagsWith(Flags);
|
||||
Node->intersectFlagsWith(N->getFlags());
|
||||
return Node;
|
||||
}
|
||||
|
||||
@ -832,8 +831,7 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
|
||||
AddNodeIDCustom(ID, N);
|
||||
SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
|
||||
if (Node)
|
||||
if (const SDNodeFlags *Flags = N->getFlags())
|
||||
Node->intersectFlagsWith(Flags);
|
||||
Node->intersectFlagsWith(N->getFlags());
|
||||
return Node;
|
||||
}
|
||||
|
||||
@ -852,8 +850,7 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops,
|
||||
AddNodeIDCustom(ID, N);
|
||||
SDNode *Node = FindNodeOrInsertPos(ID, SDLoc(N), InsertPos);
|
||||
if (Node)
|
||||
if (const SDNodeFlags *Flags = N->getFlags())
|
||||
Node->intersectFlagsWith(Flags);
|
||||
Node->intersectFlagsWith(N->getFlags());
|
||||
return Node;
|
||||
}
|
||||
|
||||
@ -901,29 +898,6 @@ void SelectionDAG::allnodes_clear() {
|
||||
#endif
|
||||
}
|
||||
|
||||
SDNode *SelectionDAG::GetBinarySDNode(unsigned Opcode, const SDLoc &DL,
|
||||
SDVTList VTs, SDValue N1, SDValue N2,
|
||||
const SDNodeFlags *Flags) {
|
||||
SDValue Ops[] = {N1, N2};
|
||||
|
||||
if (isBinOpWithFlags(Opcode)) {
|
||||
// If no flags were passed in, use a default flags object.
|
||||
SDNodeFlags F;
|
||||
if (Flags == nullptr)
|
||||
Flags = &F;
|
||||
|
||||
auto *FN = newSDNode<BinaryWithFlagsSDNode>(Opcode, DL.getIROrder(),
|
||||
DL.getDebugLoc(), VTs, *Flags);
|
||||
createOperands(FN, Ops);
|
||||
|
||||
return FN;
|
||||
}
|
||||
|
||||
auto *N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
|
||||
createOperands(N, Ops);
|
||||
return N;
|
||||
}
|
||||
|
||||
SDNode *SelectionDAG::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
|
||||
void *&InsertPos) {
|
||||
SDNode *N = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
|
||||
@ -3245,8 +3219,8 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op) const {
|
||||
if (getTarget().Options.NoNaNsFPMath)
|
||||
return true;
|
||||
|
||||
if (const BinaryWithFlagsSDNode *BF = dyn_cast<BinaryWithFlagsSDNode>(Op))
|
||||
return BF->Flags.hasNoNaNs();
|
||||
if (Op->getFlags().hasNoNaNs())
|
||||
return true;
|
||||
|
||||
// If the value is a constant, we can obviously see if it is a NaN or not.
|
||||
if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op))
|
||||
@ -3362,7 +3336,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) {
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
SDValue Operand) {
|
||||
SDValue Operand, const SDNodeFlags Flags) {
|
||||
// Constant fold unary operations with an integer constant operand. Even
|
||||
// opaque constant will be folded, because the folding of unary operations
|
||||
// doesn't create new constants with different values. Nevertheless, the
|
||||
@ -3688,8 +3662,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
if (getTarget().Options.UnsafeFPMath && OpOpcode == ISD::FSUB)
|
||||
// FIXME: FNEG has no fast-math-flags to propagate; use the FSUB's flags?
|
||||
return getNode(ISD::FSUB, DL, VT, Operand.getNode()->getOperand(1),
|
||||
Operand.getNode()->getOperand(0),
|
||||
&cast<BinaryWithFlagsSDNode>(Operand.getNode())->Flags);
|
||||
Operand.getNode()->getOperand(0),
|
||||
Operand.getNode()->getFlags());
|
||||
if (OpOpcode == ISD::FNEG) // --X -> X
|
||||
return Operand.getNode()->getOperand(0);
|
||||
break;
|
||||
@ -3706,10 +3680,13 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, Opcode, VTs, Ops);
|
||||
void *IP = nullptr;
|
||||
if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP))
|
||||
if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
|
||||
E->intersectFlagsWith(Flags);
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
|
||||
N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
|
||||
N->setFlags(Flags);
|
||||
createOperands(N, Ops);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
} else {
|
||||
@ -3888,7 +3865,7 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
|
||||
SDValue SelectionDAG::FoldConstantVectorArithmetic(unsigned Opcode,
|
||||
const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags) {
|
||||
const SDNodeFlags Flags) {
|
||||
// If the opcode is a target-specific ISD node, there's nothing we can
|
||||
// do here and the operand rules may not line up with the below, so
|
||||
// bail early.
|
||||
@ -3980,8 +3957,7 @@ SDValue SelectionDAG::FoldConstantVectorArithmetic(unsigned Opcode,
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
SDValue N1, SDValue N2,
|
||||
const SDNodeFlags *Flags) {
|
||||
SDValue N1, SDValue N2, const SDNodeFlags Flags) {
|
||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
|
||||
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
|
||||
@ -4448,21 +4424,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
// Memoize this node if possible.
|
||||
SDNode *N;
|
||||
SDVTList VTs = getVTList(VT);
|
||||
SDValue Ops[] = {N1, N2};
|
||||
if (VT != MVT::Glue) {
|
||||
SDValue Ops[] = {N1, N2};
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, Opcode, VTs, Ops);
|
||||
void *IP = nullptr;
|
||||
if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) {
|
||||
if (Flags)
|
||||
E->intersectFlagsWith(Flags);
|
||||
E->intersectFlagsWith(Flags);
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
|
||||
N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags);
|
||||
N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
|
||||
N->setFlags(Flags);
|
||||
createOperands(N, Ops);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
} else {
|
||||
N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, Flags);
|
||||
N = newSDNode<SDNode>(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs);
|
||||
createOperands(N, Ops);
|
||||
}
|
||||
|
||||
InsertNode(N);
|
||||
@ -5984,7 +5962,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags *Flags) {
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags Flags) {
|
||||
unsigned NumOps = Ops.size();
|
||||
switch (NumOps) {
|
||||
case 0: return getNode(Opcode, DL, VT);
|
||||
@ -6646,14 +6624,13 @@ SDValue SelectionDAG::getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT,
|
||||
/// else return NULL.
|
||||
SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
|
||||
ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags) {
|
||||
const SDNodeFlags Flags) {
|
||||
if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, Opcode, VTList, Ops);
|
||||
void *IP = nullptr;
|
||||
if (SDNode *E = FindNodeOrInsertPos(ID, SDLoc(), IP)) {
|
||||
if (Flags)
|
||||
E->intersectFlagsWith(Flags);
|
||||
E->intersectFlagsWith(Flags);
|
||||
return E;
|
||||
}
|
||||
}
|
||||
@ -7397,15 +7374,8 @@ bool SDNode::hasPredecessor(const SDNode *N) const {
|
||||
return hasPredecessorHelper(N, Visited, Worklist);
|
||||
}
|
||||
|
||||
const SDNodeFlags *SDNode::getFlags() const {
|
||||
if (auto *FlagsNode = dyn_cast<BinaryWithFlagsSDNode>(this))
|
||||
return &FlagsNode->Flags;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SDNode::intersectFlagsWith(const SDNodeFlags *Flags) {
|
||||
if (auto *FlagsNode = dyn_cast<BinaryWithFlagsSDNode>(this))
|
||||
FlagsNode->Flags.intersectWith(Flags);
|
||||
void SDNode::intersectFlagsWith(const SDNodeFlags Flags) {
|
||||
this->Flags.intersectWith(Flags);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) {
|
||||
|
@ -1335,7 +1335,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
|
||||
RetPtr.getValueType(), RetPtr,
|
||||
DAG.getIntPtrConstant(Offsets[i],
|
||||
getCurSDLoc()),
|
||||
&Flags);
|
||||
Flags);
|
||||
Chains[i] = DAG.getStore(Chain, getCurSDLoc(),
|
||||
SDValue(RetOp.getNode(), RetOp.getResNo() + i),
|
||||
// FIXME: better loc info would be nice.
|
||||
@ -2575,7 +2575,7 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned OpCode) {
|
||||
Flags.setUnsafeAlgebra(FMF.unsafeAlgebra());
|
||||
|
||||
SDValue BinNodeValue = DAG.getNode(OpCode, getCurSDLoc(), Op1.getValueType(),
|
||||
Op1, Op2, &Flags);
|
||||
Op1, Op2, Flags);
|
||||
setValue(&I, BinNodeValue);
|
||||
}
|
||||
|
||||
@ -2628,7 +2628,7 @@ void SelectionDAGBuilder::visitShift(const User &I, unsigned Opcode) {
|
||||
Flags.setNoSignedWrap(nsw);
|
||||
Flags.setNoUnsignedWrap(nuw);
|
||||
SDValue Res = DAG.getNode(Opcode, getCurSDLoc(), Op1.getValueType(), Op1, Op2,
|
||||
&Flags);
|
||||
Flags);
|
||||
setValue(&I, Res);
|
||||
}
|
||||
|
||||
@ -2640,7 +2640,7 @@ void SelectionDAGBuilder::visitSDiv(const User &I) {
|
||||
Flags.setExact(isa<PossiblyExactOperator>(&I) &&
|
||||
cast<PossiblyExactOperator>(&I)->isExact());
|
||||
setValue(&I, DAG.getNode(ISD::SDIV, getCurSDLoc(), Op1.getValueType(), Op1,
|
||||
Op2, &Flags));
|
||||
Op2, Flags));
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitICmp(const User &I) {
|
||||
@ -3252,7 +3252,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
Flags.setNoUnsignedWrap(true);
|
||||
|
||||
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N,
|
||||
DAG.getConstant(Offset, dl, N.getValueType()), &Flags);
|
||||
DAG.getConstant(Offset, dl, N.getValueType()), Flags);
|
||||
}
|
||||
} else {
|
||||
MVT PtrTy =
|
||||
@ -3282,7 +3282,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
|
||||
if (Offs.isNonNegative() && cast<GEPOperator>(I).isInBounds())
|
||||
Flags.setNoUnsignedWrap(true);
|
||||
|
||||
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal, &Flags);
|
||||
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal, Flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3360,7 +3360,7 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) {
|
||||
Flags.setNoUnsignedWrap(true);
|
||||
AllocSize = DAG.getNode(ISD::ADD, dl,
|
||||
AllocSize.getValueType(), AllocSize,
|
||||
DAG.getIntPtrConstant(StackAlign - 1, dl), &Flags);
|
||||
DAG.getIntPtrConstant(StackAlign - 1, dl), Flags);
|
||||
|
||||
// Mask out the low bits for alignment purposes.
|
||||
AllocSize = DAG.getNode(ISD::AND, dl,
|
||||
@ -3464,7 +3464,7 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
|
||||
SDValue A = DAG.getNode(ISD::ADD, dl,
|
||||
PtrVT, Ptr,
|
||||
DAG.getConstant(Offsets[i], dl, PtrVT),
|
||||
&Flags);
|
||||
Flags);
|
||||
auto MMOFlags = MachineMemOperand::MONone;
|
||||
if (isVolatile)
|
||||
MMOFlags |= MachineMemOperand::MOVolatile;
|
||||
@ -3619,7 +3619,7 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) {
|
||||
ChainI = 0;
|
||||
}
|
||||
SDValue Add = DAG.getNode(ISD::ADD, dl, PtrVT, Ptr,
|
||||
DAG.getConstant(Offsets[i], dl, PtrVT), &Flags);
|
||||
DAG.getConstant(Offsets[i], dl, PtrVT), Flags);
|
||||
SDValue St = DAG.getStore(
|
||||
Root, dl, SDValue(Src.getNode(), Src.getResNo() + i), Add,
|
||||
MachinePointerInfo(PtrV, Offsets[i]), Alignment, MMOFlags, AAInfo);
|
||||
@ -7883,7 +7883,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
for (unsigned i = 0; i < NumValues; ++i) {
|
||||
SDValue Add = CLI.DAG.getNode(ISD::ADD, CLI.DL, PtrVT, DemoteStackSlot,
|
||||
CLI.DAG.getConstant(Offsets[i], CLI.DL,
|
||||
PtrVT), &Flags);
|
||||
PtrVT), Flags);
|
||||
SDValue L = CLI.DAG.getLoad(
|
||||
RetTys[i], CLI.DL, CLI.Chain, Add,
|
||||
MachinePointerInfo::getFixedStack(CLI.DAG.getMachineFunction(),
|
||||
|
@ -886,7 +886,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
|
||||
// If the shift is exact, then it does demand the low bits (and knows that
|
||||
// they are zero).
|
||||
if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
|
||||
if (Op->getFlags().hasExact())
|
||||
InDemandedMask.setLowBits(ShAmt);
|
||||
|
||||
// If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
|
||||
@ -942,7 +942,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
|
||||
// If the shift is exact, then it does demand the low bits (and knows that
|
||||
// they are zero).
|
||||
if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
|
||||
if (Op->getFlags().hasExact())
|
||||
InDemandedMask.setLowBits(ShAmt);
|
||||
|
||||
// If any of the demanded bits are produced by the sign extension, we also
|
||||
@ -962,10 +962,10 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
if (Known.Zero[BitWidth - ShAmt - 1] ||
|
||||
NewMask.countLeadingZeros() >= ShAmt) {
|
||||
SDNodeFlags Flags;
|
||||
Flags.setExact(cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact());
|
||||
Flags.setExact(Op->getFlags().hasExact());
|
||||
return TLO.CombineTo(Op,
|
||||
TLO.DAG.getNode(ISD::SRL, dl, VT, Op.getOperand(0),
|
||||
Op.getOperand(1), &Flags));
|
||||
Op.getOperand(1), Flags));
|
||||
}
|
||||
|
||||
int Log2 = NewMask.exactLogBase2();
|
||||
@ -1259,16 +1259,15 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
SimplifyDemandedBits(Op.getOperand(1), LoMask, Known2, TLO, Depth+1) ||
|
||||
// See if the operation should be performed at a smaller bit width.
|
||||
ShrinkDemandedOp(Op, BitWidth, NewMask, TLO)) {
|
||||
const SDNodeFlags *Flags = Op.getNode()->getFlags();
|
||||
if (Flags->hasNoSignedWrap() || Flags->hasNoUnsignedWrap()) {
|
||||
SDNodeFlags Flags = Op.getNode()->getFlags();
|
||||
if (Flags.hasNoSignedWrap() || Flags.hasNoUnsignedWrap()) {
|
||||
// Disable the nsw and nuw flags. We can no longer guarantee that we
|
||||
// won't wrap after simplification.
|
||||
SDNodeFlags NewFlags = *Flags;
|
||||
NewFlags.setNoSignedWrap(false);
|
||||
NewFlags.setNoUnsignedWrap(false);
|
||||
Flags.setNoSignedWrap(false);
|
||||
Flags.setNoUnsignedWrap(false);
|
||||
SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, Op.getValueType(),
|
||||
Op.getOperand(0), Op.getOperand(1),
|
||||
&NewFlags);
|
||||
Flags);
|
||||
return TLO.CombineTo(Op, NewOp);
|
||||
}
|
||||
return true;
|
||||
@ -2953,7 +2952,7 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDValue Op1, APInt d,
|
||||
DAG.getDataLayout()));
|
||||
SDNodeFlags Flags;
|
||||
Flags.setExact(true);
|
||||
Op1 = DAG.getNode(ISD::SRA, dl, Op1.getValueType(), Op1, Amt, &Flags);
|
||||
Op1 = DAG.getNode(ISD::SRA, dl, Op1.getValueType(), Op1, Amt, Flags);
|
||||
Created.push_back(Op1.getNode());
|
||||
d.ashrInPlace(ShAmt);
|
||||
}
|
||||
@ -2997,7 +2996,7 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, const APInt &Divisor,
|
||||
return SDValue();
|
||||
|
||||
// If the sdiv has an 'exact' bit we can use a simpler lowering.
|
||||
if (cast<BinaryWithFlagsSDNode>(N)->Flags.hasExact())
|
||||
if (N->getFlags().hasExact())
|
||||
return BuildExactSDIV(*this, N->getOperand(0), Divisor, dl, DAG, *Created);
|
||||
|
||||
APInt::ms magics = Divisor.magic();
|
||||
|
@ -4847,9 +4847,9 @@ SDValue AArch64TargetLowering::getSqrtEstimate(SDValue Operand,
|
||||
// AArch64 reciprocal square root iteration instruction: 0.5 * (3 - M * N)
|
||||
for (int i = ExtraSteps; i > 0; --i) {
|
||||
SDValue Step = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Estimate,
|
||||
&Flags);
|
||||
Step = DAG.getNode(AArch64ISD::FRSQRTS, DL, VT, Operand, Step, &Flags);
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Step, &Flags);
|
||||
Flags);
|
||||
Step = DAG.getNode(AArch64ISD::FRSQRTS, DL, VT, Operand, Step, Flags);
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Step, Flags);
|
||||
}
|
||||
|
||||
if (!Reciprocal) {
|
||||
@ -4858,7 +4858,7 @@ SDValue AArch64TargetLowering::getSqrtEstimate(SDValue Operand,
|
||||
SDValue FPZero = DAG.getConstantFP(0.0, DL, VT);
|
||||
SDValue Eq = DAG.getSetCC(DL, CCVT, Operand, FPZero, ISD::SETEQ);
|
||||
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Operand, Estimate, &Flags);
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Operand, Estimate, Flags);
|
||||
// Correct the result if the operand is 0.0.
|
||||
Estimate = DAG.getNode(VT.isVector() ? ISD::VSELECT : ISD::SELECT, DL,
|
||||
VT, Eq, Operand, Estimate);
|
||||
@ -4887,8 +4887,8 @@ SDValue AArch64TargetLowering::getRecipEstimate(SDValue Operand,
|
||||
// AArch64 reciprocal iteration instruction: (2 - M * N)
|
||||
for (int i = ExtraSteps; i > 0; --i) {
|
||||
SDValue Step = DAG.getNode(AArch64ISD::FRECPS, DL, VT, Operand,
|
||||
Estimate, &Flags);
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Step, &Flags);
|
||||
Estimate, Flags);
|
||||
Estimate = DAG.getNode(ISD::FMUL, DL, VT, Estimate, Step, Flags);
|
||||
}
|
||||
|
||||
ExtraSteps = 0;
|
||||
|
@ -207,8 +207,8 @@ bool AMDGPUDAGToDAGISel::isNoNanSrc(SDValue N) const {
|
||||
return true;
|
||||
|
||||
// TODO: Move into isKnownNeverNaN
|
||||
if (const auto *BO = dyn_cast<BinaryWithFlagsSDNode>(N))
|
||||
return BO->Flags.hasNoNaNs();
|
||||
if (N->getFlags().isDefined())
|
||||
return N->getFlags().hasNoNaNs();
|
||||
|
||||
return CurDAG->isKnownNeverNaN(N);
|
||||
}
|
||||
|
@ -125,8 +125,9 @@ public:
|
||||
if (getTargetMachine().Options.NoSignedZerosFPMath)
|
||||
return true;
|
||||
|
||||
if (const auto *BO = dyn_cast<BinaryWithFlagsSDNode>(Op))
|
||||
return BO->Flags.hasNoSignedZeros();
|
||||
const auto Flags = Op.getNode()->getFlags();
|
||||
if (Flags.isDefined())
|
||||
return Flags.hasNoSignedZeros();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -3521,15 +3521,15 @@ SDValue SITargetLowering::lowerFastUnsafeFDIV(SDValue Op,
|
||||
}
|
||||
}
|
||||
|
||||
const SDNodeFlags *Flags = Op->getFlags();
|
||||
const SDNodeFlags Flags = Op->getFlags();
|
||||
|
||||
if (Unsafe || Flags->hasAllowReciprocal()) {
|
||||
if (Unsafe || Flags.hasAllowReciprocal()) {
|
||||
// Turn into multiply by the reciprocal.
|
||||
// x / y -> x * (1.0 / y)
|
||||
SDNodeFlags Flags;
|
||||
Flags.setUnsafeAlgebra(true);
|
||||
SDNodeFlags NewFlags;
|
||||
NewFlags.setUnsafeAlgebra(true);
|
||||
SDValue Recip = DAG.getNode(AMDGPUISD::RCP, SL, VT, RHS);
|
||||
return DAG.getNode(ISD::FMUL, SL, VT, LHS, Recip, &Flags);
|
||||
return DAG.getNode(ISD::FMUL, SL, VT, LHS, Recip, NewFlags);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
@ -4608,10 +4608,9 @@ unsigned SITargetLowering::getFusedOpcode(const SelectionDAG &DAG,
|
||||
return ISD::FMAD;
|
||||
|
||||
const TargetOptions &Options = DAG.getTarget().Options;
|
||||
if ((Options.AllowFPOpFusion == FPOpFusion::Fast ||
|
||||
Options.UnsafeFPMath ||
|
||||
(cast<BinaryWithFlagsSDNode>(N0)->Flags.hasUnsafeAlgebra() &&
|
||||
cast<BinaryWithFlagsSDNode>(N1)->Flags.hasUnsafeAlgebra())) &&
|
||||
if ((Options.AllowFPOpFusion == FPOpFusion::Fast || Options.UnsafeFPMath ||
|
||||
(N0->getFlags().hasUnsafeAlgebra() &&
|
||||
N1->getFlags().hasUnsafeAlgebra())) &&
|
||||
isFMAFasterThanFMulAndFAdd(VT)) {
|
||||
return ISD::FMA;
|
||||
}
|
||||
|
@ -6464,7 +6464,7 @@ SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::SETNE:
|
||||
std::swap(TV, FV);
|
||||
case ISD::SETEQ:
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, &Flags);
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
|
||||
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
|
||||
Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
|
||||
Sel1 = DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
|
||||
@ -6474,25 +6474,25 @@ SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
|
||||
DAG.getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
|
||||
case ISD::SETULT:
|
||||
case ISD::SETLT:
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, &Flags);
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
|
||||
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
|
||||
Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
|
||||
return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
|
||||
case ISD::SETOGE:
|
||||
case ISD::SETGE:
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, &Flags);
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, LHS, RHS, Flags);
|
||||
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
|
||||
Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
|
||||
return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
|
||||
case ISD::SETUGT:
|
||||
case ISD::SETGT:
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, &Flags);
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, Flags);
|
||||
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
|
||||
Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
|
||||
return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
|
||||
case ISD::SETOLE:
|
||||
case ISD::SETLE:
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, &Flags);
|
||||
Cmp = DAG.getNode(ISD::FSUB, dl, CmpVT, RHS, LHS, Flags);
|
||||
if (Cmp.getValueType() == MVT::f32) // Comparison is always 64-bits
|
||||
Cmp = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
|
||||
return DAG.getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
|
||||
|
@ -16342,11 +16342,9 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, const SDLoc &dl,
|
||||
case ISD::ADD:
|
||||
case ISD::SUB:
|
||||
case ISD::MUL:
|
||||
case ISD::SHL: {
|
||||
const auto *BinNode = cast<BinaryWithFlagsSDNode>(Op.getNode());
|
||||
if (BinNode->Flags.hasNoSignedWrap())
|
||||
case ISD::SHL:
|
||||
if (Op.getNode()->getFlags().hasNoSignedWrap())
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NeedOF = true;
|
||||
break;
|
||||
@ -33514,7 +33512,7 @@ static SDValue combineFneg(SDNode *N, SelectionDAG &DAG,
|
||||
// use of a constant by performing (-0 - A*B) instead.
|
||||
// FIXME: Check rounding control flags as well once it becomes available.
|
||||
if (Arg.getOpcode() == ISD::FMUL && (SVT == MVT::f32 || SVT == MVT::f64) &&
|
||||
Arg->getFlags()->hasNoSignedZeros() && Subtarget.hasAnyFMA()) {
|
||||
Arg->getFlags().hasNoSignedZeros() && Subtarget.hasAnyFMA()) {
|
||||
SDValue Zero = DAG.getConstantFP(0.0, DL, VT);
|
||||
SDValue NewNode = DAG.getNode(X86ISD::FNMSUB, DL, VT, Arg.getOperand(0),
|
||||
Arg.getOperand(1), Zero);
|
||||
@ -33875,8 +33873,8 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
|
||||
return SDValue();
|
||||
|
||||
bool Sext = Ext->getOpcode() == ISD::SIGN_EXTEND;
|
||||
bool NSW = Add->getFlags()->hasNoSignedWrap();
|
||||
bool NUW = Add->getFlags()->hasNoUnsignedWrap();
|
||||
bool NSW = Add->getFlags().hasNoSignedWrap();
|
||||
bool NUW = Add->getFlags().hasNoUnsignedWrap();
|
||||
|
||||
// We need an 'add nsw' feeding into the 'sext' or 'add nuw' feeding
|
||||
// into the 'zext'
|
||||
@ -33916,7 +33914,7 @@ static SDValue promoteExtBeforeAdd(SDNode *Ext, SelectionDAG &DAG,
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoSignedWrap(NSW);
|
||||
Flags.setNoUnsignedWrap(NUW);
|
||||
return DAG.getNode(ISD::ADD, SDLoc(Add), VT, NewExt, NewConstant, &Flags);
|
||||
return DAG.getNode(ISD::ADD, SDLoc(Add), VT, NewExt, NewConstant, Flags);
|
||||
}
|
||||
|
||||
/// (i8,i32 {s/z}ext ({s/u}divrem (i8 x, i8 y)) ->
|
||||
@ -34801,8 +34799,8 @@ static SDValue combineLoopSADPattern(SDNode *N, SelectionDAG &DAG,
|
||||
|
||||
static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
|
||||
const X86Subtarget &Subtarget) {
|
||||
const SDNodeFlags *Flags = &cast<BinaryWithFlagsSDNode>(N)->Flags;
|
||||
if (Flags->hasVectorReduction()) {
|
||||
const SDNodeFlags Flags = N->getFlags();
|
||||
if (Flags.hasVectorReduction()) {
|
||||
if (SDValue Sad = combineLoopSADPattern(N, DAG, Subtarget))
|
||||
return Sad;
|
||||
if (SDValue MAdd = combineLoopMAddPattern(N, DAG, Subtarget))
|
||||
|
Loading…
x
Reference in New Issue
Block a user