]> granicus.if.org Git - clang/commitdiff
Fix a miscompilation I introduced in r129652, thanks for Eli for tracking
authorChris Lattner <sabre@nondot.org>
Sun, 17 Apr 2011 23:21:26 +0000 (23:21 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 17 Apr 2011 23:21:26 +0000 (23:21 +0000)
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

lib/CodeGen/CGStmt.cpp
test/CodeGen/switch-dce.c

index b8b2cd9f3e76c97a735eb8c624751707d5d23aa1..8bb45343db85f61f015100a2ba6ca0b51ef3a5c8 100644 (file)
@@ -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;
     }
   }
index 4013809cbf605454508261c67ba21f286e5ef5b0..bbb5f7e5aa365436b176927acef0e0039cfb181a 100644 (file)
@@ -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;
+  }
+}
+