summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-09-18 08:16:04 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-09-18 08:16:04 +0000
commit6ba1931d6017eb40a8bf605a7b15d37f18f61bca (patch)
tree055171c46129418210c73cd42883d7b58c07de49 /llvm
parent6276f99be57dea883d1f381fe5081fa28bd656da (diff)
downloadbcm5719-llvm-6ba1931d6017eb40a8bf605a7b15d37f18f61bca.tar.gz
bcm5719-llvm-6ba1931d6017eb40a8bf605a7b15d37f18f61bca.zip
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). llvm-svn: 82214
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/MachineBasicBlock.h7
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp17
2 files changed, 19 insertions, 5 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 2a9e86a04c0..2bfb1babbb1 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -149,6 +149,10 @@ public:
return (unsigned)Predecessors.size();
}
bool pred_empty() const { return Predecessors.empty(); }
+ bool isPred(MachineBasicBlock *MBB) const {
+ return std::find(pred_begin(), pred_end(), MBB) != pred_end();
+ }
+
succ_iterator succ_begin() { return Successors.begin(); }
const_succ_iterator succ_begin() const { return Successors.begin(); }
succ_iterator succ_end() { return Successors.end(); }
@@ -165,6 +169,9 @@ public:
return (unsigned)Successors.size();
}
bool succ_empty() const { return Successors.empty(); }
+ bool isSucc(MachineBasicBlock *MBB) const {
+ return std::find(succ_begin(), succ_end(), MBB) != succ_end();
+ }
// LiveIn management methods.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 19ea6473115..e2fab1b1b80 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/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;
}
}
OpenPOWER on IntegriCloud