summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-11-10 21:05:27 +0000
committerJuergen Ributzka <juergen@apple.com>2014-11-10 21:05:27 +0000
commitd441725d3d952685dc3c86d3e8d18b5006b108f8 (patch)
tree973e2ad949cf82724c681a4fed5aa6f17ced731e /llvm/lib
parent3218b942f489c57224ebf57c9b93274b6b5d8434 (diff)
downloadbcm5719-llvm-d441725d3d952685dc3c86d3e8d18b5006b108f8.tar.gz
bcm5719-llvm-d441725d3d952685dc3c86d3e8d18b5006b108f8.zip
[SwitchLowering] Fix the "fixPhis" function.
Switch statements may have more than one incoming edge into the same BB if they all have the same value. When the switch statement is converted these incoming edges are now coming from multiple BBs. Updating all incoming values to be from a single BB is incorrect and would generate invalid LLVM IR. The fix is to only update the first occurrence of an incoming value. Switch lowering will perform subsequent calls to this helper function for each incoming edge with a new basic block - updating all edges in the process. This fixes rdar://problem/18916275. llvm-svn: 221627
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Utils/LowerSwitch.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/LowerSwitch.cpp b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
index d6e5bb62680..a0105c23d75 100644
--- a/llvm/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
@@ -131,17 +131,24 @@ static raw_ostream& operator<<(raw_ostream &O,
return O << "]";
}
-static void fixPhis(BasicBlock *Succ,
- BasicBlock *OrigBlock,
- BasicBlock *NewNode) {
- for (BasicBlock::iterator I = Succ->begin(),
- E = Succ->getFirstNonPHI();
+/// \brief Update the first occurrence of the "switch statement" BB in the PHI
+/// node with the "new" BB. The other occurrences will be updated by subsequent
+/// calls to this function.
+///
+/// Switch statements may have more than one incoming edge into the same BB if
+/// they all have the same value. When the switch statement is converted these
+/// incoming edges are now coming from multiple BBs.
+static void fixPhis(BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB) {
+ for (BasicBlock::iterator I = SuccBB->begin(), E = SuccBB->getFirstNonPHI();
I != E; ++I) {
PHINode *PN = cast<PHINode>(I);
- for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I) {
- if (PN->getIncomingBlock(I) == OrigBlock)
- PN->setIncomingBlock(I, NewNode);
+ // Only update the first occurence.
+ for (unsigned Idx = 0, E = PN->getNumIncomingValues(); Idx != E; ++Idx) {
+ if (PN->getIncomingBlock(Idx) == OrigBB) {
+ PN->setIncomingBlock(Idx, NewBB);
+ break;
+ }
}
}
}
OpenPOWER on IntegriCloud