[llvm-commits] [llvm] r144705 - in /llvm/trunk: lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/dec-eflags-lower.ll

Pete Cooper peter_cooper at apple.com
Tue Nov 15 13:57:53 PST 2011


Author: pete
Date: Tue Nov 15 15:57:53 2011
New Revision: 144705

URL: http://llvm.org/viewvc/llvm-project?rev=144705&view=rev
Log:
Added custom lowering for load->dec->store sequence in x86 when the EFLAGS registers is used
by later instructions.

Only done for DEC64m right now.

Fixes <rdar://problem/6172640>

Added:
    llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=144705&r1=144704&r2=144705&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Tue Nov 15 15:57:53 2011
@@ -948,6 +948,11 @@
     if (!TII->unfoldMemoryOperand(*DAG, N, NewNodes))
       return NULL;
 
+    // unfolding an x86 DEC64m operation results in store, dec, load which
+    // can't be handled here so quit
+    if (NewNodes.size() == 3)
+      return NULL;
+
     DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
     assert(NewNodes.size() == 2 && "Expected a load folding node!");
 

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=144705&r1=144704&r2=144705&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Nov 15 15:57:53 2011
@@ -2216,6 +2216,63 @@
     }
     break;
   }
+  case ISD::STORE: {
+    StoreSDNode *StoreNode = cast<StoreSDNode>(Node);
+    SDValue Chain = StoreNode->getOperand(0);
+    SDValue StoredVal = StoreNode->getOperand(1);
+    SDValue Address = StoreNode->getOperand(2);
+    SDValue Undef = StoreNode->getOperand(3);
+
+    if (StoreNode->getMemOperand()->getSize() != 8 ||
+        Undef->getOpcode() != ISD::UNDEF ||
+        Chain->getOpcode() != ISD::LOAD ||
+        StoredVal->getOpcode() != X86ISD::DEC ||
+        StoredVal.getResNo() != 0 ||
+        StoredVal->getOperand(0).getNode() != Chain.getNode())
+      break;
+
+    //OPC_CheckPredicate, 1, // Predicate_nontemporalstore
+    if (StoreNode->isNonTemporal())
+      break;
+
+    LoadSDNode *LoadNode = cast<LoadSDNode>(Chain.getNode());
+    if (LoadNode->getOperand(1) != Address ||
+        LoadNode->getOperand(2) != Undef)
+      break;
+
+    if (!ISD::isNormalLoad(LoadNode))
+      break;
+
+    if (!ISD::isNormalStore(StoreNode))
+      break;
+
+    // check load chain has only one use (from the store)
+    if (!Chain.hasOneUse())
+      break;
+
+    // Merge the input chains if they are not intra-pattern references.
+    SDValue InputChain = LoadNode->getOperand(0);
+
+    SDValue Base, Scale, Index, Disp, Segment;
+    if (!SelectAddr(LoadNode, LoadNode->getBasePtr(),
+                    Base, Scale, Index, Disp, Segment))
+      break;
+
+    MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(2);
+    MemOp[0] = StoreNode->getMemOperand();
+    MemOp[1] = LoadNode->getMemOperand();
+    const SDValue Ops[] = { Base, Scale, Index, Disp, Segment, InputChain };
+    MachineSDNode *Result = CurDAG->getMachineNode(X86::DEC64m,
+                                                   Node->getDebugLoc(),
+                                                   MVT::i32, MVT::Other, Ops,
+                                                   array_lengthof(Ops));
+    Result->setMemRefs(MemOp, MemOp + 2);
+
+    ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
+    ReplaceUses(SDValue(StoredVal.getNode(), 1), SDValue(Result, 0));
+
+    return Result;
+  }
   }
 
   SDNode *ResNode = SelectCode(Node);

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=144705&r1=144704&r2=144705&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Nov 15 15:57:53 2011
@@ -8263,8 +8263,10 @@
     // climbing the DAG back to the root, and it doesn't seem to be worth the
     // effort.
     for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
-           UE = Op.getNode()->use_end(); UI != UE; ++UI)
-      if (UI->getOpcode() != ISD::CopyToReg && UI->getOpcode() != ISD::SETCC)
+         UE = Op.getNode()->use_end(); UI != UE; ++UI)
+      if (UI->getOpcode() != ISD::CopyToReg &&
+          UI->getOpcode() != ISD::SETCC &&
+          UI->getOpcode() != ISD::STORE)
         goto default_case;
 
     if (ConstantSDNode *C =

Added: llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll?rev=144705&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll (added)
+++ llvm/trunk/test/CodeGen/X86/dec-eflags-lower.ll Tue Nov 15 15:57:53 2011
@@ -0,0 +1,29 @@
+; RUN: llc < %s -march=x86-64 | FileCheck %s
+
+%struct.obj = type { i64 }
+
+define void @_Z7releaseP3obj(%struct.obj* nocapture %o) nounwind uwtable ssp {
+entry:
+; CHECK: decq	(%rdi)
+; CHECK-NEXT: je
+  %refcnt = getelementptr inbounds %struct.obj* %o, i64 0, i32 0
+  %0 = load i64* %refcnt, align 8, !tbaa !0
+  %dec = add i64 %0, -1
+  store i64 %dec, i64* %refcnt, align 8, !tbaa !0
+  %tobool = icmp eq i64 %dec, 0
+  br i1 %tobool, label %if.end, label %return
+
+if.end:                                           ; preds = %entry
+  %1 = bitcast %struct.obj* %o to i8*
+  tail call void @free(i8* %1)
+  br label %return
+
+return:                                           ; preds = %entry, %if.end
+  ret void
+}
+
+declare void @free(i8* nocapture) nounwind
+
+!0 = metadata !{metadata !"long", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}





More information about the llvm-commits mailing list