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

Nate Begeman natebegeman at mac.com
Wed Apr 6 14:13:25 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.74 -> 1.75
---
Log message:

Teach ExpandShift how to handle shifts by a constant.  This allows targets
like PowerPC to codegen long shifts in many fewer instructions.


---
Diffs of the changes:  (+64 -8)

 LegalizeDAG.cpp |   72 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 64 insertions(+), 8 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.74 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.75
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.74	Tue Apr  5 19:23:54 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Wed Apr  6 16:13:14 2005
@@ -1412,13 +1412,73 @@
 /// low-parts expanded into Lo and Hi.
 bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt,
                                        SDOperand &Lo, SDOperand &Hi) {
-  // FIXME: This code is buggy, disable it for now.  Note that we should at
-  // least handle the case when Amt is an immediate here.
-  return false;
-
   assert((Opc == ISD::SHL || Opc == ISD::SRA || Opc == ISD::SRL) &&
          "This is not a shift!");
+
   MVT::ValueType NVT = TLI.getTypeToTransformTo(Op.getValueType());
+  SDOperand ShAmt = LegalizeOp(Amt);
+  MVT::ValueType ShTy = ShAmt.getValueType();
+  unsigned VTBits = MVT::getSizeInBits(Op.getValueType());
+  unsigned NVTBits = MVT::getSizeInBits(NVT);
+
+  // Handle the case when Amt is an immediate.  Other cases are currently broken
+  // and are disabled.
+  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Amt.Val)) {
+    unsigned Cst = CN->getValue();
+    // Expand the incoming operand to be shifted, so that we have its parts
+    SDOperand InL, InH;
+    ExpandOp(Op, InL, InH);
+    switch(Opc) {
+    case ISD::SHL:
+      if (Cst > VTBits) {
+        Lo = DAG.getConstant(0, NVT);
+        Hi = DAG.getConstant(0, NVT);
+      } else if (Cst > NVTBits) {
+        Lo = DAG.getConstant(0, NVT);
+        Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy));
+      } else {
+        Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst, ShTy));
+        Hi = DAG.getNode(ISD::OR, NVT,
+           DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(Cst, ShTy)),
+           DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(NVTBits-Cst, ShTy)));
+      }
+      return true;
+    case ISD::SRL:
+      if (Cst > VTBits) {
+        Lo = DAG.getConstant(0, NVT);
+        Hi = DAG.getConstant(0, NVT);
+      } else if (Cst > NVTBits) {
+        Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst-NVTBits,ShTy));
+        Hi = DAG.getConstant(0, NVT);
+      } else {
+        Lo = DAG.getNode(ISD::OR, NVT,
+           DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)),
+           DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy)));
+        Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst, ShTy));
+      }
+      return true;
+    case ISD::SRA:
+      if (Cst > VTBits) {
+        Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, 
+                              DAG.getConstant(NVTBits-1, ShTy));
+      } else if (Cst > NVTBits) {
+        Lo = DAG.getNode(ISD::SRA, NVT, InH, 
+                           DAG.getConstant(Cst-NVTBits, ShTy));
+        Hi = DAG.getNode(ISD::SRA, NVT, InH, 
+                              DAG.getConstant(NVTBits-1, ShTy));
+      } else {
+        Lo = DAG.getNode(ISD::OR, NVT,
+           DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)),
+           DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy)));
+        Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Cst, ShTy));
+      }
+      return true;
+    }
+  }
+  // FIXME: The following code for expanding shifts using ISD::SELECT is buggy,
+  // so disable it for now.  Currently targets are handling this via SHL_PARTS
+  // and friends.
+  return false;
 
   // If we have an efficient select operation (or if the selects will all fold
   // away), lower to some complex code, otherwise just emit the libcall.
@@ -1428,10 +1488,6 @@
 
   SDOperand InL, InH;
   ExpandOp(Op, InL, InH);
-  SDOperand ShAmt = LegalizeOp(Amt);
-  MVT::ValueType ShTy = ShAmt.getValueType();
-  
-  unsigned NVTBits = MVT::getSizeInBits(NVT);
   SDOperand NAmt = DAG.getNode(ISD::SUB, ShTy,           // NAmt = 32-ShAmt
                                DAG.getConstant(NVTBits, ShTy), ShAmt);
 






More information about the llvm-commits mailing list