summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl-Johan Karlsson <karl-johan.karlsson@ericsson.com>2018-07-10 12:06:16 +0000
committerKarl-Johan Karlsson <karl-johan.karlsson@ericsson.com>2018-07-10 12:06:16 +0000
commit1ffeb5d7f0a96df2e06b10252092dca3bbe610aa (patch)
tree19620632a0c27be2cbe97779f2ffe62cf28a9eec
parentd2f5a6f7a21fa0be51c02f62027b72e6dc8d86f7 (diff)
downloadbcm5719-llvm-1ffeb5d7f0a96df2e06b10252092dca3bbe610aa.tar.gz
bcm5719-llvm-1ffeb5d7f0a96df2e06b10252092dca3bbe610aa.zip
[LowerSwitch] Fixed faulty PHI nodes
Summary: Fixed two cases of where PHI nodes need to be updated by lowerswitch. When lowerswitch find out that the switch default branch is not reachable it remove the old default and replace it with the most popular block from the cases, but it forget to update the PHI nodes in the default block. The PHI nodes also need to be updated when the switch is replaced with a single branch. Reviewers: hans, reames, arsenm Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D47203 llvm-svn: 336659
-rw-r--r--llvm/lib/Transforms/Utils/LowerSwitch.cpp14
-rw-r--r--llvm/test/Transforms/Util/lowerswitch.ll48
2 files changed, 59 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/LowerSwitch.cpp b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
index 76ad35832dc..e99ecfef19c 100644
--- a/llvm/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/llvm/lib/Transforms/Utils/LowerSwitch.cpp
@@ -74,7 +74,7 @@ namespace {
LowerSwitch() : FunctionPass(ID) {
initializeLowerSwitchPass(*PassRegistry::getPassRegistry());
- }
+ }
bool runOnFunction(Function &F) override;
@@ -327,7 +327,7 @@ BasicBlock* LowerSwitch::newLeafBlock(CaseRange& Leaf, Value* Val,
} else if (Leaf.Low->isZero()) {
// Val >= 0 && Val <= Hi --> Val <=u Hi
Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High,
- "SwitchLeaf");
+ "SwitchLeaf");
} else {
// Emit V-Lo <=u Hi-Lo
Constant* NegLo = ConstantExpr::getNeg(Leaf.Low);
@@ -354,7 +354,7 @@ BasicBlock* LowerSwitch::newLeafBlock(CaseRange& Leaf, Value* Val,
for (uint64_t j = 0; j < Range; ++j) {
PN->removeIncomingValue(OrigBlock);
}
-
+
int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
assert(BlockIdx != -1 && "Switch didn't go to this successor??");
PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf);
@@ -495,6 +495,10 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI,
}
#endif
+ // As the default block in the switch is unreachable, update the PHI nodes
+ // (remove the entry to the default block) to reflect this.
+ Default->removePredecessor(OrigBlock);
+
// Use the most popular block as the new default, reducing the number of
// cases.
assert(MaxPop > 0 && PopSucc);
@@ -508,6 +512,10 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI,
if (Cases.empty()) {
BranchInst::Create(Default, CurBlock);
SI->eraseFromParent();
+ // As all the cases have been replaced with a single branch, only keep
+ // one entry in the PHI nodes.
+ for (unsigned I = 0 ; I < (MaxPop - 1) ; ++I)
+ PopSucc->removePredecessor(OrigBlock);
return;
}
}
diff --git a/llvm/test/Transforms/Util/lowerswitch.ll b/llvm/test/Transforms/Util/lowerswitch.ll
index 70e1e239b3d..5f5134e71a2 100644
--- a/llvm/test/Transforms/Util/lowerswitch.ll
+++ b/llvm/test/Transforms/Util/lowerswitch.ll
@@ -242,3 +242,51 @@ cleanup: ; preds = %for.body7, %if.then
unreachable: ; preds = %cleanup
unreachable
}
+
+; Test that the PHI node in cleanup17 is removed as the switch default block is
+; not reachable.
+define void @test4() {
+; CHECK-LABEL: @test4
+entry:
+ switch i32 undef, label %cleanup17 [
+ i32 0, label %return
+ i32 9, label %return
+ ]
+
+cleanup17:
+; CHECK: cleanup17:
+; CHECK-NOT: phi i16 [ undef, %entry ]
+; CHECK: return:
+
+ %retval.4 = phi i16 [ undef, %entry ]
+ unreachable
+
+return:
+ ret void
+}
+
+; Test that the PHI node in for.inc is updated correctly as the switch is
+; replaced with a single branch to for.inc
+define void @test5() {
+; CHECK-LABEL: @test5
+entry:
+ br i1 undef, label %cleanup10, label %cleanup10.thread
+
+cleanup10.thread:
+ br label %for.inc
+
+cleanup10:
+ switch i32 undef, label %unreachable [
+ i32 0, label %for.inc
+ i32 4, label %for.inc
+ ]
+
+for.inc:
+; CHECK: for.inc:
+; CHECK-NEXT: phi i16 [ 0, %cleanup10.thread ], [ undef, %cleanup10 ]
+%0 = phi i16 [ undef, %cleanup10 ], [ 0, %cleanup10.thread ], [ undef, %cleanup10 ]
+ unreachable
+
+unreachable:
+ unreachable
+}
OpenPOWER on IntegriCloud