mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[SDAG] At the suggestion of Hal, switch to an output parameter that
tracks which elements of the build vector are in fact undef. This should make actually inpsecting them (likely in my next patch) reasonably pretty. Also makes the output parameter optional as it is clear now that *most* users are happy with undefs in their splats. llvm-svn: 212581
This commit is contained in:
parent
2c8ab6f1ca
commit
14de70ee01
@ -20,6 +20,7 @@
|
|||||||
#define LLVM_CODEGEN_SELECTIONDAGNODES_H
|
#define LLVM_CODEGEN_SELECTIONDAGNODES_H
|
||||||
|
|
||||||
#include "llvm/ADT/iterator_range.h"
|
#include "llvm/ADT/iterator_range.h"
|
||||||
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
@ -1584,15 +1585,26 @@ public:
|
|||||||
bool isBigEndian = false) const;
|
bool isBigEndian = false) const;
|
||||||
|
|
||||||
/// \brief Returns the splatted value or a null value if this is not a splat.
|
/// \brief Returns the splatted value or a null value if this is not a splat.
|
||||||
SDValue getSplatValue(bool &HasUndefElements) const;
|
///
|
||||||
|
/// If passed a non-null UndefElements bitvector, it will resize it to match
|
||||||
|
/// the vector width and set the bits where elements are undef.
|
||||||
|
SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
|
||||||
|
|
||||||
/// \brief Returns the splatted constant or null if this is not a constant
|
/// \brief Returns the splatted constant or null if this is not a constant
|
||||||
/// splat.
|
/// splat.
|
||||||
ConstantSDNode *getConstantSplatNode(bool &HasUndefElements) const;
|
///
|
||||||
|
/// If passed a non-null UndefElements bitvector, it will resize it to match
|
||||||
|
/// the vector width and set the bits where elements are undef.
|
||||||
|
ConstantSDNode *
|
||||||
|
getConstantSplatNode(BitVector *UndefElements = nullptr) const;
|
||||||
|
|
||||||
/// \brief Returns the splatted constant FP or null if this is not a constant
|
/// \brief Returns the splatted constant FP or null if this is not a constant
|
||||||
/// FP splat.
|
/// FP splat.
|
||||||
ConstantFPSDNode *getConstantFPSplatNode(bool &HasUndefElements) const;
|
///
|
||||||
|
/// If passed a non-null UndefElements bitvector, it will resize it to match
|
||||||
|
/// the vector width and set the bits where elements are undef.
|
||||||
|
ConstantFPSDNode *
|
||||||
|
getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
|
||||||
|
|
||||||
bool isConstant() const;
|
bool isConstant() const;
|
||||||
|
|
||||||
|
@ -655,13 +655,13 @@ static ConstantSDNode *isConstOrConstSplat(SDValue N) {
|
|||||||
return CN;
|
return CN;
|
||||||
|
|
||||||
if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
|
if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
|
||||||
bool HasUndefElements;
|
BitVector UndefElements;
|
||||||
ConstantSDNode *CN = BV->getConstantSplatNode(HasUndefElements);
|
ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
|
||||||
|
|
||||||
// BuildVectors can truncate their operands. Ignore that case here.
|
// BuildVectors can truncate their operands. Ignore that case here.
|
||||||
// FIXME: We blindly ignore splats which include undef which is overly
|
// FIXME: We blindly ignore splats which include undef which is overly
|
||||||
// pessimistic.
|
// pessimistic.
|
||||||
if (CN && !HasUndefElements &&
|
if (CN && UndefElements.none() &&
|
||||||
CN->getValueType(0) == N.getValueType().getScalarType())
|
CN->getValueType(0) == N.getValueType().getScalarType())
|
||||||
return CN;
|
return CN;
|
||||||
}
|
}
|
||||||
|
@ -1521,15 +1521,15 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1,
|
|||||||
|
|
||||||
// A splat should always show up as a build vector node.
|
// A splat should always show up as a build vector node.
|
||||||
if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) {
|
if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) {
|
||||||
bool SplatHasUndefs;
|
BitVector UndefElements;
|
||||||
SDValue Splat = BV->getSplatValue(SplatHasUndefs);
|
SDValue Splat = BV->getSplatValue(&UndefElements);
|
||||||
// If this is a splat of an undef, shuffling it is also undef.
|
// If this is a splat of an undef, shuffling it is also undef.
|
||||||
if (Splat && Splat.getOpcode() == ISD::UNDEF)
|
if (Splat && Splat.getOpcode() == ISD::UNDEF)
|
||||||
return getUNDEF(VT);
|
return getUNDEF(VT);
|
||||||
|
|
||||||
// We only have a splat which can skip shuffles if there is a splatted
|
// We only have a splat which can skip shuffles if there is a splatted
|
||||||
// value and no undef lanes rearranged by the shuffle.
|
// value and no undef lanes rearranged by the shuffle.
|
||||||
if (Splat && !SplatHasUndefs) {
|
if (Splat && UndefElements.none()) {
|
||||||
// Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the
|
// Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the
|
||||||
// number of elements match or the value splatted is a zero constant.
|
// number of elements match or the value splatted is a zero constant.
|
||||||
if (V.getValueType().getVectorNumElements() ==
|
if (V.getValueType().getVectorNumElements() ==
|
||||||
@ -6635,17 +6635,22 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
|
SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const {
|
||||||
HasUndefElements = false;
|
if (UndefElements) {
|
||||||
|
UndefElements->clear();
|
||||||
|
UndefElements->resize(getNumOperands());
|
||||||
|
}
|
||||||
SDValue Splatted;
|
SDValue Splatted;
|
||||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
||||||
SDValue Op = getOperand(i);
|
SDValue Op = getOperand(i);
|
||||||
if (Op.getOpcode() == ISD::UNDEF)
|
if (Op.getOpcode() == ISD::UNDEF) {
|
||||||
HasUndefElements = true;
|
if (UndefElements)
|
||||||
else if (!Splatted)
|
(*UndefElements)[i] = true;
|
||||||
|
} else if (!Splatted) {
|
||||||
Splatted = Op;
|
Splatted = Op;
|
||||||
else if (Splatted != Op)
|
} else if (Splatted != Op) {
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Splatted) {
|
if (!Splatted) {
|
||||||
@ -6658,15 +6663,15 @@ SDValue BuildVectorSDNode::getSplatValue(bool &HasUndefElements) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConstantSDNode *
|
ConstantSDNode *
|
||||||
BuildVectorSDNode::getConstantSplatNode(bool &HasUndefElements) const {
|
BuildVectorSDNode::getConstantSplatNode(BitVector *UndefElements) const {
|
||||||
return dyn_cast_or_null<ConstantSDNode>(
|
return dyn_cast_or_null<ConstantSDNode>(
|
||||||
getSplatValue(HasUndefElements).getNode());
|
getSplatValue(UndefElements).getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantFPSDNode *
|
ConstantFPSDNode *
|
||||||
BuildVectorSDNode::getConstantFPSplatNode(bool &HasUndefElements) const {
|
BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const {
|
||||||
return dyn_cast_or_null<ConstantFPSDNode>(
|
return dyn_cast_or_null<ConstantFPSDNode>(
|
||||||
getSplatValue(HasUndefElements).getNode());
|
getSplatValue(UndefElements).getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildVectorSDNode::isConstant() const {
|
bool BuildVectorSDNode::isConstant() const {
|
||||||
|
@ -1158,11 +1158,11 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
IsVec = true;
|
IsVec = true;
|
||||||
bool HasUndefElements;
|
BitVector UndefElements;
|
||||||
CN = BV->getConstantSplatNode(HasUndefElements);
|
CN = BV->getConstantSplatNode(&UndefElements);
|
||||||
// Only interested in constant splats, and we don't try to handle undef
|
// Only interested in constant splats, and we don't try to handle undef
|
||||||
// elements in identifying boolean constants.
|
// elements in identifying boolean constants.
|
||||||
if (!CN || HasUndefElements)
|
if (!CN || UndefElements.none())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,11 +1190,11 @@ bool TargetLowering::isConstFalseVal(const SDNode *N) const {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
IsVec = true;
|
IsVec = true;
|
||||||
bool HasUndefElements;
|
BitVector UndefElements;
|
||||||
CN = BV->getConstantSplatNode(HasUndefElements);
|
CN = BV->getConstantSplatNode(&UndefElements);
|
||||||
// Only interested in constant splats, and we don't try to handle undef
|
// Only interested in constant splats, and we don't try to handle undef
|
||||||
// elements in identifying boolean constants.
|
// elements in identifying boolean constants.
|
||||||
if (!CN || HasUndefElements)
|
if (!CN || UndefElements.none())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user