[llvm] r311749 - [x86] NFC: More refactoring to pave the way to extending this ISel logic

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 24 19:06:36 PDT 2017


Author: chandlerc
Date: Thu Aug 24 19:06:36 2017
New Revision: 311749

URL: http://llvm.org/viewvc/llvm-project?rev=311749&view=rev
Log:
[x86] NFC: More refactoring to pave the way to extending this ISel logic
to handle other x86 pseudos that carry flags and thus can't be matched
by our ISel patterns with fused memory accesses.

Differential Revision: https://reviews.llvm.org/D37088

Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=311749&r1=311748&r2=311749&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Aug 24 19:06:36 2017
@@ -1932,15 +1932,48 @@ static bool hasNoSignedComparisonUses(SD
   return true;
 }
 
-/// Check whether or not the chain ending in StoreNode is suitable for doing
-/// the {load; increment or decrement; store} to modify transformation.
-static bool isLoadIncOrDecStore(StoreSDNode *StoreNode, unsigned Opc,
-                                SDValue StoredVal, SelectionDAG *CurDAG,
-                                LoadSDNode* &LoadNode, SDValue &InputChain) {
-
-  // is the value stored the result of a DEC or INC?
-  if (!(Opc == X86ISD::DEC || Opc == X86ISD::INC)) return false;
+/// Get the appropriate X86 opcode for an in-memory arithmetic operation that
+/// also sets flags.
+///
+/// FIXME: This is essentially re-implemneting a subset of the patterns for
+/// these instructions. Instead, we should compute this from the patterns
+/// somehow.
+///
+/// FIXME: Currently we only support integer operations.
+///
+/// If there is no X86 opcode, returns none.
+static Optional<unsigned> getFusedLdStWithFlagsOpcode(EVT LdVT, unsigned Opc) {
+  auto SelectSize = [&](unsigned Opc64, unsigned Opc32, unsigned Opc16,
+                        unsigned Opc8) -> Optional<unsigned> {
+    switch (LdVT.getSimpleVT().SimpleTy) {
+    case MVT::i64:
+      return Opc64;
+    case MVT::i32:
+      return Opc32;
+    case MVT::i16:
+      return Opc16;
+    case MVT::i8:
+      return Opc8;
+    default:
+      return None;
+    }
+  };
+  switch (Opc) {
+  default:
+    return None;
+  case X86ISD::DEC:
+    return SelectSize(X86::DEC64m, X86::DEC32m, X86::DEC16m, X86::DEC8m);
+  case X86ISD::INC:
+    return SelectSize(X86::INC64m, X86::INC32m, X86::INC16m, X86::INC8m);
+  }
+}
 
+/// Check whether or not the chain ending in StoreNode is suitable for doing
+/// the {load; op; store} to modify transformation.
+static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode,
+                                        SDValue StoredVal, SelectionDAG *CurDAG,
+                                        LoadSDNode *&LoadNode,
+                                        SDValue &InputChain) {
   // is the stored value result 0 of the load?
   if (StoredVal.getResNo() != 0) return false;
 
@@ -1957,11 +1990,6 @@ static bool isLoadIncOrDecStore(StoreSDN
 
   // Return LoadNode by reference.
   LoadNode = cast<LoadSDNode>(Load);
-  // is the size of the value one that we can handle? (i.e. 64, 32, 16, or 8)
-  EVT LdVT = LoadNode->getMemoryVT();
-  if (LdVT != MVT::i64 && LdVT != MVT::i32 && LdVT != MVT::i16 &&
-      LdVT != MVT::i8)
-    return false;
 
   // Is store the only read of the loaded value?
   if (!Load.hasOneUse())
@@ -2019,24 +2047,6 @@ static bool isLoadIncOrDecStore(StoreSDN
   return true;
 }
 
-/// Get the appropriate X86 opcode for an in-memory increment or decrement.
-/// Opc should be X86ISD::DEC or X86ISD::INC.
-static unsigned getFusedLdStOpcode(EVT &LdVT, unsigned Opc) {
-  if (Opc == X86ISD::DEC) {
-    if (LdVT == MVT::i64) return X86::DEC64m;
-    if (LdVT == MVT::i32) return X86::DEC32m;
-    if (LdVT == MVT::i16) return X86::DEC16m;
-    if (LdVT == MVT::i8)  return X86::DEC8m;
-  } else {
-    assert(Opc == X86ISD::INC && "unrecognized opcode");
-    if (LdVT == MVT::i64) return X86::INC64m;
-    if (LdVT == MVT::i32) return X86::INC32m;
-    if (LdVT == MVT::i16) return X86::INC16m;
-    if (LdVT == MVT::i8)  return X86::INC8m;
-  }
-  llvm_unreachable("unrecognized size for LdVT");
-}
-
 // Change a chain of {load; incr or dec; store} of the same value into
 // a simple increment or decrement through memory of that value, if the
 // uses of the modified value and its address are suitable.
@@ -2061,10 +2071,17 @@ bool X86DAGToDAGISel::foldLoadStoreIntoM
   SDValue StoredVal = StoreNode->getOperand(1);
   unsigned Opc = StoredVal->getOpcode();
 
+  EVT MemVT = StoreNode->getMemoryVT();
+  if (!MemVT.isSimple())
+    return false;
+  Optional<unsigned> NewOpc = getFusedLdStWithFlagsOpcode(MemVT, Opc);
+  if (!NewOpc)
+    return false;
+
   LoadSDNode *LoadNode = nullptr;
   SDValue InputChain;
-  if (!isLoadIncOrDecStore(StoreNode, Opc, StoredVal, CurDAG, LoadNode,
-                           InputChain))
+  if (!isFusableLoadOpStorePattern(StoreNode, StoredVal, CurDAG, LoadNode,
+                                   InputChain))
     return false;
 
   SDValue Base, Scale, Index, Disp, Segment;
@@ -2076,10 +2093,8 @@ bool X86DAGToDAGISel::foldLoadStoreIntoM
   MemOp[0] = StoreNode->getMemOperand();
   MemOp[1] = LoadNode->getMemOperand();
   const SDValue Ops[] = {Base, Scale, Index, Disp, Segment, InputChain};
-  EVT LdVT = LoadNode->getMemoryVT();
-  unsigned newOpc = getFusedLdStOpcode(LdVT, Opc);
   MachineSDNode *Result =
-      CurDAG->getMachineNode(newOpc, SDLoc(Node), MVT::i32, MVT::Other, Ops);
+      CurDAG->getMachineNode(*NewOpc, SDLoc(Node), MVT::i32, MVT::Other, Ops);
   Result->setMemRefs(MemOp, MemOp + 2);
 
   ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));




More information about the llvm-commits mailing list