[all-commits] [llvm/llvm-project] 82134c: [CIR] Terminate conditional regions after creation...
Akshay K via All-commits
all-commits at lists.llvm.org
Fri Jul 17 13:52:03 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 82134c708f7ec224d86e2096d9b53c76640a490f
https://github.com/llvm/llvm-project/commit/82134c708f7ec224d86e2096d9b53c76640a490f
Author: Akshay K <iit.akshay at gmail.com>
Date: 2026-07-17 (Fri, 17 Jul 2026)
Changed paths:
M clang/lib/CIR/CodeGen/CIRGenExpr.cpp
M clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
M clang/test/CIR/CodeGen/ternary-throw.cpp
Log Message:
-----------
[CIR] Terminate conditional regions after creation; fix glvalue conditional with a throw arm (#210384)
Follow-up to #208850: @andykaylor's comments about
`CIRGenFunction::emitConditionalBlocks` also have a similar
insertion-point problem.
The PR addresses the two related problems found while looking into the
conditional branch emission path:
**1. Terminate conditional regions after creation instead of patching
yields**
`CIRGenFunction::emitConditionalBlocks` still had the save-and-patch
insertion-point machinery removed from the scalar path in #208850. The
path is unreachable, and its guard is saved only after
`cir.unreachable`, where a patched yield would generate the dead code.
The machinery is removed; regions are closed with
`terminateStructuredRegionBody` after creation.
The aggregate emitter had the reverse problem: an unconditional
cir.yield after each arm lands in the dead block a throw leaves behind
and keeps it in the final CIR:
```
struct test_s { int x; int y; };
void test_throw(bool flag) {
test_s a = flag ? throw 0 : test_s{1, 2};
}
mlir
cir.if %2 {
...
cir.throw %3 : !cir.ptr<!s32i>, @_ZTIi
cir.unreachable
^bb1: // no predecessors <-- dead block kept alive by the yield
cir.yield
} else {
...
}
```
The explicit yields are removed; `emitIfOnBoolExpr` already terminates
each region, adding a yield only where one is missing. Tests pin the
dead block's absence with CIR-NEXT after `cir.unreachable`.
**2. Fix glvalue conditionals with a throw arm using a region-local
pointer**
```
int &ref_cond(bool c, int &x) { return c ? x : throw 0; }
// error: operand #0 does not dominate this use
// fatal error: CIR module verification error
```
With one arm throwing, `emitConditionalOperatorLValue` returned the
surviving arm's LValue directly, valid in OG CodeGen's flat CFG, invalid
in CIR where the pointer is materialized inside the ternary's region:
```
%4 = cir.ternary(%3, true {
%8 = cir.load %1 ... // pointer loaded inside the region
cir.yield %8 : !cir.ptr<!s32i>
}, false { ... cir.unreachable })
cir.store %8, %2 ... // region-local %8 used outside the region
```
Existing tests missed it because a local's pointer is a function-entry
`alloca`, so dominance held by accident. The fix addresses the result
through the ternary's result value, which the yield carries out. New
tests cover a reference parameter, assignment via the conditional, and
member access, all of which previously failed verification.
Assisted-by: Cursor/Codex
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list