OSDN Git Service

[SystemZ] Fix bootstrap failure due to invalid DAG loop
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 22 Jan 2018 15:41:49 +0000 (15:41 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 22 Jan 2018 15:41:49 +0000 (15:41 +0000)
The change in r322988 caused a failure in the bootstrap build bot.
The problem was that directly gluing a BR_CCMASK node to a
compare-and-swap could lead to issues if other nodes were
chained in between.  There is then no way to create a topological
sort that respects both the chain sequence and the glue property.

Fixed for now by rejecting the optimization in this case.  As a
future enhancement, we may be able to handle additional cases
by swapping chain links around.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323129 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZISelLowering.cpp

index f7fc061..0d29676 100644 (file)
@@ -5484,6 +5484,23 @@ static bool combineCCMask(SDValue &Glue, int &CCValid, int &CCMask) {
   return true;
 }
 
+static bool combineMergeChains(SDValue &Chain, SDValue Glue) {
+  // We are about to glue an instruction with input chain Chain to the
+  // instruction Glue.  Verify that this would not create an invalid
+  // topological sort due to intervening chain nodes.
+
+  SDNode *Node = Glue.getNode();
+  for (int ResNo = Node->getNumValues() - 1; ResNo >= 0; --ResNo)
+    if (Node->getValueType(ResNo) == MVT::Other) {
+      SDValue OutChain = SDValue(Node, ResNo);
+      // FIXME: We should be able to at least handle an intervening
+      // TokenFactor node by swapping chains around a bit ...
+      return Chain == OutChain;
+    }
+
+  return true;
+}
+
 SDValue SystemZTargetLowering::combineBR_CCMASK(
     SDNode *N, DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
@@ -5496,11 +5513,13 @@ SDValue SystemZTargetLowering::combineBR_CCMASK(
 
   int CCValidVal = CCValid->getZExtValue();
   int CCMaskVal = CCMask->getZExtValue();
+  SDValue Chain = N->getOperand(0);
   SDValue Glue = N->getOperand(4);
 
-  if (combineCCMask(Glue, CCValidVal, CCMaskVal))
+  if (combineCCMask(Glue, CCValidVal, CCMaskVal)
+      && combineMergeChains(Chain, Glue))
     return DAG.getNode(SystemZISD::BR_CCMASK, SDLoc(N), N->getValueType(0),
-                       N->getOperand(0),
+                       Chain,
                        DAG.getConstant(CCValidVal, SDLoc(N), MVT::i32),
                        DAG.getConstant(CCMaskVal, SDLoc(N), MVT::i32),
                        N->getOperand(3), Glue);