diff options
author | Chris Lattner <sabre@nondot.org> | 2007-01-16 05:59:59 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-01-16 05:59:59 +0000 |
commit | c4e664bb9d640e7b04f6fce23830dfb808895b31 (patch) | |
tree | a815ff78ff01d49a143a1afb1dacfe085e15432d /lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | 232b8ad8c1805d66fd07a4fa61e35166cd956175 (diff) |
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 96bf9cd437..654f6c5269 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; } } } |