From c4e664bb9d640e7b04f6fce23830dfb808895b31 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Jan 2007 05:59:59 +0000 Subject: [PATCH] Fix PR1114 and CodeGen/Generic/2007-01-15-LoadSelectCycle.ll by being careful when folding "c ? load p : load q" that C doesn't reach either load. If so, folding this into load (c ? p : q) will induce a cycle in the graph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33251 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 66 +++++++++++++++--------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 96bf9cd4376..654f6c52695 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3709,36 +3709,52 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDOperand LHS, // the right thing to do, but nothing uses srcvalues now. When they do, // turn SrcValue into a list of locations. SDOperand Addr; - if (TheSelect->getOpcode() == ISD::SELECT) - Addr = DAG.getNode(ISD::SELECT, LLD->getBasePtr().getValueType(), - TheSelect->getOperand(0), LLD->getBasePtr(), - RLD->getBasePtr()); - else - Addr = DAG.getNode(ISD::SELECT_CC, LLD->getBasePtr().getValueType(), + if (TheSelect->getOpcode() == ISD::SELECT) { + // Check that the condition doesn't reach either load. If so, folding + // this will induce a cycle into the DAG. + if (!LLD->isPredecessor(TheSelect->getOperand(0).Val) && + !RLD->isPredecessor(TheSelect->getOperand(0).Val)) { + Addr = DAG.getNode(ISD::SELECT, LLD->getBasePtr().getValueType(), + TheSelect->getOperand(0), LLD->getBasePtr(), + RLD->getBasePtr()); + } + } else { + // Check that the condition doesn't reach either load. If so, folding + // this will induce a cycle into the DAG. + if (!LLD->isPredecessor(TheSelect->getOperand(0).Val) && + !RLD->isPredecessor(TheSelect->getOperand(0).Val) && + !LLD->isPredecessor(TheSelect->getOperand(1).Val) && + !RLD->isPredecessor(TheSelect->getOperand(1).Val)) { + Addr = DAG.getNode(ISD::SELECT_CC, LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), TheSelect->getOperand(1), LLD->getBasePtr(), RLD->getBasePtr(), TheSelect->getOperand(4)); - - SDOperand Load; - if (LLD->getExtensionType() == ISD::NON_EXTLOAD) - Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(), - Addr,LLD->getSrcValue(), LLD->getSrcValueOffset()); - else { - Load = DAG.getExtLoad(LLD->getExtensionType(), - TheSelect->getValueType(0), - LLD->getChain(), Addr, LLD->getSrcValue(), - LLD->getSrcValueOffset(), - LLD->getLoadedVT()); + } + } + + if (Addr.Val) { + SDOperand Load; + if (LLD->getExtensionType() == ISD::NON_EXTLOAD) + Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(), + Addr,LLD->getSrcValue(), + LLD->getSrcValueOffset()); + else { + Load = DAG.getExtLoad(LLD->getExtensionType(), + TheSelect->getValueType(0), + LLD->getChain(), Addr, LLD->getSrcValue(), + LLD->getSrcValueOffset(), + LLD->getLoadedVT()); + } + // Users of the select now use the result of the load. + CombineTo(TheSelect, Load); + + // Users of the old loads now use the new load's chain. We know the + // old-load value is dead now. + CombineTo(LHS.Val, Load.getValue(0), Load.getValue(1)); + CombineTo(RHS.Val, Load.getValue(0), Load.getValue(1)); + return true; } - // Users of the select now use the result of the load. - CombineTo(TheSelect, Load); - - // Users of the old loads now use the new load's chain. We know the - // old-load value is dead now. - CombineTo(LHS.Val, Load.getValue(0), Load.getValue(1)); - CombineTo(RHS.Val, Load.getValue(0), Load.getValue(1)); - return true; } } }