Follow-up to the July report. Numbers are from upstream main at 8074923be0f3 (2026-08-25) at -O2, x86_64 native on Linux. 2,177 commits since July, 73 of them touching clang/lib/CIR.
Numbers
All figures here have x86_64 calling-convention lowering (the ABI pass for the rest of this post) off, as in every report so far, so they compare directly with July.
| Test Suite | July | Aug 17 | Aug 25 |
|---|---|---|---|
| SingleSource | 97.1% (1794/1848) | 97.8% (1808/1848) | 97.5% (1802/1848) |
| MultiSource | 94.0% (189/201) | 94.5% (190/201) | 93.5% (188/201) |
| SPEC CINT 2017 | 7/10 | 7/10 | 6/10 |
| SPEC CFP 2017 | 5/8 | 7/8 | 5/8 |
libcxx (std/) |
80.4% (7083/8814) | 88.7% (7878/8880) | 88.7% (7882/8891) |
| Self-hosting (per-TU) | 96.6% (4490/4649) | 99.87% (4674/4680) | 99.3% (4668/4703) |
Month over month that’s a good one: libcxx +8.3pp, self-hosting +2.7pp, SingleSource +8 tests.
The mid-August column is there because it shows what the last two weeks cost. SPEC CFP was at 7/8 on the 17th and is back to 5/8; SPEC CINT dropped to 6/10; MultiSource and self-hosting each gave a little back. Two regressions, below.
The ABI pass caught up
The ABI pass is enabled with -fclangir-call-conv-lowering. Upstream it was off by default until recently, and these reports have always measured with it off, it was too unfinished to measure through, since turning it on meant half of everything fell over on one unimplemented case.
New this month: both ways, on both dates.
| Suite | Aug 17 (off) | Aug 17 (on) | Aug 25 (off) | Aug 25 (on) |
|---|---|---|---|---|
| SingleSource | 1808/1848 | 1710/1848 | 1802/1848 | 1802/1848 |
| MultiSource | 190/201 | 182/201 | 188/201 | 191/201 |
On the 17th the pass still cost 98 SingleSource tests. On the 25th it costs nothing. SingleSource is identical either way, and MultiSource is better with it on.
September’s numbers will be measured with the ABI pass on. This is x86_64 only; on every other target it stays off until it catches up there too.
Two regressions
Both are single well-scoped defects rather than missing features, and each has a four-line reproducer in its issue.
Typed catch fails to verify at -O1+: 822 hits, the largest category this month. Cost three SPEC benchmarks: 523.xalancbmk_r (CINT 7→6), 511.povray_r and 526.blender_r (CFP 7→5). #219549.
[[no_unique_address]] on a struct wrapping an empty struct: 788 hits, and the whole self-hosting regression (31 of 35 failing targets, up from 2). LLVM’s own headers use the pattern. #219547.
One big fix
ExtVectorBoolType store/load is at zero. It was the #1 category in July (80 hits) and still #1 mid-August (82). Biggest thing ever cleared off this list, and a good part of why libcxx moved.
Self-hosting
Stage-2 bootstrap (a -fclangir-built clang recompiling LLVM/clang), per-TU, (still) ABI pass off.
| July | Aug 17 | Aug 25 | |
|---|---|---|---|
| Targets built / total | 4490 / 4649 | 4674 / 4680 | 4668 / 4703 |
| Pass rate | 96.6% | 99.87% | 99.3% |
35 of 4,703 don’t build: 31 are the [[no_unique_address]] regression above, 4 hit the timeout (FuchsiaHandleChecker.cpp, llvm-dwarfutil.cpp, ObjcopyOptions.cpp, ELFDumper.cpp, same four as last time). The denominator moved because the tree grew.
Timeout here means over the 180 s per-TU budget, not that they never finish. Those four haven’t been looked at, but the one compile-time blowup I did characterise this month is an ABI-pass-off artefact: without sret, a large by-value aggregate return becomes an LLVM first-class aggregate, so one function picked up 20,000 insertvalue instructions and 43 minutes in the backend against 2 seconds without -fclangir (on SPEC CPU 2026). These four may be the same thing, in which case measuring with the ABI pass on makes them go away.
Top issues
Across libcxx, the test suites and self-hosting.
| # | Category | Hits | vs July |
|---|---|---|---|
| 1 | cir.try: handler must start with cir.begin_catch |
174 | NEW (regression) |
| 2 | [[no_unique_address]] empty-for-layout field |
79 | NEW (regression) |
| 3 | Coroutine builtins (coro_promise, _resume, _done, _destroy) |
7 | 7 (was coro_id) |
| 4 | llvm::cast_if_present assertion (Casting.h) |
6 | NEW |
| 5 | llvm::cast assertion (Casting.h) |
4 | 19 |
| 6 | “pass manager failed to lower CIR to LLVMIR dialect” | 4 | 13 |
| 7 | “module verification error before running CIR passes” | 4 | NEW |
| 8 | AggExprEmitter: AtomicCast on a padded atomic |
3 | 3 |
| 9 | LowerVAARG assertion (MVT::f80) |
3 | 2 |
| 10 | declaration of kind: Import |
2 | 2 |
| 11 | AggExprEmitter: VisitCoawaitExpr |
2 | 2 |
Gone to zero since July: ExtVectorBoolType store/load (35), which was the
month’s biggest single fix; “Lowering from LLVMIR dialect to llvm IR failed”
(14); and the X86 library-function NYI (2). __builtin_clear_padding is also at
zero — it was implemented upstream in #216126 on Aug 13.
CIR unit tests, as a sanity signal only: 983/1016 (936/957 mid-August, the suite grew by 59).
What’s next
- Fix the two regressions. Between them: three SPEC benchmarks and 29 extra self-host failures.
- Measure September with the ABI pass on. Worth saying plainly: the gap is confirmed closed on SingleSource and MultiSource, not on libcxx or self-hosting, so this could still move.
- Coroutines more than doubled (33 → 78) as
coro_promise/coro_resume/coro_done. Biggest thing left that isn’t a regression. ValueTypes.cpp(34) andLowerVAARG(22) are one gap: CIR emits a genericva_arg, and neither an aggregate norlong doublehas an MVT the X86 backend can select. The aggregate half can’t be fixed in the backend at all.- Compile time and memory are becoming their own problem, separate from correctness. Re-checking the four self-host timeouts with the ABI pass on is the cheap first step, they may simply be the missing-
sretblowup. - Still no ARM64 numbers; that sweep is pending.
Questions, corrections, contributions welcome.