mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[DAG] make isConstantSplatVector() available to the rest of lowering
llvm-svn: 275025
This commit is contained in:
parent
ba1aea29ff
commit
07d6ec0ea5
@ -66,6 +66,10 @@ struct SDVTList {
|
||||
namespace ISD {
|
||||
/// Node predicates
|
||||
|
||||
/// If N is a BUILD_VECTOR node whose elements are all the same constant or
|
||||
/// undefined, return true and return the constant value in \p SplatValue.
|
||||
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
|
||||
|
||||
/// Return true if the specified node is a BUILD_VECTOR where all of the
|
||||
/// elements are ~0 or undef.
|
||||
bool isBuildVectorAllOnes(const SDNode *N);
|
||||
|
@ -765,22 +765,6 @@ bool DAGCombiner::isOneUseSetCC(SDValue N) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if N is a BUILD_VECTOR node whose
|
||||
/// elements are all the same constant or undefined.
|
||||
static bool isConstantSplatVector(SDNode *N, APInt& SplatValue) {
|
||||
BuildVectorSDNode *C = dyn_cast<BuildVectorSDNode>(N);
|
||||
if (!C)
|
||||
return false;
|
||||
|
||||
APInt SplatUndef;
|
||||
unsigned SplatBitSize;
|
||||
bool HasAnyUndefs;
|
||||
EVT EltVT = N->getValueType(0).getVectorElementType();
|
||||
return (C->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
|
||||
HasAnyUndefs) &&
|
||||
EltVT.getSizeInBits() >= SplatBitSize);
|
||||
}
|
||||
|
||||
// \brief Returns the SDNode if it is a constant float BuildVector
|
||||
// or constant float.
|
||||
static SDNode *isConstantFPBuildVectorOrConstantFP(SDValue N) {
|
||||
@ -2034,8 +2018,8 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
if (SDValue FoldedVOp = SimplifyVBinOp(N))
|
||||
return FoldedVOp;
|
||||
|
||||
N0IsConst = isConstantSplatVector(N0.getNode(), ConstValue0);
|
||||
N1IsConst = isConstantSplatVector(N1.getNode(), ConstValue1);
|
||||
N0IsConst = ISD::isConstantSplatVector(N0.getNode(), ConstValue0);
|
||||
N1IsConst = ISD::isConstantSplatVector(N1.getNode(), ConstValue1);
|
||||
} else {
|
||||
N0IsConst = isa<ConstantSDNode>(N0);
|
||||
if (N0IsConst) {
|
||||
@ -2099,23 +2083,21 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
APInt Val;
|
||||
// (mul (shl X, c1), c2) -> (mul X, c2 << c1)
|
||||
if (N1IsConst && N0.getOpcode() == ISD::SHL &&
|
||||
(isConstantSplatVector(N0.getOperand(1).getNode(), Val) ||
|
||||
isa<ConstantSDNode>(N0.getOperand(1)))) {
|
||||
SDValue C3 = DAG.getNode(ISD::SHL, SDLoc(N), VT,
|
||||
N1, N0.getOperand(1));
|
||||
(ISD::isConstantSplatVector(N0.getOperand(1).getNode(), Val) ||
|
||||
isa<ConstantSDNode>(N0.getOperand(1)))) {
|
||||
SDValue C3 = DAG.getNode(ISD::SHL, SDLoc(N), VT, N1, N0.getOperand(1));
|
||||
AddToWorklist(C3.getNode());
|
||||
return DAG.getNode(ISD::MUL, SDLoc(N), VT,
|
||||
N0.getOperand(0), C3);
|
||||
return DAG.getNode(ISD::MUL, SDLoc(N), VT, N0.getOperand(0), C3);
|
||||
}
|
||||
|
||||
// Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one
|
||||
// use.
|
||||
{
|
||||
SDValue Sh(nullptr,0), Y(nullptr,0);
|
||||
SDValue Sh(nullptr, 0), Y(nullptr, 0);
|
||||
// Check for both (mul (shl X, C), Y) and (mul Y, (shl X, C)).
|
||||
if (N0.getOpcode() == ISD::SHL &&
|
||||
(isConstantSplatVector(N0.getOperand(1).getNode(), Val) ||
|
||||
isa<ConstantSDNode>(N0.getOperand(1))) &&
|
||||
(ISD::isConstantSplatVector(N0.getOperand(1).getNode(), Val) ||
|
||||
isa<ConstantSDNode>(N0.getOperand(1))) &&
|
||||
N0.getNode()->hasOneUse()) {
|
||||
Sh = N0; Y = N1;
|
||||
} else if (N1.getOpcode() == ISD::SHL &&
|
||||
@ -2125,10 +2107,8 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
|
||||
}
|
||||
|
||||
if (Sh.getNode()) {
|
||||
SDValue Mul = DAG.getNode(ISD::MUL, SDLoc(N), VT,
|
||||
Sh.getOperand(0), Y);
|
||||
return DAG.getNode(ISD::SHL, SDLoc(N), VT,
|
||||
Mul, Sh.getOperand(1));
|
||||
SDValue Mul = DAG.getNode(ISD::MUL, SDLoc(N), VT, Sh.getOperand(0), Y);
|
||||
return DAG.getNode(ISD::SHL, SDLoc(N), VT, Mul, Sh.getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4609,7 +4589,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
|
||||
APInt Val;
|
||||
if (N1C && N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse() &&
|
||||
(isa<ConstantSDNode>(N0.getOperand(1)) ||
|
||||
isConstantSplatVector(N0.getOperand(1).getNode(), Val))) {
|
||||
ISD::isConstantSplatVector(N0.getOperand(1).getNode(), Val))) {
|
||||
SDValue Shl0 = DAG.getNode(ISD::SHL, SDLoc(N0), VT, N0.getOperand(0), N1);
|
||||
SDValue Shl1 = DAG.getNode(ISD::SHL, SDLoc(N1), VT, N0.getOperand(1), N1);
|
||||
return DAG.getNode(ISD::ADD, SDLoc(N), VT, Shl0, Shl1);
|
||||
|
@ -93,6 +93,19 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
|
||||
// ISD Namespace
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
|
||||
auto *BV = dyn_cast<BuildVectorSDNode>(N);
|
||||
if (!BV)
|
||||
return false;
|
||||
|
||||
APInt SplatUndef;
|
||||
unsigned SplatBitSize;
|
||||
bool HasUndefs;
|
||||
EVT EltVT = N->getValueType(0).getVectorElementType();
|
||||
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) &&
|
||||
EltVT.getSizeInBits() >= SplatBitSize;
|
||||
}
|
||||
|
||||
// FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be
|
||||
// specializations of the more general isConstantSplatVector()?
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user