forked from OSchip/llvm-project
[SelectionDAG] move constant or splat functions to common location
rL347502 moved the null sibling, so we should group all of these together. I'm not sure why these aren't methods of the SDValue class itself, but that's another patch if that's possible. llvm-svn: 347523
This commit is contained in:
parent
36296c0484
commit
04435677d0
|
@ -1613,11 +1613,21 @@ ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false);
|
||||||
/// Returns the SDNode if it is a constant splat BuildVector or constant float.
|
/// Returns the SDNode if it is a constant splat BuildVector or constant float.
|
||||||
ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
|
ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
|
||||||
|
|
||||||
/// Determines if it is a constant null integer or a splatted vector of a
|
/// Return true if the value is a constant 0 integer or a splatted vector of
|
||||||
/// constant null integer (with no undefs).
|
/// a constant 0 integer (with no undefs).
|
||||||
/// Build vector implicit truncation is not an issue for null values.
|
/// Build vector implicit truncation is not an issue for null values.
|
||||||
bool isNullOrNullSplat(SDValue V);
|
bool isNullOrNullSplat(SDValue V);
|
||||||
|
|
||||||
|
/// Return true if the value is a constant 1 integer or a splatted vector of a
|
||||||
|
/// constant 1 integer (with no undefs).
|
||||||
|
/// Does not permit build vector implicit truncation.
|
||||||
|
bool isOneOrOneSplat(SDValue V);
|
||||||
|
|
||||||
|
/// Return true if the value is a constant -1 integer or a splatted vector of a
|
||||||
|
/// constant -1 integer (with no undefs).
|
||||||
|
/// Does not permit build vector implicit truncation.
|
||||||
|
bool isAllOnesOrAllOnesSplat(SDValue V);
|
||||||
|
|
||||||
class GlobalAddressSDNode : public SDNode {
|
class GlobalAddressSDNode : public SDNode {
|
||||||
friend class SelectionDAG;
|
friend class SelectionDAG;
|
||||||
|
|
||||||
|
|
|
@ -911,29 +911,6 @@ static bool isConstantOrConstantVector(SDValue N, bool NoOpaques = false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if it is a constant integer of one or a splatted vector of a
|
|
||||||
// constant integer of one (with no undefs).
|
|
||||||
// Do not permit build vector implicit truncation.
|
|
||||||
static bool isOneConstantOrOneSplatConstant(SDValue N) {
|
|
||||||
// TODO: may want to use peekThroughBitcast() here.
|
|
||||||
unsigned BitWidth = N.getScalarValueSizeInBits();
|
|
||||||
if (ConstantSDNode *Splat = isConstOrConstSplat(N))
|
|
||||||
return Splat->isOne() && Splat->getAPIntValue().getBitWidth() == BitWidth;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determines if it is a constant integer of all ones or a splatted vector of a
|
|
||||||
// constant integer of all ones (with no undefs).
|
|
||||||
// Do not permit build vector implicit truncation.
|
|
||||||
static bool isAllOnesConstantOrAllOnesSplatConstant(SDValue N) {
|
|
||||||
N = peekThroughBitcasts(N);
|
|
||||||
unsigned BitWidth = N.getScalarValueSizeInBits();
|
|
||||||
if (ConstantSDNode *Splat = isConstOrConstSplat(N))
|
|
||||||
return Splat->isAllOnesValue() &&
|
|
||||||
Splat->getAPIntValue().getBitWidth() == BitWidth;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determines if a BUILD_VECTOR is composed of all-constants possibly mixed with
|
// Determines if a BUILD_VECTOR is composed of all-constants possibly mixed with
|
||||||
// undef's.
|
// undef's.
|
||||||
static bool isAnyConstantBuildVector(const SDNode *N) {
|
static bool isAnyConstantBuildVector(const SDNode *N) {
|
||||||
|
@ -1911,11 +1888,10 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
|
||||||
// and (select Cond, 0, -1), X --> select Cond, 0, X
|
// and (select Cond, 0, -1), X --> select Cond, 0, X
|
||||||
// or X, (select Cond, -1, 0) --> select Cond, -1, X
|
// or X, (select Cond, -1, 0) --> select Cond, -1, X
|
||||||
auto BinOpcode = BO->getOpcode();
|
auto BinOpcode = BO->getOpcode();
|
||||||
bool CanFoldNonConst = (BinOpcode == ISD::AND || BinOpcode == ISD::OR) &&
|
bool CanFoldNonConst =
|
||||||
(isNullOrNullSplat(CT) ||
|
(BinOpcode == ISD::AND || BinOpcode == ISD::OR) &&
|
||||||
isAllOnesConstantOrAllOnesSplatConstant(CT)) &&
|
(isNullOrNullSplat(CT) || isAllOnesOrAllOnesSplat(CT)) &&
|
||||||
(isNullOrNullSplat(CF) ||
|
(isNullOrNullSplat(CF) || isAllOnesOrAllOnesSplat(CF));
|
||||||
isAllOnesConstantOrAllOnesSplatConstant(CF));
|
|
||||||
|
|
||||||
SDValue CBO = BO->getOperand(SelOpNo ^ 1);
|
SDValue CBO = BO->getOperand(SelOpNo ^ 1);
|
||||||
if (!CanFoldNonConst &&
|
if (!CanFoldNonConst &&
|
||||||
|
@ -2084,7 +2060,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
||||||
// add (zext i1 X), -1 -> sext (not i1 X)
|
// add (zext i1 X), -1 -> sext (not i1 X)
|
||||||
// because most (?) targets generate better code for the zext form.
|
// because most (?) targets generate better code for the zext form.
|
||||||
if (N0.getOpcode() == ISD::SIGN_EXTEND && N0.hasOneUse() &&
|
if (N0.getOpcode() == ISD::SIGN_EXTEND && N0.hasOneUse() &&
|
||||||
isOneConstantOrOneSplatConstant(N1)) {
|
isOneOrOneSplat(N1)) {
|
||||||
SDValue X = N0.getOperand(0);
|
SDValue X = N0.getOperand(0);
|
||||||
if ((!LegalOperations ||
|
if ((!LegalOperations ||
|
||||||
(TLI.isOperationLegal(ISD::XOR, X.getValueType()) &&
|
(TLI.isOperationLegal(ISD::XOR, X.getValueType()) &&
|
||||||
|
@ -2175,7 +2151,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
||||||
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
|
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
|
||||||
|
|
||||||
// fold (add (xor a, -1), 1) -> (sub 0, a)
|
// fold (add (xor a, -1), 1) -> (sub 0, a)
|
||||||
if (isBitwiseNot(N0) && isOneConstantOrOneSplatConstant(N1))
|
if (isBitwiseNot(N0) && isOneOrOneSplat(N1))
|
||||||
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
|
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
|
||||||
N0.getOperand(0));
|
N0.getOperand(0));
|
||||||
|
|
||||||
|
@ -2245,8 +2221,7 @@ SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference)
|
||||||
|
|
||||||
// (add z, (and (sbbl x, x), 1)) -> (sub z, (sbbl x, x))
|
// (add z, (and (sbbl x, x), 1)) -> (sub z, (sbbl x, x))
|
||||||
// and similar xforms where the inner op is either ~0 or 0.
|
// and similar xforms where the inner op is either ~0 or 0.
|
||||||
if (NumSignBits == DestBits &&
|
if (NumSignBits == DestBits && isOneOrOneSplat(N1->getOperand(1)))
|
||||||
isOneConstantOrOneSplatConstant(N1->getOperand(1)))
|
|
||||||
return DAG.getNode(ISD::SUB, DL, VT, N0, AndOp0);
|
return DAG.getNode(ISD::SUB, DL, VT, N0, AndOp0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2377,7 +2352,7 @@ SDValue DAGCombiner::visitUADDO(SDNode *N) {
|
||||||
DAG.getConstant(0, DL, CarryVT));
|
DAG.getConstant(0, DL, CarryVT));
|
||||||
|
|
||||||
// fold (uaddo (xor a, -1), 1) -> (usub 0, a) and flip carry.
|
// fold (uaddo (xor a, -1), 1) -> (usub 0, a) and flip carry.
|
||||||
if (isBitwiseNot(N0) && isOneConstantOrOneSplatConstant(N1)) {
|
if (isBitwiseNot(N0) && isOneOrOneSplat(N1)) {
|
||||||
SDValue Sub = DAG.getNode(ISD::USUBO, DL, N->getVTList(),
|
SDValue Sub = DAG.getNode(ISD::USUBO, DL, N->getVTList(),
|
||||||
DAG.getConstant(0, DL, VT),
|
DAG.getConstant(0, DL, VT),
|
||||||
N0.getOperand(0));
|
N0.getOperand(0));
|
||||||
|
@ -2613,7 +2588,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
|
// Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
|
||||||
if (isAllOnesConstantOrAllOnesSplatConstant(N0))
|
if (isAllOnesOrAllOnesSplat(N0))
|
||||||
return DAG.getNode(ISD::XOR, DL, VT, N1, N0);
|
return DAG.getNode(ISD::XOR, DL, VT, N1, N0);
|
||||||
|
|
||||||
// fold (A - (0-B)) -> A+B
|
// fold (A - (0-B)) -> A+B
|
||||||
|
@ -3899,7 +3874,7 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
|
||||||
bool IsInteger = OpVT.isInteger();
|
bool IsInteger = OpVT.isInteger();
|
||||||
if (LR == RR && CC0 == CC1 && IsInteger) {
|
if (LR == RR && CC0 == CC1 && IsInteger) {
|
||||||
bool IsZero = isNullOrNullSplat(LR);
|
bool IsZero = isNullOrNullSplat(LR);
|
||||||
bool IsNeg1 = isAllOnesConstantOrAllOnesSplatConstant(LR);
|
bool IsNeg1 = isAllOnesOrAllOnesSplat(LR);
|
||||||
|
|
||||||
// All bits clear?
|
// All bits clear?
|
||||||
bool AndEqZero = IsAnd && CC1 == ISD::SETEQ && IsZero;
|
bool AndEqZero = IsAnd && CC1 == ISD::SETEQ && IsZero;
|
||||||
|
@ -5946,7 +5921,7 @@ SDValue DAGCombiner::unfoldMaskedMerge(SDNode *N) {
|
||||||
assert(N->getOpcode() == ISD::XOR);
|
assert(N->getOpcode() == ISD::XOR);
|
||||||
|
|
||||||
// Don't touch 'not' (i.e. where y = -1).
|
// Don't touch 'not' (i.e. where y = -1).
|
||||||
if (isAllOnesConstantOrAllOnesSplatConstant(N->getOperand(1)))
|
if (isAllOnesOrAllOnesSplat(N->getOperand(1)))
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
EVT VT = N->getValueType(0);
|
EVT VT = N->getValueType(0);
|
||||||
|
@ -5963,7 +5938,7 @@ SDValue DAGCombiner::unfoldMaskedMerge(SDNode *N) {
|
||||||
SDValue Xor0 = Xor.getOperand(0);
|
SDValue Xor0 = Xor.getOperand(0);
|
||||||
SDValue Xor1 = Xor.getOperand(1);
|
SDValue Xor1 = Xor.getOperand(1);
|
||||||
// Don't touch 'not' (i.e. where y = -1).
|
// Don't touch 'not' (i.e. where y = -1).
|
||||||
if (isAllOnesConstantOrAllOnesSplatConstant(Xor1))
|
if (isAllOnesOrAllOnesSplat(Xor1))
|
||||||
return false;
|
return false;
|
||||||
if (Other == Xor0)
|
if (Other == Xor0)
|
||||||
std::swap(Xor0, Xor1);
|
std::swap(Xor0, Xor1);
|
||||||
|
|
|
@ -8381,8 +8381,22 @@ ConstantFPSDNode *llvm::isConstOrConstSplatFP(SDValue N, bool AllowUndefs) {
|
||||||
|
|
||||||
bool llvm::isNullOrNullSplat(SDValue N) {
|
bool llvm::isNullOrNullSplat(SDValue N) {
|
||||||
// TODO: may want to use peekThroughBitcast() here.
|
// TODO: may want to use peekThroughBitcast() here.
|
||||||
ConstantSDNode *Splat = isConstOrConstSplat(N);
|
ConstantSDNode *C = isConstOrConstSplat(N);
|
||||||
return Splat && Splat->isNullValue();
|
return C && C->isNullValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::isOneOrOneSplat(SDValue N) {
|
||||||
|
// TODO: may want to use peekThroughBitcast() here.
|
||||||
|
unsigned BitWidth = N.getScalarValueSizeInBits();
|
||||||
|
ConstantSDNode *C = isConstOrConstSplat(N);
|
||||||
|
return C && C->isOne() && C->getValueSizeInBits(0) == BitWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::isAllOnesOrAllOnesSplat(SDValue N) {
|
||||||
|
N = peekThroughBitcasts(N);
|
||||||
|
unsigned BitWidth = N.getScalarValueSizeInBits();
|
||||||
|
ConstantSDNode *C = isConstOrConstSplat(N);
|
||||||
|
return C && C->isAllOnesValue() && C->getValueSizeInBits(0) == BitWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleSDNode::~HandleSDNode() {
|
HandleSDNode::~HandleSDNode() {
|
||||||
|
|
Loading…
Reference in New Issue