MLIR dialects and operations
A dialect namespaces operations, types, and attributes, and can own interfaces and pass pipelines; it is not a separate IR.
One tree of operations
An MLIR module is a tree of operations, and each op name is a dialect namespace, a dot, and the op name:
func.func @scale(%x: memref<4xf32>) {
%c0 = arith.constant 0 : index
%cst = arith.constant 2.0 : f32
%v = memref.load %x[%c0] : memref<4xf32>
%s = arith.mulf %v, %cst : f32
memref.store %s, %x[%c0] : memref<4xf32>
return
}
Three dialects — func, arith, memref — interleave in one block with no boundary between them. Nothing converts arith to memref for the last line to work. They coexist because there is one IR, not one per dialect. A dialect owns the operations, types, and attributes whose names it prefixes, and the context loads registered dialects on demand. builtin is always present and prints without its prefix: the module at the top of the file is builtin.module.
What the namespace does not do
A dialect does not partition the IR, create a conversion boundary, or imply a level. arith.addi and arith.muli are no more related than arith.addi and scf.for. A pass that must work across dialects matches on traits or interfaces, never on the prefix.
Registration matters at parse time. An op whose dialect is unknown fails to parse unless you pass --allow-unregistered-dialect, in which case it is kept as an opaque operation and printed generically:
"my.thing"(%0) : (f32) -> f32
Same operation, no custom assembly. The quotes are the tell that the tool did not know the dialect. Confirm the flag on your pinned release with mlir-opt --help.
Things that break
--allow-unregistered-dialect turns a misspelled op name into a valid opaque op: no verifier runs, no pattern matches it, and the failure surfaces much later as IR that quietly stopped changing. Confirm the name is registered before debugging the pass. In the other direction, a quoted op in output means the tool lacked that dialect, not that the IR is malformed.
Sources
- MLIR Language Referencedocs · LLVM 19
- Operation Definition Specification (ODS)docs · LLVM 19
- MLIR CodeGen Dialects for Machine Learning Compilersblog
A version records the documentation the claim was checked against, not a house pin. Confirm flags with --help on the release you installed.
Check yourself
`mlir-opt` prints `"my.thing"(%0) : (f32) -> f32`. What does the quoting mean?
A function body contains `arith`, `tensor` and `linalg` ops with no conversion between them. What is wrong?
Which of these does a dialect not define?