[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp

Nate Begeman natebegeman at mac.com
Tue Nov 22 10:16:12 PST 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.214 -> 1.215
SelectionDAG.cpp updated: 1.214 -> 1.215
SelectionDAGISel.cpp updated: 1.104 -> 1.105
---
Log message:

Check in code to scalarize arbitrarily wide packed types for some simple
vector operations (load, add, sub, mul).

This allows us to codegen:
void %foo(<4 x float> * %a) {
entry:
  %tmp1 = load <4 x float> * %a;
  %tmp2 = add <4 x float> %tmp1, %tmp1
  store <4 x float> %tmp2, <4 x float> *%a
  ret void
}

on ppc as:
_foo:
        lfs f0, 12(r3)
        lfs f1, 8(r3)
        lfs f2, 4(r3)
        lfs f3, 0(r3)
        fadds f0, f0, f0
        fadds f1, f1, f1
        fadds f2, f2, f2
        fadds f3, f3, f3
        stfs f0, 12(r3)
        stfs f1, 8(r3)
        stfs f2, 4(r3)
        stfs f3, 0(r3)
        blr


---
Diffs of the changes:  (+81 -5)

 LegalizeDAG.cpp      |   82 +++++++++++++++++++++++++++++++++++++++++++++++++--
 SelectionDAG.cpp     |    2 -
 SelectionDAGISel.cpp |    2 -
 3 files changed, 81 insertions(+), 5 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.214 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.215
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.214	Mon Nov 21 19:29:36 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Tue Nov 22 12:16:00 2005
@@ -1121,6 +1121,7 @@
 
     case Expand:
       SDOperand Lo, Hi;
+      unsigned IncrementSize;
       ExpandOp(Node->getOperand(1), Lo, Hi);
 
       if (!TLI.isLittleEndian())
@@ -1128,7 +1129,16 @@
 
       Lo = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2,
                        Node->getOperand(3));
-      unsigned IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
+      // If this is a vector type, then we have to calculate the increment as
+      // the product of the element size in bytes, and the number of elements
+      // in the high half of the vector.
+      if (MVT::Vector == Hi.getValueType()) {
+        unsigned NumElems = cast<ConstantSDNode>(Hi.getOperand(2))->getValue();
+        MVT::ValueType EVT = cast<VTSDNode>(Hi.getOperand(3))->getVT();
+        IncrementSize = NumElems * MVT::getSizeInBits(EVT)/8;
+      } else {
+        IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
+      }
       Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
                          getIntPtrConstant(IncrementSize));
       assert(isTypeLegal(Tmp2.getValueType()) &&
@@ -3001,8 +3011,9 @@
   MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
   SDNode *Node = Op.Val;
   assert(getTypeAction(VT) == Expand && "Not an expanded type!");
-  assert(MVT::isInteger(VT) && "Cannot expand FP values!");
-  assert(MVT::isInteger(NVT) && NVT < VT &&
+  assert((MVT::isInteger(VT) || VT == MVT::Vector) && 
+         "Cannot expand FP values!");
+  assert(((MVT::isInteger(NVT) && NVT < VT) || VT == MVT::Vector) &&
          "Cannot expand to FP value or to larger int value!");
 
   // See if we already expanded it.
@@ -3107,6 +3118,71 @@
       std::swap(Lo, Hi);
     break;
   }
+  case ISD::VLOAD: {
+    SDOperand Ch = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
+    SDOperand Ptr = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+    unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(2))->getValue();
+    MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
+    
+    // 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));
+      // Increment the pointer to the other half.
+      unsigned IncrementSize = MVT::getSizeInBits(EVT)/8;
+      Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                        getIntPtrConstant(IncrementSize));
+      //Is this safe?  declaring that the two parts of the split load
+      //are from the same instruction?
+      Hi = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4));
+    } else {
+      NumElements /= 2; // Split the vector in half
+      Lo = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4));
+      unsigned IncrementSize = NumElements * MVT::getSizeInBits(EVT)/8;
+      Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                        getIntPtrConstant(IncrementSize));
+      //Is this safe?  declaring that the two parts of the split load
+      //are from the same instruction?
+      Hi = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4));
+    }
+    
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                               Hi.getValue(1));
+    
+    // Remember that we legalized the chain.
+    AddLegalizedOperand(Op.getValue(1), TF);
+    if (!TLI.isLittleEndian())
+      std::swap(Lo, Hi);
+    break;
+  }
+  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();
+    SDOperand LL, LH, RL, RH;
+    
+    ExpandOp(Node->getOperand(0), LL, LH);
+    ExpandOp(Node->getOperand(1), 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);
+    } 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));
+    }
+    break;
+  }
   case ISD::TAILCALL:
   case ISD::CALL: {
     SDOperand Chain  = LegalizeOp(Node->getOperand(0));  // Legalize the chain.


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.214 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.215
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.214	Fri Nov 18 19:44:53 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Tue Nov 22 12:16:00 2005
@@ -1106,7 +1106,7 @@
   Ops.push_back(SV);
   std::vector<MVT::ValueType> VTs;
   VTs.reserve(2);
-  VTs.push_back(EVT); VTs.push_back(MVT::Other);  // Add token chain.
+  VTs.push_back(MVT::Vector); VTs.push_back(MVT::Other);  // Add token chain.
   return getNode(ISD::VLOAD, VTs, Ops);
 }
 


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.104 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.105
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.104	Mon Nov 21 19:29:36 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Tue Nov 22 12:16:00 2005
@@ -528,7 +528,7 @@
     } else {
       SDOperand Num = DAG.getConstant(NumElements, MVT::i32);
       SDOperand Typ = DAG.getValueType(PVT);
-      setValue(&I, DAG.getNode(VecOp, Op1.getValueType(), Num, Typ, Op1, Op2));
+      setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
     }
   }
 }






More information about the llvm-commits mailing list