ClangIR (CIR) is an MLIR dialect between the AST and LLVM IR, and in October 2026 the clang area team accepted building it by default. CIR is built on MLIR because each step along the way was locally reasonable, and together the steps locked MLIR in. The costs (build time, binary size, MLIR API churn) land largely on Clang contributors who neither chose MLIR nor use CIR.
This post traces how CIR came to depend on MLIR, collects what the dependency costs, and uses an MLIR-free CIR as a thought experiment to separate the costs inherent to MLIR from those that can be reduced.
This post relies heavily on an LLM agent (Claude Code). It read the Discourse threads, GitHub PRs, slides, and the source tree, computed the build-closure and contributor numbers, and drafted the text, which I then edited. My part was steering, and some of what I added to its context:
- the build-by-default and premerge-testing RFCs, and a discussion on Discord #llvm;
- the opportunity-cost framing: contributors without fast machines pay for MLIR (and Flang) on every llvm/ change, though most of them never use either.
Treat the numbers as checked but not peer-reviewed.
What ClangIR replaces
Classic Clang lowers the AST to LLVM IR in
clang/lib/CodeGen. With -fclangir,
clang/lib/CIR/CodeGen (CIRGen) emits CIR instead, a set of
CIR passes runs, CIR is converted to MLIR's llvm dialect,
and MLIR translates that to LLVM IR.
- CIRGen mirrors the AST-to-IR half of
clang/lib/CodeGenfile by file:CodeGenFunctionbecomesCIRGenFunction,CGExprScalar.cppbecomesCIRGenExprScalar.cpp, and so on. It is 66K lines against CodeGen's 214K, with 786errorNYIcalls marking what is missing. - Work that classic CodeGen does while emitting IR becomes separate
CIR passes: C++ ABI lowering (
CXXABILowering), calling conventions (CallConvLowering), exception handling (EHABILowering), and structured control flow to a CFG (FlattenCFG). - The optimizer and backend are not replaced. CIR's frontend action
calls
emitBackendOutputfromclang/lib/CodeGen/BackendUtil.cpp, soclangCIRFrontendActionlinksclangCodeGen. - Some code is shared rather than duplicated:
clang/lib/CodeGenUtils(#221001, September 2026) holds AST-only helpers used by both, andllvm/lib/ABI(LLVMABI) does ABI classification for CIR's calling-convention lowering and, under-fexperimental-abi-lowering, for classic CodeGen. - Nothing in
clang/lib/Analysisis replaced yet. The CFG, the analyses behind Sema's analysis-based warnings, the dataflow framework, lifetime safety, and the Static Analyzer all still work on the AST and the CFG. Upstream CIR's only analysis is an alias analysis used by ABI lowering. Replacing CFG-based analysis is an aspiration rather than a plan: the 2022 RFC argued that the CFG is "discarded after analysis" and "has lots of known problems", and the area team expects CIR to replace "the current CodeGen and CFG analysis", but no ClangIR document schedules it.
The in-tree roadmap, clang/docs/CIR/CodeDuplication.md,
is about CodeGen. It plans to raise CIR to a higher level, move ABI
details into later lowering passes, and "replace relevant parts of the
existing implementation, piece by piece" with implementations shared by
both code generators. Calling conventions are the first case (LLVMABI,
plus an MLIR adapter that FIR can also use). The roadmap lists the next
candidates: constant expression evaluation, complex multiplication and
division, builtins, exception handling and C++ cleanups, inline
assembly, and C++ ABI handling (vtables, virtual calls, constructor and
destructor arguments, dynamic casts, base class addresses, type
descriptors, array new and delete). Linkage, alignment, debug info,
TBAA, sanitizers, and lifetime markers are spread through CodeGen and
listed as harder to share. It also aims to run all classic CodeGen tests
through the CIR path.
Where things stand
The area team's decision says "ClangIR is likely to reach the point
where it becomes the replacement for the current CodeGen and CFG
analysis." The same post promises that
-DCLANG_ENABLE_CIR=Off "will still be a supported
configuration for the forseeable future", and -fclangir
stays off by default. On main, clang/CMakeLists.txt tests
CLANG_ENABLE_CIR but declares no option() for
it, so the flip is still pending.
A separate RFC, Add CIR testing to clang and MLIR CI (#227834), would build and test CIR in premerge for clang/ and mlir/ changes. nikic is weakly -1: if contributors have to fix CIR failures, "they also need to build and test CIR locally", so premerge testing and build-by-default "should go hand in hand". rengolin calls asking non-CIR developers to stub out CIR breakage "an unreasonable request" and suggests a different CI setup.
As for the compiler itself, the ClangIR
progress report for September 2026 measures -fclangir
against classic CodeGen: 1.32x the wall time on a typical file, 1.57x
across the tree, 1.17x the memory, and 3% more code.
Why MLIR
Meta, 2022: framework reuse for a lifetime checker
ClangIR started at Meta in October 2021. Bruno Cardoso Lopes and Nathan Lanza proposed it in RFC: An MLIR based Clang IR (CIR) in June 2022, and it moved to an LLVM incubator in August 2022 (timeline from the 2025 keynote). The primary goal was "improved diagnostics for modern C++"; the design had "grown out of implementing a lifetime analysis/checker pass"; optimization and lowering were "a secondary goal for now". Clang lacked a suitable IR: the AST is awkward for dataflow, LLVM IR is too low level, and the Clang CFG is discarded after analysis. The RFC's entire "Why MLIR?" section reads:
MLIR provides a solid and tested framework to build custom IR and run passes. Among several other capabilities, it's also in already in tree and used by Flang to build FIR.
Nobody in the thread asked for a bespoke IR instead. efriedma wrote
"using MLIR to build it seems like the right approach" and objected to
structured control flow instead. Gábor Horváth argued
that the CFG suffices for lifetime analysis, and John McCall wanted
a two-stage lowering like Swift's. Reid Kleckner asked
for an agreed compile-time ceiling, "like +15-25%, before making this
part of the default pipeline". -fclangir is still opt-in,
and 1.32x/1.57x is already past that ceiling.
Lopes's later talks do not revisit the choice. The 2023 Developers' Meeting talk (video) describes CIR as "Implemented as an MLIR dialect for C/C++". Its pipeline diagram goes from CIRGen through CIR passes, including the lifetime checker, to LLVM lowering, with a dashed side path through SCF and Affine. The lifetime checker was real: the talk reports integration with clangd, clang-tidy, and an internal IDE, and "Successful detection of lifetime bug that caused a major internal outage". The same talk lists "Compile & execution time, binary size, memory usage" among the challenges. The project site gives today's rationale: MLIR enables "the development of passes and IR, rapid design iteration, and reuse of community-provided analyses and transformations". Apart from a few OpenMP passes, clang's CIR pipeline runs only CIR's own passes.
The lifetime checker never reached upstream CIR. Clang's lifetime-safety analysis (#142313, July 2025) is built on the CFG, and Horváth is among its authors.
NVIDIA, 2023: OpenACC lives in MLIR
In October 2023 Erich Keane (NVIDIA) posted RFC:
Implementation of OpenACC 3.3 for offload in Clang. Flang lowers
OpenACC through MLIR's acc dialect: "It is our intention to
use that as well, so NVIDIA is beginning to participate in the CIR/MLIR
effort". Clang shares more than the dialect with Flang. CIR and FIR
implement the same acc type interfaces
(CIROpenACCTypeInterfaces.cpp,
FIROpenACCTypeInterfaces.cpp), and acc-to-GPU passes are
landing in mlir/lib/Dialect/OpenACC/Transforms. Classic
CodeGen has no OpenACC lowering (CodeGenFunction.h: "TODO
OpenACC: Implement this"), so CIR plus acc is Clang's only
OpenACC implementation.
Strictly, the requirement was MLIR's acc dialect, not
CIR. Keane's fallback
was "LLVM-IR based metadata to enable the translation to the OpenACC
MLIR dialect", and the second
fallback, "lowering as OMP does", gives up sharing with Flang.
OpenMP has the same sharing benefit without the necessity: CIR emits
omp ops, but classic CodeGen already lowers OpenMP.
By 2026 the motive had widened. Keane wrote that the goal is to "enable further advancement for our compiler stack … the way to allow those to integrate with C/C++/Clang is to have a dialect for it".
2024–2026: lock-in
Lopes proposed
upstreaming in January 2024, Lanza landed the scaffolding in April
2024, and NVIDIA's first upstream CIR commit (David Olsen) followed in
November 2024. Today CIR is 120K lines (lib + include) on ODS, MLIR
interfaces, and MLIR rewrite drivers, with ~230 ops and 1,269 test
files, 868 of which check -emit-cir output in MLIR's
textual format.
Readers might ask whether NVIDIA led the upstreaming. I counted
commits touching clang/lib/CIR, both upstream and in the
archived llvm/clangir incubator (excluding incubator commits that also
exist upstream). Affiliation comes from email domains, GitHub profiles,
and LinkedIn; a GitHub profile shows the current employer, not the
employer at commit time.
| Author | Incubator only (2,498, 2021-08..2026-02) | Upstream (2,023) |
|---|---|---|
| Meta | 55% | 1.5% |
| NVIDIA | 2.7% | 47% |
| Amr Hesham (GSoC 2025, then kept going) | 5% | 14% |
| unknown | 28% | 27% |
Meta wrote the incubator: its share was 100% in 2021, 97% in 2022, about half in 2023–2024, and 11% in 2025. NVIDIA wrote 45–49% of upstream commits each year, so by volume NVIDIA led the upstreaming; by authorship of the RFC and the scaffolding, Meta did. Of the 260 upstream commits titled "upstream …", the explicit ports from the incubator, Amr Hesham wrote 37%, NVIDIA 31%, and unknown authors 31%. Most NVIDIA commits are new code written upstream. The maintainers are Andy Kaylor (NVIDIA), Bruno Cardoso Lopes (Meta), and Henrich Lauko (NVIDIA since August 2026, previously Trail of Bits and NextSilicon).
The stated long-term value is mixing dialects. From Lopes's SC24
talk (November 2024) on, the slides describe CIR as a way to "Move
Clang onto the MLIR substrate" and "Use MLIR from C, C++ and
extensions", and to "Mix CIR with downstream and custom dialects". The
2025 keynote with Andy Kaylor lists "Lower to other MLIR dialects" among
CIR's uses, next to the lifetime checker, and has a slide titled "CIR
Won't Always Go To LLVM IR", where CIR is consumed by MLIR to "Offload
to GPU or other targets".
clang/docs/CIR/CodeDuplication.md: "even now we generate
the ACC (OpenACC) dialect in combination with CIR, and when support for
OpenMP and CUDA are added, similar mixing will occur". The area team's
acceptance ratifies this direction. Every year of upstreaming raised the
cost of switching, and the main funder's motive now depends on MLIR
itself, not just on the original team's choice of framework.
The costs
Build
aengelke's -1
in the build-by-default thread starts from "I usually don't build MLIR".
His measurements of ninja clang in a dylib build track the
trimming work:
| Date | Landed before | CPU time | Wall time | c-t-t build time |
|---|---|---|---|---|
| 2026-09-05 | +130% | +155% | ||
| 2026-09-09 | #221616, #221813 | +40% | +83% | +58% |
| 2026-09-14 | #222576 | +30% | +71% | +47% |
My #221616 links only the MLIR dialects CIR uses; on 192 cores
PragmaTwice measured
it alone taking ninja clang wall time from +109% to +75%.
#221813 shards the LLVM dialect's generated code, and #222576 gives
MLIRIR a precompiled header. On 2026-09-14, libclang-cpp.so
in the dylib build was still +91% (+83% stripped); on c-t-t, the
clang binary was +51% (+68 MiB) and the build's max-rss
+40%. The area team's "roughly 1.2x for a build only building clang" is
wall time of a parallel build, which hides much of the CPU cost.
The c-t-t comparison
for the "enable clangir" commit lists per-file compile times. Summed,
they add 1,644 s (+48%): ~744 s for CIR's own code
(CIRDialect.cpp.o alone takes 44 s) and ~881 s for MLIR.
These sums measure work, not wall time.
clang still links a closure of 90 MLIR libraries, and
some are unused:
MLIRArithToLLVMdepends onMLIRArithTransformsfor one helper,populateCeilFloorDivExpandOpsPatterns(#118839), which drags in Bufferization, SparseTensor, Tensor, Vector, and Shard (~177 s); see Reducing the cost.MLIROpenACCDialectdepends onMLIRGPUDialect(~38 s, #174671).- PDL (~21 s) can be disabled with the existing
MLIR_ENABLE_PDL_IN_PATTERNMATCHoption.
The often-cited NVVM and ROCDL dialects
(NVVMDialect.cpp.o 108 s and
ROCDLDialect.cpp.o 134 s in aengelke's 2026-09-05 list) are
no longer in the closure after #221616; only 3.3 s of their TableGen
output remains, via the mlir-headers umbrella target.
MLIR's headers are heavy. For files under tools/mlir/,
the frontend is 75% of compile time and header parsing 55% (aengelke's
numbers in #213412).
MLIRIR now has a precompiled header, but CIR's own libraries do not, and
AddLLVM.cmake lets a library reuse the precompiled header
of at most one direct dependency. CIRGen reuses clangAST's, so each of
its files reparses the MLIR and CIR dialect headers; a private
precompiled header like clangCodeGen's (#206018)
cuts CIRGen's summed compile time by 72%.
Contributors without a build farm
Most of the numbers above come from many-core machines, and wall time
on a many-core machine hides the cost. On aengelke's 96-thread machine,
ninja clang used 30% more CPU time but 71% more wall time,
because a few slow files dominate the critical path (on c-t-t,
CIRDialect.cpp.o takes 44 s and MLIR's
OpenACC.cpp.o 31 s). With fewer cores, wall time approaches
CPU time divided by the core count: the extra 2,100 CPU-seconds of that
build are 4–5 minutes on 8 threads, for every clean build.
Incremental builds matter more to someone iterating on a patch. From the c-t-t per-file times and the header dependencies of my MLIR-enabled build:
- Linking
clangis 38% slower on c-t-t (105 s to 145 s); with lld it stays under a second. - Touching
llvm/ADT/DenseMap.h,StringRef.h, orraw_ostream.hrecompiles 2,504 files (3,274 s summed) without CIR; MLIR adds 380 files (853 s) and CIR another 100 (751 s), +49%. - Touching
llvm/IR/Function.hrecompiles 58 more MLIR files (+16%), before counting CIR's lowering. - Touching
clang/AST/Decl.hrecompiles 521 files (1,198 s) without CIR; CIRGen adds at least 51 files and 415 s, +35%. CIRGen alone costs 2.2x classic CodeGen (104 files, 189 s); in my parallel build, 1.6x (351 s vs 221 s).
Memory and disk grow too: c-t-t's build max-rss is +40% (+1 GiB), which matters when running many jobs on a 16 or 32 GiB machine, and aengelke's build directory grew from 1.5 GiB to 2.4 GiB.
-DCLANG_ENABLE_CIR=Off stays supported, but once
premerge tests CIR, a contributor who opts out learns about CIR breakage
from CI and then has to build CIR anyway. Flang shows where this goes.
.ci/compute_projects.py tests flang and mlir for every
llvm/ change, so fixing a breakage means building Flang and MLIR. In my
full build (clang, mlir, flang, lld, …), summed per-file compile time
splits clang 25.6%, mlir 19.7%, llvm 16.2%, flang 14.5%. Users who need
Flang or OpenACC can get them from a vendor toolchain; a contributor
whose llvm/ change breaks them has to build them to fix it. Companies
that fund CIR and Flang have build farms; many volunteers and
contributors from smaller companies have a desktop or a laptop, and each
component that becomes everyone's responsibility raises the bar for
them.
Runtime, for every clang user
Building CIR in costs something even without -fclangir.
On c-t-t, stage2-O2-g compile time is +0.18% and max-rss +2.6%. In
aengelke's dylib build, clang -emit-llvm -c empty.c
executes 12% more instructions, down from +88% when clang still linked
libMLIR.so, and clang -c empty.c still crashed
on 2026-09-14. aengelke names dynamic relocations, global constructors,
and additional cl::opt as probable causes.
With -fclangir, the five worst files in the progress
report took 2.0–4.1x as long, "almost all in lowering CIR to LLVM IR:
30–92 s per file, roughly split between the CIR-to-LLVM-dialect
conversion and the translation to LLVM IR". A linear scan for comdats
made that quadratic; #227127 cut
the lowering to 8–11 s. Quadratic paths keep surfacing through the
llvm dialect: #198424 for
insertvalue globals, and Flang's #140268 and
#209393.
For typical files, I compiled 29 random C++ files from
llvm/lib and clang/lib with their build flags
(-O3) and -ftime-trace, with and without
-fclangir, using a Release+Asserts clang at a160747d89a3
(after #227127). -fclangir took 1.15x as long in total,
1.12x for the median file, below the progress report's 1.32x. The extra
time splits roughly in thirds:
| Phase | Extra time | Share of the -fclangir
compile |
|---|---|---|
| CIRGen (vs. classic IR generation) | 3.6 s | 4.4% |
| CIR-to-CIR passes | 3.0 s | 3.6% |
| CIR to LLVM IR (conversion and translation) | 3.8 s | 4.7% |
| optimizer and backend | 0.4 s | 0.5% |
For the median file, lowering to LLVM IR is 3.6% of the compile, and
6.5% with the CIR-to-CIR passes. GotoSolver alone is 22% of
the CIR-to-CIR time. CIRGen's deferred emission and the module verifier
run outside any -ftime-trace scope, so I attribute the
untraced time to CIRGen.
Lopes's AsiaLLVM
2025 report measured the incubator in June 2025. On the three CTMark
programs that compiled, -fclangir took 1.9–2.9x the user
time at -O0 and 1.1–1.6x at -O2. For clamr_cpuonly.cpp at
-O0, classic CodeGen took 15 ms and CIRGen 289 ms, 265 ms of it in
CIRGenModule::applyReplacements, which the slides call "low
hanging fruit".
Some costs are not measured yet. CIR emits no debug info; in Flang,
#146543
saw 1.75M debug-info nodes against 8K for one type. MLIRContext uniques
types, attributes, and locations and never
frees them. CIRGenFunction::getLoc eagerly calls
getPresumedLoc and creates a uniqued
FileLineColLoc for each call.
Maintenance
CIR re-implements classic CodeGen (ABI lowering, builtins, …), and
CodeDuplication.md accepts "a significant amount of
technical debt" kept in sync by hand. That would be true of any new IR,
MLIR or not.
MLIR's API churn is MLIR-specific. The 2025 keynote names it among
the growing pains: "The ClangIR build sometimes gets broken by changes
in MLIR or other parts of clang". I counted at least six CIR fixups
since June 2025 caused by MLIR interface changes, e.g. after the
RegionBranchOpInterface revamp (#165441) and
a MemorySlotInterfaces rename (#229068).
Premerge testing would turn them into every clang and mlir author's
problem.
Compile-time culture
llvm-compile-time-tracker.com measures every LLVM commit, and
regressions get bisected and discussed. I found no per-commit tracker
for MLIR or Flang, and MLIR's in-tree benchmark runner
mlir/utils/mbr has had no functional change since July
2022. MLIR compile-time work happens after users hit a wall: the One-Shot
Dialect Conversion driver (dialect conversion was "by far the
slowest part"), the LLVM dialect sharding, the MLIRIR precompiled
header. Flang's #58730, at
4x gfortran's time and memory, has been open since 2022. My reading is
that MLIR's main users (machine learning compilers that compile a model
once and run it many times) tolerate costs that a C++ build, recompiling
large translation units on every edit, does not. Clang's bar has to be
enforced on the CIR side.
Reducing the cost
I keep this table updated as patches land. Local numbers come from my
machine (i7-14700K, 28 threads, Release with assertions, lld), with
summed per-file times from .ninja_log.
| Patch | Status | Effect |
|---|---|---|
| #221616 link only the MLIR dialects CIR uses | landed 2026-09-07 | ninja clang wall time +109% to +75% (PragmaTwice, 192
cores) |
| #221813 shard the LLVM dialect's generated ops | landed 2026-09-07 | splits LLVMDialect.cpp.o, 121 s in aengelke's list |
| #222576 precompiled header for MLIRIR | landed 2026-09-10 | c-t-t build time +58% to +47% across it |
| #227127 cached symbol tables for comdat lookups | landed 2026-10-02 | lowering of the five worst files from 30–92 s to 8–11 s |
| precompiled header for clangCIR | not yet posted | CIRGen's 54 files from 312 s to 85 s summed (including 6 s for the header); user CPU 282 s to 78 s |
| move the ceil/floor div expansion from MLIRArithTransforms to MLIRArithUtils | not yet posted | clang links 16 fewer MLIR libraries (90 to 74); 64
fewer object files, 147 s summed (177 s on c-t-t) |
MLIROpenACCDialect without
MLIRGPUDialect |
open | ~38 s; acc declares gpu as a dependent
dialect and uses its types |
| PDL off when MLIR is only a dependency | open | ~21 s |
shard CIRDialect.cpp |
open | 58 s locally, the slowest file in the build; its generated
CIROps.cpp.inc has 102K lines |
Thought experiment: an MLIR-free ClangIR
What does CIR take from MLIR?
- Dialects:
cir,builtin,llvm(~900 references),acc(402),ptr(74),omp(~65),dlti. - ODS: ~230 ops, 164 declarative assembly formats, 53 verifiers, 22 folders/canonicalizers.
OpBuilder, symbol tables, and the region-branch, loop, call, memory-slot, and data-layout interfaces.- The pass manager with 12 CIR passes, the greedy rewrite driver, and the conversion driver (125 lowering patterns).
- The
llvmdialect andModuleTranslation.
Not used in clang's pipeline: MLIR's mem2reg and SROA (CIR implements
the memory-slot interfaces, but only cir-opt tests run
-mem2reg), CSE, the inliner, the dataflow framework, and
the loop dialects. The incubator's ThroughMLIR path (to
affine/scf) never went upstream; efriedma noted
that "translating from ClangIR to the MLIR's loop-based dialects is
probably more complicated than ClangIR itself."
CIRGen would port almost unchanged. Only 8.6% of its 66K lines
mention mlir::, mostly Value,
Location, Type, OpBuilder,
Block, and Region. An API-compatible core
would keep the ~1,300 XOp::create calls, which depend only
on generated signatures. The .td files are TableGen data,
but they carry 818 embedded C++ blocks (521 mlir::
references) and declare MLIR interfaces, so they are reusable only with
a source-compatible core.
The real cost is everything else: an IR core; an ODS-equivalent
emitter including the assembly-format generator (the MLIR emitters it
replaces are ~14K lines, plus 5K in mlir/lib/TableGen); the
interfaces; 15K lines of passes rewritten off MLIR's drivers; and the
868 -emit-cir tests reproduced byte for byte or churned.
CIR would also lose MLIR's reviewers; Lauko was nominated as
maintainer for "overseeing the quality of CIR dialect (the MLIR part)".
The gains: most of MLIR's ~881 s of build work, no conversion step or
extra IR copy, SourceLocation as the location type, memory
freed with the module, and no MLIR API churn.
OpenACC forces one of three choices: drop it, duplicate Flang's
acc pipeline, or keep MLIR as an optional island reached
through LLVM IR metadata. Only Keane's one fallback sentence supports
the third; the route (metadata, then ModuleImport, then
acc ops, then the shared passes) is my extrapolation, and I
found no work on it.
So an MLIR-free CIR is technically plausible, but it removes the property the funders want, and I see nobody who would fund it. Its value is as a lens. It separates what only leaving MLIR fixes (immortal context uniquing, the volume of ODS-generated code, the core library closure) from what can be fixed inside MLIR.
Conclusion
Clang needs a better IR than the AST and the CFG, and CIR is the one
that got funded. Who funds Clang has changed, and that explains much of
this post. Commits under clang/ by employer:
| Year | Commits | Apple | Red Hat | NVIDIA | AMD | personal email | |
|---|---|---|---|---|---|---|---|
| 2016 | 5,250 | 33% | 17% | 0% | 0% | 2% | 19% |
| 2020 | 5,523 | 30% | 9% | 1% | 0% | 4% | 20% |
| 2024 | 7,330 | 11% | 4% | 12% | 4% | 4% | 29% |
| 2026 (to October) | 7,160 | 7% | 5% | 8% | 10% | 8% | 34% |
(Employer is the email domain, or, for a personal address, the company whose address the same author used in the same period. I also assigned the personal addresses of a few people I know were at Google or Apple then: Richard Smith, Chandler Carruth, David Majnemer, Benjamin Kramer, Nico Weber, Haojian Wu, and Sam McCall at Google; Argyrios Kyrtzidis and Bruno Cardoso Lopes at Apple. "Personal email" is what remains at gmail.com and similar.) Google and Apple, whose priorities were large C++ code bases, compile time, and tooling, went from half of Clang commits to 12%. Red Hat's share is mostly Timm Bäder's bytecode constant expression interpreter. NVIDIA's is mostly CIR (3% of commits outside CIR), and its Clang people came from elsewhere: Erich Keane (from Intel, 2023), Andy Kaylor (from Intel, 2025), Reid Kleckner (from Google, 2026). AMD's is mostly AMDGPU, HIP, and offloading work.
The new funders build GPU and accelerator compilers, and their other compilers (Flang, Triton, IREE, their own stacks) are built on MLIR. For them, a Clang that emits an MLIR dialect is the point, not an implementation detail. For the C++ programmers who were Clang's main constituency, CIR has to earn its place by being better at what the AST, the CFG, and classic CodeGen do today: diagnostics, safety analyses, and optimizations that need C++ semantics, without making the compiler slower to build or run. Lifetime safety went to the CFG in 2025 rather than wait for CIR, which shows the bar is real.
The question was never really whether CIR should use MLIR. It is
whether anyone is funded to keep the cheap path cheap. Today the
measurable costs fall on Clang contributors and users, most heavily on
those who build on their own machines, while the benefits of MLIR accrue
to the organizations funding CIR. Tracking -fclangir on
c-t-t, keeping -DCLANG_ENABLE_CIR=Off working, and landing
the cheap build fixes in Reducing the
cost are how the people paying the cost get something back.