diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-11-19 00:36:38 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-11-19 00:36:38 +0000 |
commit | 5fbb5d2459a5410590f285250faa604576308a93 (patch) | |
tree | ccb623e7f9965907ac76987d1e0964967b61f766 /lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | |
parent | 06a40438722a4889abd239efbd6c1bf4bbbee85b (diff) |
Teach LLVM how to scalarize packed types. Currently, this only works on
packed types with an element count of 1, although more generic support is
coming. This allows LLVM to turn the following code:
void %foo(<1 x float> * %a) {
entry:
%tmp1 = load <1 x float> * %a;
%tmp2 = add <1 x float> %tmp1, %tmp1
store <1 x float> %tmp2, <1 x float> *%a
ret void
}
Into:
_foo:
lfs f0, 0(r3)
fadds f0, f0, f0
stfs f0, 0(r3)
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24416 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 7b453a282b..135f58fba5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -149,6 +149,15 @@ private: }; } +static unsigned scalarizedOpcode(unsigned VecOp, MVT::ValueType VT) { + switch (VecOp) { + default: assert(0 && "Don't know how to scalarize this opcode!"); + break; + case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD; + case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB; + case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL; + } +} SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) : TLI(dag.getTargetLoweringInfo()), DAG(dag), @@ -914,7 +923,27 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 0), Result); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - + + case ISD::VLOAD: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + // If we just have one element, scalarize the result. Otherwise, check to + // see if we support this operation on this type at this width. If not, + // split the vector in half and try again. + if (1 == cast<ConstantSDNode>(Node->getOperand(2))->getValue()) { + MVT::ValueType SVT = cast<VTSDNode>(Node->getOperand(3))->getVT(); + Result = LegalizeOp(DAG.getLoad(SVT, Tmp1, Tmp2, Node->getOperand(4))); + } else { + assert(0 && "Expand case for vectors unimplemented"); + } + + // Since loads produce two values, make sure to remember that we legalized + // both of them. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: { @@ -1654,6 +1683,28 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2); break; + // Vector binary operators + case ISD::VADD: + case ISD::VSUB: + case ISD::VMUL: { + Tmp1 = Node->getOperand(0); // Element Count + Tmp2 = Node->getOperand(1); // Element Type + + // If we just have one element, scalarize the result. Otherwise, check to + // see if we support this operation on this type at this width. If not, + // split the vector in half and try again. + if (1 == cast<ConstantSDNode>(Tmp1)->getValue()) { + MVT::ValueType SVT = cast<VTSDNode>(Tmp2)->getVT(); + + Result = DAG.getNode(scalarizedOpcode(Node->getOpcode(), SVT), SVT, + LegalizeOp(Node->getOperand(2)), + LegalizeOp(Node->getOperand(3))); + } else { + assert(0 && "Expand case for vectors unimplemented"); + } + break; + } + case ISD::BUILD_PAIR: { MVT::ValueType PairTy = Node->getValueType(0); // TODO: handle the case where the Lo and Hi operands are not of legal type |