Fold (trunc (srl x, c)) -> (srl (trunc x), c)
authorChris Lattner <sabre@nondot.org>
Sat, 6 May 2006 00:11:52 +0000 (00:11 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 6 May 2006 00:11:52 +0000 (00:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28138 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/TargetLowering.cpp

index 30ef67256f40056eb0dd72f2a321719b0be2f8b4..37fd2e304742da8f047fd0d1294357d3ca0dce71 100644 (file)
@@ -608,9 +608,41 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
     break;
   }
   case ISD::TRUNCATE: {
+    // Simplify the input, using demanded bit information, and compute the known
+    // zero/one bits live out.
     if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask,
                              KnownZero, KnownOne, TLO, Depth+1))
       return true;
+    
+    // If the input is only used by this truncate, see if we can shrink it based
+    // on the known demanded bits.
+    if (Op.getOperand(0).Val->hasOneUse()) {
+      SDOperand In = Op.getOperand(0);
+      switch (In.getOpcode()) {
+      default: break;
+      case ISD::SRL:
+        // Shrink SRL by a constant if none of the high bits shifted in are
+        // demanded.
+        if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(In.getOperand(1))){
+          uint64_t HighBits = MVT::getIntVTBitMask(In.getValueType());
+          HighBits &= ~MVT::getIntVTBitMask(Op.getValueType());
+          HighBits >>= ShAmt->getValue();
+          
+          if (ShAmt->getValue() < MVT::getSizeInBits(Op.getValueType()) &&
+              (DemandedMask & HighBits) == 0) {
+            // None of the shifted in bits are needed.  Add a truncate of the
+            // shift input, then shift it.
+            SDOperand NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, 
+                                                 Op.getValueType(), 
+                                                 In.getOperand(0));
+            return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL,Op.getValueType(),
+                                                   NewTrunc, In.getOperand(1)));
+          }
+        }
+        break;
+      }
+    }
+    
     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 
     uint64_t OutMask = MVT::getIntVTBitMask(Op.getValueType());
     KnownZero &= OutMask;