[llvm-commits] [llvm] r42954 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Chris Lattner sabre at nondot.org
Fri Oct 12 23:58:48 PDT 2007


Author: lattner
Date: Sat Oct 13 01:58:48 2007
New Revision: 42954

URL: http://llvm.org/viewvc/llvm-project?rev=42954&view=rev
Log:
Enhance the truncstore optimization code to handle shifted
values and propagate demanded bits through them in simple cases.

This allows this code:
void foo(char *P) {
   strcpy(P, "abc");
}
to compile to:

_foo:
        ldrb r3, [r1]
        ldrb r2, [r1, #+1]
        ldrb r12, [r1, #+2]!
        ldrb r1, [r1, #+1]
        strb r1, [r0, #+3]
        strb r2, [r0, #+1]
        strb r12, [r0, #+2]
        strb r3, [r0]
        bx lr

instead of:

_foo:
        ldrb r3, [r1, #+3]
        ldrb r2, [r1, #+2]
        orr r3, r2, r3, lsl #8
        ldrb r2, [r1, #+1]
        ldrb r1, [r1]
        orr r2, r1, r2, lsl #8
        orr r3, r2, r3, lsl #16
        strb r3, [r0]
        mov r2, r3, lsr #24
        strb r2, [r0, #+3]
        mov r2, r3, lsr #16
        strb r2, [r0, #+2]
        mov r3, r3, lsr #8
        strb r3, [r0, #+1]
        bx lr

testcase here: test/CodeGen/ARM/truncstore-dag-combine.ll

This also helps occasionally for X86 and other cases not involving 
unaligned load/stores.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=42954&r1=42953&r2=42954&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Oct 13 01:58:48 2007
@@ -156,10 +156,10 @@
     /// SimplifyDemandedBits - Check the specified integer node value to see if
     /// it can be simplified or if things it uses can be simplified by bit
     /// propagation.  If so, return true.
-    bool SimplifyDemandedBits(SDOperand Op) {
+    bool SimplifyDemandedBits(SDOperand Op, uint64_t Demanded = ~0ULL) {
       TargetLowering::TargetLoweringOpt TLO(DAG);
       uint64_t KnownZero, KnownOne;
-      uint64_t Demanded = MVT::getIntVTBitMask(Op.getValueType());
+      Demanded &= MVT::getIntVTBitMask(Op.getValueType());
       if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
         return false;
 
@@ -2809,6 +2809,20 @@
     if (DAG.MaskedValueIsZero(V.getOperand(1), Mask))
       return V.getOperand(0);
     break;
+  case ISD::SRL:
+    // Only look at single-use SRLs.
+    if (!V.Val->hasOneUse())
+      break;
+    if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
+      // See if we can recursively simplify the LHS.
+      unsigned Amt = RHSC->getValue();
+      Mask = (Mask << Amt) & MVT::getIntVTBitMask(V.getValueType());
+      SDOperand SimplifyLHS = GetDemandedBits(V.getOperand(0), Mask);
+      if (SimplifyLHS.Val) {
+        return DAG.getNode(ISD::SRL, V.getValueType(), 
+                           SimplifyLHS, V.getOperand(1));
+      }
+    }
   }
   return SDOperand();
 }
@@ -4040,6 +4054,11 @@
       return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(),
                                ST->getSrcValueOffset(), ST->getStoredVT(),
                                ST->isVolatile(), ST->getAlignment());
+    
+    // Otherwise, see if we can simplify the operation with
+    // SimplifyDemandedBits, which only works if the value has a single use.
+    if (SimplifyDemandedBits(Value, MVT::getIntVTBitMask(ST->getStoredVT())))
+      return SDOperand(N, 0);
   }
   
   return SDOperand();





More information about the llvm-commits mailing list