Fix PR1975: dag isel emitter produces patterns that isel wrong flag result.
authorEvan Cheng <evan.cheng@apple.com>
Tue, 5 Feb 2008 22:50:29 +0000 (22:50 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 5 Feb 2008 22:50:29 +0000 (22:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46776 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/X86/2008-02-05-ISelCrash.ll [new file with mode: 0644]
utils/TableGen/DAGISelEmitter.cpp

index 11b289bf8f323f401c7d328749b43e0037c3efaf..4b68fb7e95fc35482946b4356fd1dc43aefd75c6 100644 (file)
@@ -3183,10 +3183,6 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
 void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand To,
                                       DAGUpdateListener *UpdateListener) {
   SDNode *From = FromN.Val;
-  // FIXME: This works around a dag isel emitter bug.
-  if (From->getNumValues() == 1 && FromN.ResNo != 0)
-    return;  // FIXME: THIS IS BOGUS
-  
   assert(From->getNumValues() == 1 && FromN.ResNo == 0 && 
          "Cannot replace with this method!");
   assert(From != To.Val && "Cannot replace uses of with self");
diff --git a/test/CodeGen/X86/2008-02-05-ISelCrash.ll b/test/CodeGen/X86/2008-02-05-ISelCrash.ll
new file mode 100644 (file)
index 0000000..6885cf1
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR1975
+
+@nodes = external global i64           ; <i64*> [#uses=2]
+
+define fastcc i32 @ab(i32 %alpha, i32 %beta) nounwind  {
+entry:
+       %tmp1 = load i64* @nodes, align 8               ; <i64> [#uses=1]
+       %tmp2 = add i64 %tmp1, 1                ; <i64> [#uses=1]
+       store i64 %tmp2, i64* @nodes, align 8
+       ret i32 0
+}
index dda56c094211f3d748074794ef7516dc0693d98b..7a1920ceac7b2e11bbcdf4fbbe51075ec3481ed7 100644 (file)
@@ -305,6 +305,8 @@ private:
   std::map<std::string, std::string> VariableMap;
   // Node to operator mapping
   std::map<std::string, Record*> OperatorMap;
+  // Name of the folded node which produces a flag.
+  std::pair<std::string, unsigned> FoldedFlag;
   // Names of all the folded nodes which produce chains.
   std::vector<std::pair<std::string, unsigned> > FoldedChains;
   // Original input chain(s).
@@ -587,8 +589,17 @@ public:
       emitCheck(RootName + ".getOpcode() == " +
                 CInfo.getEnumName());
       EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
-      if (NodeHasProperty(Child, SDNPHasChain, CGP))
+      bool HasChain = false;
+      if (NodeHasProperty(Child, SDNPHasChain, CGP)) {
+        HasChain = true;
         FoldedChains.push_back(std::make_pair(RootName, CInfo.getNumResults()));
+      }
+      if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
+        assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
+               "Pattern folded multiple nodes which produce flags?");
+        FoldedFlag = std::make_pair(RootName,
+                                    CInfo.getNumResults() + (unsigned)HasChain);
+      }
     } else {
       // If this child has a name associated with it, capture it in VarMap. If
       // we already saw this in the pattern, emit code to verify dagness.
@@ -1105,9 +1116,15 @@ public:
         }
 
         if (NodeHasOutFlag) {
-          emitCode("ReplaceUses(SDOperand(N.Val, " +
-                   utostr(NumPatResults + (unsigned)InputHasChain)
-                   +"), InFlag);");
+          if (FoldedFlag.first != "") {
+            emitCode("ReplaceUses(SDOperand(" + FoldedFlag.first + ".Val, " +
+                     utostr(FoldedFlag.second) + "), InFlag);");
+          } else {
+            assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
+            emitCode("ReplaceUses(SDOperand(N.Val, " +
+                     utostr(NumPatResults + (unsigned)InputHasChain)
+                     +"), InFlag);");
+          }
           NeedReplace = true;
         }