[clang] [Clang][CodeGen] Fold forwarding blocks after nested else control flow (PR #207129)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 2 23:16:47 PDT 2026


================
@@ -987,9 +987,17 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
       EmitStmt(Else);
     }
     {
+      llvm::BasicBlock *ElseExitBlock = Builder.GetInsertBlock();
       // There is no need to emit line number for an unconditional branch.
       auto NL = ApplyDebugLocation::CreateEmpty(*this);
       EmitBranch(ContBlock);
+
+      // If nested control flow in the else body left behind a synthetic
+      // continuation, fold it into this if's continuation when possible. Do not
+      // fold source-label targets, as they may still be referenced.
+      if (ElseExitBlock && ElseExitBlock != ElseBlock &&
+          !isLabelTarget(ElseExitBlock))
----------------
firmiana402 wrote:

The difference is the kind of block being simplified here.

In `EmitWhileStmt` and `EmitDoStmt`, `SimplifyForwardingBlocks` is applied to CodeGen-created loop blocks (`LoopHeader` / `LoopCond`) in the special cases where the condition branch was skipped. Those blocks are part of the synthetic loop structure.

Here, `ElseExitBlock` is the current insertion block after emitting an arbitrary `else` body. That block can be a source-label target, e.g.

```c
if (x) {
  f();
} else {
label:;
}
```

In that case, the block is still tracked through `LabelMap`, and later `goto label`  emission can still refer to it at the CodeGen level. `SimplifyForwardingBlocks` only updates existing LLVM IR uses, not those future CodeGen references. So this call site needs to avoid folding source-label targets.

https://github.com/llvm/llvm-project/pull/207129


More information about the cfe-commits mailing list