diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-09-18 08:16:04 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-18 08:16:04 +0000 |
commit | f8a56255a54bf60d0cfa6b20d10dad969cce9f81 (patch) | |
tree | ab02b516f483c2c622f62eb4dea11716585ac889 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 1134dc5cc0cb83abcdf072dc4300cd7a898f830c (diff) |
Fix a bug in sdisel switch lowering code. When it updates the phi nodes in switch successor blocks, it can introduce multiple phi operands of the same value from different blocks (and may not be on the predecessor list).
This can be seen on CodeGen/Generic/2006-09-06-SwitchLowering.ll. But it's not known to cause any real regression (but I have added an assertion for it now).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82214 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 19ea647311..e2fab1b1b8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -982,6 +982,7 @@ SelectionDAGISel::FinishBasicBlock() { // If we generated any switch lowering information, build and codegen any // additional DAGs necessary. + SmallSet<unsigned, 4> Processed; for (unsigned i = 0, e = SDL->SwitchCases.size(); i != e; ++i) { // Set the current basic block to the mbb we wish to insert the code into BB = SDL->SwitchCases[i].ThisBB; @@ -1004,12 +1005,18 @@ SelectionDAGISel::FinishBasicBlock() { for (unsigned pn = 0; ; ++pn) { assert(pn != SDL->PHINodesToUpdate.size() && "Didn't find PHI entry!"); - if (SDL->PHINodesToUpdate[pn].first == Phi) { - Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn]. - second, false)); - Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB)); + if (SDL->PHINodesToUpdate[pn].first != Phi) + continue; + if (!Processed.insert(pn)) + // Already processed, done. We can't have the value from more than + // one edges. break; - } + Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn]. + second, false)); + assert(BB->isPred(SDL->SwitchCases[i].ThisBB) && + "phi value cannot come from a bb that is not a predecessor!"); + Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB)); + break; } } |