mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-03 10:19:25 +00:00
Vector ops lowering.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26436 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f338dd881f
commit
860771d2d8
@ -663,7 +663,7 @@ SDOperand DAGCombiner::visitADD(SDNode *N) {
|
||||
if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1))
|
||||
return N1.getOperand(0);
|
||||
//
|
||||
if (SimplifyDemandedBits(SDOperand(N, 0)))
|
||||
if (!MVT::isVector(VT) && SimplifyDemandedBits(SDOperand(N, 0)))
|
||||
return SDOperand();
|
||||
return SDOperand();
|
||||
}
|
||||
|
@ -1306,8 +1306,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
// in the high half of the vector.
|
||||
unsigned IncrementSize;
|
||||
if (MVT::Vector == Hi.getValueType()) {
|
||||
unsigned NumElems = cast<ConstantSDNode>(Hi.getOperand(2))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Hi.getOperand(3))->getVT();
|
||||
unsigned NumElems = cast<ConstantSDNode>(Hi.getOperand(0))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Hi.getOperand(1))->getVT();
|
||||
IncrementSize = NumElems * MVT::getSizeInBits(EVT)/8;
|
||||
} else {
|
||||
IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
|
||||
@ -3529,25 +3529,39 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT);
|
||||
break;
|
||||
}
|
||||
case ISD::ConstantVec: {
|
||||
unsigned NumElements = Node->getNumOperands();
|
||||
// If we only have two elements left in the constant vector, just break it
|
||||
// apart into the two scalar constants it contains. Otherwise, bisect the
|
||||
// ConstantVec, and return each half as a new ConstantVec.
|
||||
// FIXME: this is hard coded as big endian, it may have to change to support
|
||||
// SSE and Alpha MVI
|
||||
if (NumElements == 2) {
|
||||
Hi = Node->getOperand(0);
|
||||
Lo = Node->getOperand(1);
|
||||
case ISD::VConstant: {
|
||||
unsigned NumElements =
|
||||
cast<ConstantSDNode>(Node->getOperand(0))->getValue() / 2;
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
||||
MVT::ValueType TVT = (NumElements > 1)
|
||||
? getVectorType(EVT, NumElements) : EVT;
|
||||
// If type of bisected vector is legal, turn it into a ConstantVec (which
|
||||
// will be lowered to a ConstantPool or something else). Otherwise, bisect
|
||||
// the VConstant, and return each half as a new VConstant.
|
||||
unsigned Opc = ISD::ConstantVec;
|
||||
std::vector<SDOperand> LoOps, HiOps;
|
||||
if (!(TVT != MVT::Other &&
|
||||
(!MVT::isVector(TVT) || TLI.isTypeLegal(TVT)))) {
|
||||
Opc = ISD::VConstant;
|
||||
TVT = MVT::Vector;
|
||||
SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
|
||||
SDOperand Typ = DAG.getValueType(EVT);
|
||||
HiOps.push_back(Num);
|
||||
HiOps.push_back(Typ);
|
||||
LoOps.push_back(Num);
|
||||
LoOps.push_back(Typ);
|
||||
}
|
||||
|
||||
if (NumElements == 1) {
|
||||
Hi = Node->getOperand(2);
|
||||
Lo = Node->getOperand(3);
|
||||
} else {
|
||||
NumElements /= 2;
|
||||
std::vector<SDOperand> LoOps, HiOps;
|
||||
for (unsigned I = 0, E = NumElements; I < E; ++I) {
|
||||
HiOps.push_back(Node->getOperand(I));
|
||||
LoOps.push_back(Node->getOperand(I+NumElements));
|
||||
HiOps.push_back(Node->getOperand(I+2));
|
||||
LoOps.push_back(Node->getOperand(I+2+NumElements));
|
||||
}
|
||||
Lo = DAG.getNode(ISD::ConstantVec, MVT::Vector, LoOps);
|
||||
Hi = DAG.getNode(ISD::ConstantVec, MVT::Vector, HiOps);
|
||||
Hi = DAG.getNode(Opc, TVT, HiOps);
|
||||
Lo = DAG.getNode(Opc, TVT, LoOps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3652,22 +3666,25 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
break;
|
||||
}
|
||||
case ISD::VLOAD: {
|
||||
SDOperand Ch = Node->getOperand(0); // Legalize the chain.
|
||||
SDOperand Ptr = Node->getOperand(1); // Legalize the pointer.
|
||||
unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(2))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
|
||||
SDOperand Ch = Node->getOperand(2); // Legalize the chain.
|
||||
SDOperand Ptr = Node->getOperand(3); // Legalize the pointer.
|
||||
unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(0))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
||||
MVT::ValueType TVT = (NumElements/2 > 1)
|
||||
? getVectorType(EVT, NumElements/2) : EVT;
|
||||
|
||||
// If we only have two elements, turn into a pair of scalar loads.
|
||||
// FIXME: handle case where a vector of two elements is fine, such as
|
||||
// 2 x double on SSE2.
|
||||
if (NumElements == 2) {
|
||||
Lo = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4));
|
||||
// If type of split vector is legal, turn into a pair of scalar or
|
||||
// packed loads.
|
||||
if (TVT != MVT::Other &&
|
||||
(!MVT::isVector(TVT) ||
|
||||
(TLI.isTypeLegal(TVT) && TLI.isOperationLegal(ISD::LOAD, TVT)))) {
|
||||
Lo = DAG.getLoad(TVT, Ch, Ptr, Node->getOperand(4));
|
||||
// Increment the pointer to the other half.
|
||||
unsigned IncrementSize = MVT::getSizeInBits(EVT)/8;
|
||||
unsigned IncrementSize = MVT::getSizeInBits(TVT)/8;
|
||||
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
|
||||
getIntPtrConstant(IncrementSize));
|
||||
// FIXME: This creates a bogus srcvalue!
|
||||
Hi = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4));
|
||||
Hi = DAG.getLoad(TVT, Ch, Ptr, Node->getOperand(4));
|
||||
} else {
|
||||
NumElements /= 2; // Split the vector in half
|
||||
Lo = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4));
|
||||
@ -3692,25 +3709,28 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
case ISD::VADD:
|
||||
case ISD::VSUB:
|
||||
case ISD::VMUL: {
|
||||
unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(2))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
|
||||
unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(0))->getValue();
|
||||
MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
||||
MVT::ValueType TVT = (NumElements/2 > 1)
|
||||
? getVectorType(EVT, NumElements/2) : EVT;
|
||||
SDOperand LL, LH, RL, RH;
|
||||
|
||||
ExpandOp(Node->getOperand(0), LL, LH);
|
||||
ExpandOp(Node->getOperand(1), RL, RH);
|
||||
ExpandOp(Node->getOperand(2), LL, LH);
|
||||
ExpandOp(Node->getOperand(3), RL, RH);
|
||||
|
||||
// If we only have two elements, turn into a pair of scalar loads.
|
||||
// FIXME: handle case where a vector of two elements is fine, such as
|
||||
// 2 x double on SSE2.
|
||||
if (NumElements == 2) {
|
||||
unsigned Opc = getScalarizedOpcode(Node->getOpcode(), EVT);
|
||||
Lo = DAG.getNode(Opc, EVT, LL, RL);
|
||||
Hi = DAG.getNode(Opc, EVT, LH, RH);
|
||||
// If type of split vector is legal, turn into a pair of scalar / packed
|
||||
// ADD, SUB, or MUL.
|
||||
unsigned Opc = getScalarizedOpcode(Node->getOpcode(), EVT);
|
||||
if (TVT != MVT::Other &&
|
||||
(!MVT::isVector(TVT) ||
|
||||
(TLI.isTypeLegal(TVT) && TLI.isOperationLegal(Opc, TVT)))) {
|
||||
Lo = DAG.getNode(Opc, TVT, LL, RL);
|
||||
Hi = DAG.getNode(Opc, TVT, LH, RH);
|
||||
} else {
|
||||
Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, LL, RL, LL.getOperand(2),
|
||||
LL.getOperand(3));
|
||||
Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, LH, RH, LH.getOperand(2),
|
||||
LH.getOperand(3));
|
||||
SDOperand Num = DAG.getConstant(NumElements/2, MVT::i32);
|
||||
SDOperand Typ = DAG.getValueType(EVT);
|
||||
Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, Num, Typ, LL, RL);
|
||||
Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, Num, Typ, LH, RH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -415,7 +415,11 @@ public:
|
||||
} else {
|
||||
// If the packed type isn't legal, then create a ConstantVec node with
|
||||
// generic Vector type instead.
|
||||
return N = DAG.getNode(ISD::ConstantVec, MVT::Vector, Ops);
|
||||
SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
|
||||
SDOperand Typ = DAG.getValueType(PVT);
|
||||
Ops.insert(Ops.begin(), Typ);
|
||||
Ops.insert(Ops.begin(), Num);
|
||||
return N = DAG.getNode(ISD::VConstant, MVT::Vector, Ops);
|
||||
}
|
||||
} else {
|
||||
// Canonicalize all constant ints to be unsigned.
|
||||
@ -668,12 +672,13 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned IntOp, unsigned FPOp,
|
||||
unsigned Opc = MVT::isFloatingPoint(PVT) ? FPOp : IntOp;
|
||||
if (NumElements == 1) {
|
||||
setValue(&I, DAG.getNode(Opc, PVT, Op1, Op2));
|
||||
} else if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
|
||||
} else if (TVT != MVT::Other &&
|
||||
TLI.isTypeLegal(TVT) && TLI.isOperationLegal(Opc, TVT)) {
|
||||
setValue(&I, DAG.getNode(Opc, TVT, Op1, Op2));
|
||||
} else {
|
||||
SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
|
||||
SDOperand Typ = DAG.getValueType(PVT);
|
||||
setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
|
||||
setValue(&I, DAG.getNode(VecOp, MVT::Vector, Num, Typ, Op1, Op2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -905,7 +910,8 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
|
||||
// the Legalize pass does not have to deal with them.
|
||||
if (NumElements == 1) {
|
||||
L = DAG.getLoad(PVT, Root, Ptr, DAG.getSrcValue(I.getOperand(0)));
|
||||
} else if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
|
||||
} else if (TVT != MVT::Other &&
|
||||
TLI.isTypeLegal(TVT) && TLI.isOperationLegal(ISD::LOAD, TVT)) {
|
||||
L = DAG.getLoad(TVT, Root, Ptr, DAG.getSrcValue(I.getOperand(0)));
|
||||
} else {
|
||||
L = DAG.getVecLoad(NumElements, PVT, Root, Ptr,
|
||||
|
Loading…
Reference in New Issue
Block a user