]> granicus.if.org Git - clang/commitdiff
Prevent the creation of empty (forwarding) blocks resulting from nested ifs.
authorWolfgang Pieb <Wolfgang.Pieb@sony.com>
Mon, 11 Jul 2016 22:22:23 +0000 (22:22 +0000)
committerWolfgang Pieb <Wolfgang.Pieb@sony.com>
Mon, 11 Jul 2016 22:22:23 +0000 (22:22 +0000)
Summary:
Nested if statements can generate empty BBs whose terminator branches
unconditionally to its successor. These branches are not eliminated
to help generate better line number information in some cases, but there
is no reason to keep the empty blocks that result from nested ifs.

Reviewers: mehdi_amini, dblaikie, echristo

Subscribers: mehdi_amini, cfe-commits

Differential review: http://reviews.llvm.org/D11360

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@275115 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGStmt.cpp
test/CodeGen/forwarding-blocks-if.c [new file with mode: 0644]

index 29889dd6b50af36cb382fe1e4b116daaeba6a7cf..ee6e3ebb356754a839192128ad2b188ed7301dfc 100644 (file)
@@ -613,7 +613,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
     RunCleanupsScope ThenScope(*this);
     EmitStmt(S.getThen());
   }
-  EmitBranch(ContBlock);
+  {
+    auto CurBlock = Builder.GetInsertBlock();
+    EmitBranch(ContBlock);
+    // Eliminate any empty blocks that may have been created by nested
+    // control flow statements in the 'then' clause.
+    if (CurBlock)
+      SimplifyForwardingBlocks(CurBlock); 
+  }
 
   // Emit the 'else' code if present.
   if (const Stmt *Else = S.getElse()) {
@@ -629,7 +636,12 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
     {
       // There is no need to emit line number for an unconditional branch.
       auto NL = ApplyDebugLocation::CreateEmpty(*this);
+      auto CurBlock = Builder.GetInsertBlock();
       EmitBranch(ContBlock);
+      // Eliminate any empty blocks that may have been created by nested
+      // control flow statements emitted in the 'else' clause.
+      if (CurBlock)
+        SimplifyForwardingBlocks(CurBlock); 
     }
   }
 
diff --git a/test/CodeGen/forwarding-blocks-if.c b/test/CodeGen/forwarding-blocks-if.c
new file mode 100644 (file)
index 0000000..19c8d61
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// Check that no empty blocks are generated for nested ifs.
+
+extern void func();
+
+int f0(int val) {
+  if (val == 0) {
+    func();
+  } else if (val == 1) {
+    func();
+  }
+  return 0;
+}
+
+// CHECK-LABEL: define i32 @f0
+// CHECK: call void {{.*}} @func
+// CHECK: call void {{.*}} @func
+// CHECK: br label %[[RETBLOCK1:[^ ]*]]
+// CHECK: [[RETBLOCK1]]:
+// CHECK-NOT: br label
+// CHECK: ret i32
+
+int f1(int val, int g) {
+  if (val == 0)
+    if (g == 1) {
+      func();
+    }
+  return 0;
+}
+
+// CHECK-LABEL: define i32 @f1
+// CHECK: call void {{.*}} @func
+// CHECK: br label %[[RETBLOCK2:[^ ]*]]
+// CHECK: [[RETBLOCK2]]:
+// CHECK-NOT: br label
+// CHECK: ret i32