Tips on debugging MLIR

Hi folks, i’m just learning MLIR and have been stepping through example in the debugger to learn about the internals of the project. I looked for some tips/tricks on debugging and stepping through the MLIR complier (mlir-opt.exe), but what i found here and on the MLIR documentation page was not as detailed as i was hoping to find.

I wanted to start a thread here for folks to share their techniques and insights. I personally am debugging on Windows (via Visual Studio), but i’m sure that development environments are varied, so i’m sure that’s lots of different techniques to share.


ian Bearman
Principal Software Engineering Manager
Microsoft Visual C++ Team: Optimization & Code Generation
/* Making your code faster, smaller, smarter! */

@benvanik has a pretty good windows/vc debugging flow that he was showing me on chat the other day. I remember him mentioning the value typing and other coding style things being a challenge without some debugger helpers but we didn’t go into details.

Yeah, it’d be really good to have a natvis file for MLIR that made it possible to resolve all the uniqued types (mlir::Operation, mlir::Value, mlir::Type, mlir::Attribute, etc). They are really painful to work with otherwise :slight_smile:

I’m not sure if multiple visualizer files can be used, or if LLVM has one of its own for llvm::StringRef/etc.

(vscode docs note that the natvis files work for gdb/lldb debugging too, which is awesome!)

1 Like

Here’s my shortlist when debugging an error (might not be as useful for someone who is just exploring the codebase). Most of this involves running mlir-opt on the command line to probe issues:

First resorts:

  • -print-ir-before-all to stare at IR before each pass (there is also a corresponding -print-ir-after-all.
  • run just the single pass of interest on the IR that was printed
  • -verify-each=0 disables verification, which can let you stare at IR even if it fails the verifier somewhere (sometimes useful)

Other really useful options:

  • -mlir-print-stacktrace-on-diagnostic prints a stacktrace so you can see where in the code was emitting the diagnostic
  • -mlir-print-op-on-diagnostic to see the op that a diagnostic was emitted on, exactly as it was when the diagnostic was issued
  • for dialect conversion, -debug-only=dialect-conversion shows very useful information about what happened during conversion.

The particular combination of --verify-each=0 --mlir-print-op-generic is often useful for debugging verifier errors which happen during development of a dialect. Many transformation bugs are (unfortunately) obfuscated by the pretty-printing process.

1 Like

A couple of my gotos:

  • --pass-pipeline-crash-reproducer=/tmp/somefile.mlir to dump a file with a comment at the top with mlir-opt (or equiv) repro command line. I often find that when a high level tool produces an error/crash, it is more effective to drop into *-opt to debug in detail
  • -debug-only=mydebugtag coupled with use of the LLVM_DEBUG facility to just get debug info for things you are working on
1 Like

If someone wants to gather these info and send a PR for the website (maybe starting the FAQ?)

1 Like

It ended up growing past something that would make sense in the FAQ. Added a new


Any idea if a .natvis for MLIR types is available at this moment? I don’t see further information about it on this thread. Thanks.

Not AFAIK. We’ve done some work for prettier GDB results and would gladly welcome an addition here (I had to look up .natvis though so I’m not the most knowledgeable but I’ve not seen any proposal).

Seems like there is a patch for review for a .natvis:

Yep! That’s from my colleague Kirsten. She put this together to help our team debug and we believe it will be helpful for anyone using Visual Studio to debug MLIR compilation. We’re excited to make our first contribution back to MLIR :slight_smile: