[llvm-commits] [llvm] r45762 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/longlong-deadload.ll

Chris Lattner sabre at nondot.org
Tue Jan 8 15:08:09 PST 2008


Author: lattner
Date: Tue Jan  8 17:08:06 2008
New Revision: 45762

URL: http://llvm.org/viewvc/llvm-project?rev=45762&view=rev
Log:
Make load->store deletion a bit smarter.  This allows us to compile this:

void test(long long *P) { *P ^= 1; }

into just:

_test:
	movl	4(%esp), %eax
	xorl	$1, (%eax)
	ret

instead of code like this:

_test:
	movl	4(%esp), %ecx
        xorl    $1, (%ecx)
	movl	4(%ecx), %edx
	movl	%edx, 4(%ecx)
	ret


Added:
    llvm/trunk/test/CodeGen/X86/longlong-deadload.ll
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=45762&r1=45761&r2=45762&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jan  8 17:08:06 2008
@@ -4122,6 +4122,34 @@
   return SDOperand();
 }
 
+/// ReachesChainWithoutSideEffects - Do a little local search to see if Src can
+/// reach Dest without any side effects like a store, or call.  Non-volatile
+/// loads are ok though.
+static bool ReachesChainWithoutSideEffects(SDOperand Src, SDOperand Dest,
+                                           unsigned Depth = 0) {
+  if (Src == Dest) return true;
+  
+  // Don't search too deeply, we just want to be able to see through
+  // TokenFactor's etc.
+  if (Depth == 2) return false;
+  
+  // If this is a token factor, all inputs to the TF happen in parallel.  If any
+  // of the operands of the TF reach dest, then we can do the xform.
+  if (Src.getOpcode() == ISD::TokenFactor) {
+    for (unsigned i = 0, e = Src.getNumOperands(); i != e; ++i)
+      if (ReachesChainWithoutSideEffects(Src.getOperand(i), Dest, Depth+1))
+        return true;
+    return false;
+  }
+  
+  // Loads don't have side effects, look through them.
+  if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Src)) {
+    if (!Ld->isVolatile())
+      return ReachesChainWithoutSideEffects(Ld->getChain(), Dest, Depth+1);
+  }
+  return false;
+}
+
 SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   StoreSDNode *ST  = cast<StoreSDNode>(N);
   SDOperand Chain = ST->getChain();
@@ -4250,10 +4278,12 @@
   // If this is a load followed by a store to the same location, then the store
   // is dead/noop.
   if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Value)) {
-    if (Chain.Val == Ld && Ld->getBasePtr() == Ptr &&
+    if (Ld->getBasePtr() == Ptr && ST->getStoredVT() == Ld->getLoadedVT() &&
         ST->getAddressingMode() == ISD::UNINDEXED &&
-        ST->getStoredVT() == Ld->getLoadedVT() &&
-        !ST->isVolatile()) {
+        !ST->isVolatile() &&
+        // There can't be any side effects between the load and store, such as
+        // a call or store.
+        ReachesChainWithoutSideEffects(Chain, SDOperand(Ld, 1))) {
       // The store is dead, remove it.
       return Chain;
     }

Added: llvm/trunk/test/CodeGen/X86/longlong-deadload.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/longlong-deadload.ll?rev=45762&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/longlong-deadload.ll (added)
+++ llvm/trunk/test/CodeGen/X86/longlong-deadload.ll Tue Jan  8 17:08:06 2008
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | llc -march=x86 | not grep '4{(%...)}
+; This should not load or store the top part of *P.
+
+define void @test(i64* %P) nounwind  {
+entry:
+	%tmp1 = load i64* %P, align 8		; <i64> [#uses=1]
+	%tmp2 = xor i64 %tmp1, 1		; <i64> [#uses=1]
+	store i64 %tmp2, i64* %P, align 8
+	ret void
+}
+





More information about the llvm-commits mailing list