Skip to content

Util

-iree-util-annotate-op-ordinalslink

Annotates ops with globally unique IDs for debugging.

-iree-util-apply-patternslink

Applies some risky/IREE-specific canonicalization patterns.

-iree-util-attribute-call-graphlink

Propagates attributes from callees to call sites.

Walks all call operations and propagates relevant attributes from the called functions to the call sites. This includes: * Attributes implementing CallAnnotationAttrInterface * nosideeffects (for side-effect analysis)

This allows subsequent passes to check attributes directly on call sites without expensive symbol table lookups during analysis.

-iree-util-combine-initializerslink

Combines global initializers into one.

-iree-util-drop-compiler-hintslink

Deletes operations that have no runtime equivalent.

Deletes operations that have no runtime equivalent and are only used in the compiler. This should be performed after all other compiler passes.

With keep-assume-int=true, leaves util.int.assume operations in place so they can be propagated to backends. This is a temporary measure until all bbackends have a rewrite for those assumptions (currently they're only handled by the patterns that target LLVM).

Optionslink

-keep-assume-int : Whether annotations about the ranges and divisibility of integers should be kept.

-iree-util-dump-modulelink

Dumps the module IR to the given file path.

Dumps the module IR to the given file path in either textual (.mlir) or binary (.mlirbc) format. Source locations remain unchanged.

Optionslink

-path : File path to write the module text or binary into.

-iree-util-fixed-point-iteratorlink

Iterates a sub-pipeline to a fixed point.

-iree-util-fold-globalslink

Folds duplicate globals and propagates constants.

Statisticslink

global ops before folding : Number of util.global ops before folding
global ops after folding  : Number of util.global ops after folding

-iree-util-fuse-globalslink

Fuses correlated globals together.

-iree-util-hoist-into-globalslink

Greedily hoists eligible constant expressions into globals.

Optionslink

-max-size-increase-threshold : Maximum byte size increase allowed for constant expr hoisting policy toallow hoisting. The threshold is 1MB by default.

-iree-util-import-resourceslink

Imports IR with arbitrary large-data into resources that IREE can manage efficiently

MLIR has many interesting ways to store large constants, most of which derive from *ElementsAttr. Given the uniquing/inline behavior, this exacts very large runtime and memory overhead costs.

This is a temporary pass to convert a majority of the legacy DenseElementsAttr attributes to DenseResourceElementsAttr. Ideally this is done at the source (frontend), but this pass is provided to aid transition and testing by doing a manual conversion with iree-opt.

-iree-util-ipolink

Performs basic inter-procedural optimization.

-iree-util-lift-cfg-to-scflink

Lift unstructured control flow to SCF/Util dialect for callable ops.

Transforms unstructured control flow (CFG) in util.initializer/util.func ops to structured control flow (SCF) operations. All CFG terminator ops like cf.br and cf.cond_br along with non-terminator ops like cf.switch are converted to their structured equivalents like scf.if, scf.while, and scf.index_switch ops.

Limitations: * Irreducible control flow (loops with multiple entry points) will cause the transformation to fail. This is rare in practice as most high-level languages and ML frameworks generate reducible control flow. * Operations with side-effecting branches are not supported. * Operations that produce successor operands dynamically are not supported. * Infinite loops require the insertion of util.unreachable terminators.

The algorithm handles: * Simple if/else patterns -> scf.if * Loops with single entry -> scf.while * Switch statements -> scf.index_switch * Multiple returns -> exit block combining * Unreachable code -> util.unreachable insertion

Based on the algorithm from: Bahmann et al. 2015. Perfect Reconstructability of Control Flow from Demand Dependence Graphs. ACM TACO. https://dl.acm.org/doi/10.1145/2693261

Links external functions from source modules into the target module.

Resolves external function declarations by loading definitions from source modules. This pass enables composing programs from multiple MLIR modules where functions can reference implementations from separately compiled modules using dotted name scoping (e.g., @module_a.compute).

For each external function in the target module:

  1. Searches for the definition in explicitly provided source modules
  2. If not found and the symbol has a module prefix (@prefix.name) attempts to automatically load prefix.mlir or prefix.mlirbc from library paths
  3. Clones the function definition along with transitive dependencies (including IREE::Util::ObjectLike operations like flow.executable)
  4. Detects and resolves conflicts between private symbols from different source modules or with existing target module definitions by renaming conflicting symbols (e.g., @scale_factor, @scale_factor_0)
  5. Renames imported symbols to match the external declaration name
  6. Forces all imported symbols to private visibility

ObjectLike operations (such as flow.executable) are treated as self-contained units: their internal structure is preserved but not scanned for additional dependencies, preventing nested symbols from being treated as external references.

Module name scoping: Source modules with module @foo { util.func @bar } export public symbols as @foo.bar. Private symbols keep their local names. Internal references within the module use the simple name @bar, while external references use the dotted notation.

Supports both text (.mlir) and bytecode (.mlirbc) formats for all modules.

Optionslink

-link-module  : Explicit paths to source modules to link from.
-library-path : Directories to search for modules during automatic discovery.

-iree-util-optimize-int-arithmeticlink

Optimizes integer arithmetic using a variety of dataflow analysis and patterns.

Optionslink

-narrow-to-i32 : Flag indicating if computations that can be performed with 32 bits should be. Mainly used for GPU code generation to not waste registers.

-iree-util-propagate-subrangeslink

Propagates resource subranges across the program.

-iree-util-simplify-global-accesseslink

Hoists loads and sinks stores to variables to decrease data dependency regions.

-iree-util-strip-and-splat-constantslink

Strips constant util.global ops and replaces them with splats.

-iree-util-strip-debug-opslink

Strips debug ops, like assertions.

-iree-util-test-conversionlink

Tests util dialect conversion patterns.

Optionslink

-widen-integers        : Tests type conversion by widening integers to i32.
-structural-conversion : Tests generic structural conversion ops.

-iree-util-test-float-range-analysislink

Tests floating point range analysis.

Tests floating point range analysis by evaluating any 'iree_unregistered.test_fprange' op and setting the results on an attribute.

-iree-util-verify-initialization-orderlink

Verifies module initialization order constraints.

Verifies that module initialization follows the rules documented in the util.initializer and util.global operations:

  1. Initializers can only access globals defined before them in module order.
  2. Immutable globals can only be initialized once (either by initial_value OR by stores in initializers, never both).
  3. Globals with initial values cannot be modified by initializers that precede them in module order.
  4. Stores to immutable globals must occur in initializers or functions only reachable from initializers.

The pass uses conservative analysis and emits warnings for patterns it cannot definitively verify (e.g. conditional stores in initializer-only functions).

-iree-util-verify-structured-control-flowlink

Verifies that functions contain only structured control flow.

Verifies that functions contain only structured control flow (no ops implementing BranchOpInterface like cf.br or cf.cond_br).