forked from OSchip/llvm-project
[DAG] Move DAGCombiner::GetDemandedBits to SelectionDAG
This patch moves the DAGCombiner::GetDemandedBits function to SelectionDAG::GetDemandedBits as a first step towards making it easier for targets to get to the source of any demanded bits without the limitations of SimplifyDemandedBits. Differential Revision: https://reviews.llvm.org/D35841 llvm-svn: 308983
This commit is contained in:
parent
8d89179e33
commit
6d59933175
|
@ -1307,6 +1307,14 @@ public:
|
||||||
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
|
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
|
||||||
const SDLoc &dl);
|
const SDLoc &dl);
|
||||||
|
|
||||||
|
/// See if the specified operand can be simplified with the knowledge that only
|
||||||
|
/// the bits specified by Mask are used. If so, return the simpler operand,
|
||||||
|
/// otherwise return a null SDValue.
|
||||||
|
///
|
||||||
|
/// (This exists alongside SimplifyDemandedBits because GetDemandedBits can
|
||||||
|
/// simplify nodes with multiple uses more aggressively.)
|
||||||
|
SDValue GetDemandedBits(SDValue V, const APInt &Mask);
|
||||||
|
|
||||||
/// Return true if the sign bit of Op is known to be zero.
|
/// Return true if the sign bit of Op is known to be zero.
|
||||||
/// We use this predicate to simplify operations downstream.
|
/// We use this predicate to simplify operations downstream.
|
||||||
bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
|
bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
|
||||||
|
|
|
@ -406,8 +406,6 @@ namespace {
|
||||||
SDValue VecIn2, unsigned LeftIdx);
|
SDValue VecIn2, unsigned LeftIdx);
|
||||||
SDValue matchVSelectOpSizesWithSetCC(SDNode *N);
|
SDValue matchVSelectOpSizesWithSetCC(SDNode *N);
|
||||||
|
|
||||||
SDValue GetDemandedBits(SDValue V, const APInt &Mask);
|
|
||||||
|
|
||||||
/// Walk up chain skipping non-aliasing memory nodes,
|
/// Walk up chain skipping non-aliasing memory nodes,
|
||||||
/// looking for aliasing nodes and adding them to the Aliases vector.
|
/// looking for aliasing nodes and adding them to the Aliases vector.
|
||||||
void GatherAllAliases(SDNode *N, SDValue OriginalChain,
|
void GatherAllAliases(SDNode *N, SDValue OriginalChain,
|
||||||
|
@ -7904,59 +7902,6 @@ SDValue DAGCombiner::visitAssertZext(SDNode *N) {
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See if the specified operand can be simplified with the knowledge that only
|
|
||||||
/// the bits specified by Mask are used. If so, return the simpler operand,
|
|
||||||
/// otherwise return a null SDValue.
|
|
||||||
///
|
|
||||||
/// (This exists alongside SimplifyDemandedBits because GetDemandedBits can
|
|
||||||
/// simplify nodes with multiple uses more aggressively.)
|
|
||||||
SDValue DAGCombiner::GetDemandedBits(SDValue V, const APInt &Mask) {
|
|
||||||
switch (V.getOpcode()) {
|
|
||||||
default: break;
|
|
||||||
case ISD::Constant: {
|
|
||||||
const ConstantSDNode *CV = cast<ConstantSDNode>(V.getNode());
|
|
||||||
assert(CV && "Const value should be ConstSDNode.");
|
|
||||||
const APInt &CVal = CV->getAPIntValue();
|
|
||||||
APInt NewVal = CVal & Mask;
|
|
||||||
if (NewVal != CVal)
|
|
||||||
return DAG.getConstant(NewVal, SDLoc(V), V.getValueType());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ISD::OR:
|
|
||||||
case ISD::XOR:
|
|
||||||
// If the LHS or RHS don't contribute bits to the or, drop them.
|
|
||||||
if (DAG.MaskedValueIsZero(V.getOperand(0), Mask))
|
|
||||||
return V.getOperand(1);
|
|
||||||
if (DAG.MaskedValueIsZero(V.getOperand(1), Mask))
|
|
||||||
return V.getOperand(0);
|
|
||||||
break;
|
|
||||||
case ISD::SRL:
|
|
||||||
// Only look at single-use SRLs.
|
|
||||||
if (!V.getNode()->hasOneUse())
|
|
||||||
break;
|
|
||||||
if (ConstantSDNode *RHSC = getAsNonOpaqueConstant(V.getOperand(1))) {
|
|
||||||
// See if we can recursively simplify the LHS.
|
|
||||||
unsigned Amt = RHSC->getZExtValue();
|
|
||||||
|
|
||||||
// Watch out for shift count overflow though.
|
|
||||||
if (Amt >= Mask.getBitWidth()) break;
|
|
||||||
APInt NewMask = Mask << Amt;
|
|
||||||
if (SDValue SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask))
|
|
||||||
return DAG.getNode(ISD::SRL, SDLoc(V), V.getValueType(),
|
|
||||||
SimplifyLHS, V.getOperand(1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ISD::AND: {
|
|
||||||
// X & -1 -> X (ignoring bits which aren't demanded).
|
|
||||||
ConstantSDNode *AndVal = isConstOrConstSplat(V.getOperand(1));
|
|
||||||
if (AndVal && Mask.isSubsetOf(AndVal->getAPIntValue()))
|
|
||||||
return V.getOperand(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SDValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the result of a wider load is shifted to right of N bits and then
|
/// If the result of a wider load is shifted to right of N bits and then
|
||||||
/// truncated to a narrower type and where N is a multiple of number of bits of
|
/// truncated to a narrower type and where N is a multiple of number of bits of
|
||||||
/// the narrower type, transform it to a narrower load from address + N / num of
|
/// the narrower type, transform it to a narrower load from address + N / num of
|
||||||
|
@ -8427,9 +8372,9 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
|
||||||
// Currently we only perform this optimization on scalars because vectors
|
// Currently we only perform this optimization on scalars because vectors
|
||||||
// may have different active low bits.
|
// may have different active low bits.
|
||||||
if (!VT.isVector()) {
|
if (!VT.isVector()) {
|
||||||
if (SDValue Shorter =
|
APInt Mask =
|
||||||
GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(),
|
APInt::getLowBitsSet(N0.getValueSizeInBits(), VT.getSizeInBits());
|
||||||
VT.getSizeInBits())))
|
if (SDValue Shorter = DAG.GetDemandedBits(N0, Mask))
|
||||||
return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Shorter);
|
return DAG.getNode(ISD::TRUNCATE, SDLoc(N), VT, Shorter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13360,7 +13305,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
|
||||||
// See if we can simplify the input to this truncstore with knowledge that
|
// See if we can simplify the input to this truncstore with knowledge that
|
||||||
// only the low bits are being used. For example:
|
// only the low bits are being used. For example:
|
||||||
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
|
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
|
||||||
SDValue Shorter = GetDemandedBits(
|
SDValue Shorter = DAG.GetDemandedBits(
|
||||||
Value, APInt::getLowBitsSet(Value.getScalarValueSizeInBits(),
|
Value, APInt::getLowBitsSet(Value.getScalarValueSizeInBits(),
|
||||||
ST->getMemoryVT().getScalarSizeInBits()));
|
ST->getMemoryVT().getScalarSizeInBits()));
|
||||||
AddToWorklist(Value.getNode());
|
AddToWorklist(Value.getNode());
|
||||||
|
|
|
@ -1952,6 +1952,57 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// See if the specified operand can be simplified with the knowledge that only
|
||||||
|
/// the bits specified by Mask are used.
|
||||||
|
SDValue SelectionDAG::GetDemandedBits(SDValue V, const APInt &Mask) {
|
||||||
|
switch (V.getOpcode()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ISD::Constant: {
|
||||||
|
const ConstantSDNode *CV = cast<ConstantSDNode>(V.getNode());
|
||||||
|
assert(CV && "Const value should be ConstSDNode.");
|
||||||
|
const APInt &CVal = CV->getAPIntValue();
|
||||||
|
APInt NewVal = CVal & Mask;
|
||||||
|
if (NewVal != CVal)
|
||||||
|
return getConstant(NewVal, SDLoc(V), V.getValueType());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::OR:
|
||||||
|
case ISD::XOR:
|
||||||
|
// If the LHS or RHS don't contribute bits to the or, drop them.
|
||||||
|
if (MaskedValueIsZero(V.getOperand(0), Mask))
|
||||||
|
return V.getOperand(1);
|
||||||
|
if (MaskedValueIsZero(V.getOperand(1), Mask))
|
||||||
|
return V.getOperand(0);
|
||||||
|
break;
|
||||||
|
case ISD::SRL:
|
||||||
|
// Only look at single-use SRLs.
|
||||||
|
if (!V.getNode()->hasOneUse())
|
||||||
|
break;
|
||||||
|
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
|
||||||
|
// See if we can recursively simplify the LHS.
|
||||||
|
unsigned Amt = RHSC->getZExtValue();
|
||||||
|
|
||||||
|
// Watch out for shift count overflow though.
|
||||||
|
if (Amt >= Mask.getBitWidth())
|
||||||
|
break;
|
||||||
|
APInt NewMask = Mask << Amt;
|
||||||
|
if (SDValue SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask))
|
||||||
|
return getNode(ISD::SRL, SDLoc(V), V.getValueType(), SimplifyLHS,
|
||||||
|
V.getOperand(1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ISD::AND: {
|
||||||
|
// X & -1 -> X (ignoring bits which aren't demanded).
|
||||||
|
ConstantSDNode *AndVal = isConstOrConstSplat(V.getOperand(1));
|
||||||
|
if (AndVal && Mask.isSubsetOf(AndVal->getAPIntValue()))
|
||||||
|
return V.getOperand(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
|
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
|
||||||
/// use this predicate to simplify operations downstream.
|
/// use this predicate to simplify operations downstream.
|
||||||
bool SelectionDAG::SignBitIsZero(SDValue Op, unsigned Depth) const {
|
bool SelectionDAG::SignBitIsZero(SDValue Op, unsigned Depth) const {
|
||||||
|
|
Loading…
Reference in New Issue