aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-04-17 23:21:26 +0000
committerChris Lattner <sabre@nondot.org>2011-04-17 23:21:26 +0000
commit421048698b6b6bf86754190bcfe98a0ed82ee5b5 (patch)
treeed832ae025ced205bcd95935183e876906d14ac6
parentf54d81f516ee01467ab0ed54b5031e552c857ff7 (diff)
Fix a miscompilation I introduced in r129652, thanks for Eli for tracking
it down. we effectively were compile the testcase into: void test14(int x) { switch (x) { case 11: break; case 42: test14(97); // fallthrough default: test14(42); break; which is not the same thing at all. This fixes a miscompilation of MallocBench/gs seen on the clang-x86_64-linux-fnt buildbot. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129679 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGStmt.cpp10
-rw-r--r--test/CodeGen/switch-dce.c16
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index b8b2cd9f3e..8bb45343db 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -873,7 +873,8 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
return;
}
- // If the body of the case is just a 'break', try to not emit an empty block.
+ // If the body of the case is just a 'break', and if there was no fallthrough,
+ // try to not emit an empty block.
if (isa<BreakStmt>(S.getSubStmt())) {
JumpDest Block = BreakContinueStack.back().BreakBlock;
@@ -882,6 +883,13 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext());
SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal),
Block.getBlock());
+
+ // If there was a fallthrough into this case, make sure to redirect it to
+ // the end of the switch as well.
+ if (Builder.GetInsertBlock()) {
+ Builder.CreateBr(Block.getBlock());
+ Builder.ClearInsertionPoint();
+ }
return;
}
}
diff --git a/test/CodeGen/switch-dce.c b/test/CodeGen/switch-dce.c
index 4013809cbf..bbb5f7e5aa 100644
--- a/test/CodeGen/switch-dce.c
+++ b/test/CodeGen/switch-dce.c
@@ -229,3 +229,19 @@ void test13(int x) {
default: test13(42); break;
}
}
+
+
+// Verify that case 42 only calls test14 once.
+// CHECK: @test14
+// CHECK: call void @test14(i32 97)
+// CHECK-NEXT: br label [[EPILOG2:%[0-9.a-z]+]]
+// CHECK: call void @test14(i32 42)
+// CHECK-NEXT: br label [[EPILOG2]]
+void test14(int x) {
+ switch (x) {
+ case 42: test14(97); // fallthrough
+ case 11: break;
+ default: test14(42); break;
+ }
+}
+