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

Chris Lattner sabre at nondot.org
Sun Feb 25 19:14:16 PST 2007



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.270 -> 1.271
---
Log message:

Fold (sext (truncate x)) more aggressively, by avoiding creation of a
sextinreg if not needed.   This is useful in two cases: before legalize,
it avoids creating a sextinreg that will be trivially removed.  After legalize
if the target doesn't support sextinreg, the trunc/sext would not have been
removed before.


---
Diffs of the changes:  (+34 -10)

 DAGCombiner.cpp |   44 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 34 insertions(+), 10 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.270 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.271
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.270	Thu Feb  8 16:13:59 2007
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Sun Feb 25 21:13:59 2007
@@ -1940,18 +1940,42 @@
   if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
     return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0));
   
-  // fold (sext (truncate x)) -> (sextinreg x).
-  if (N0.getOpcode() == ISD::TRUNCATE && 
-      (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG,
-                                              N0.getValueType()))) {
+  if (N0.getOpcode() == ISD::TRUNCATE) {
+    // See if the value being truncated is already sign extended.  If so, just
+    // eliminate the trunc/sext pair.
     SDOperand Op = N0.getOperand(0);
-    if (Op.getValueType() < VT) {
-      Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op);
-    } else if (Op.getValueType() > VT) {
-      Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
+    unsigned OpBits   = MVT::getSizeInBits(Op.getValueType());
+    unsigned MidBits  = MVT::getSizeInBits(N0.getValueType());
+    unsigned DestBits = MVT::getSizeInBits(VT);
+    unsigned NumSignBits = TLI.ComputeNumSignBits(Op);
+    
+    if (OpBits == DestBits) {
+      // Op is i32, Mid is i8, and Dest is i32.  If Op has more than 24 sign
+      // bits, it is already ready.
+      if (NumSignBits > DestBits-MidBits)
+        return Op;
+    } else if (OpBits < DestBits) {
+      // Op is i32, Mid is i8, and Dest is i64.  If Op has more than 24 sign
+      // bits, just sext from i32.
+      if (NumSignBits > OpBits-MidBits)
+        return DAG.getNode(ISD::SIGN_EXTEND, VT, Op);
+    } else {
+      // Op is i64, Mid is i8, and Dest is i32.  If Op has more than 56 sign
+      // bits, just truncate to i32.
+      if (NumSignBits > OpBits-MidBits)
+        return DAG.getNode(ISD::TRUNCATE, VT, Op);
+    }
+    
+    // fold (sext (truncate x)) -> (sextinreg x).
+    if (!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG,
+                                               N0.getValueType())) {
+      if (Op.getValueType() < VT)
+        Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op);
+      else if (Op.getValueType() > VT)
+        Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
+      return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
+                         DAG.getValueType(N0.getValueType()));
     }
-    return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op,
-                       DAG.getValueType(N0.getValueType()));
   }
   
   // fold (sext (load x)) -> (sext (truncate (sextload x)))






More information about the llvm-commits mailing list