28  Type Conversion

A TypeConverter defines how a conversion changes the type of values. It is the representation map that makes a dialect conversion coherent across producers, users, block arguments, and function signatures.

28.1 A Mapping Is More Than One Function

A simple converter maps one old type to one new type, such as index to a target-selected integer. More complex conversions may expand one type into several values, drop an empty representation, or require context-sensitive materializations. The mapping must be consistent wherever the converted type appears.

Changing an operation result without converting its uses is not type conversion; it is invalid IR. The framework uses the converter to adapt operands presented to conversion patterns and to update block signatures, function interfaces, and region boundaries when the relevant patterns support them.

28.2 Materialization Bridges

At a temporary boundary, an old value may need a target representation or a new value may need to be viewed in an old representation. A materialization is an explicit operation that creates that bridge. It must have defined semantics: a tensor-to-memref bridge, for example, has aliasing and ownership consequences that a generic cast cannot erase.

Avoid materializations that merely silence a verifier. They can conceal an incomplete conversion and leave illegal types indefinitely. A mature conversion reduces bridges as adjacent operations become legal in the same representation.

28.3 Signatures And Blocks

Function arguments, results, block arguments, branch operands, and region terminators all carry types. A conversion that changes a function parameter must also update calls and its entry block. A conversion that changes a block argument must update every predecessor edge. These connected edits are why MLIR provides signature-conversion support instead of asking patterns to mutate each list by hand.