llvm / llvm/llvm-project

[mlir] `MLIRContext::getLoadedDialect` asserts when using TD schedule

Open
#179,247 2 comments 0 reactions 1 assignee Claimed by @banach-space View on GitHub
mlir mlir:transform_dialect
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

### OVERVIEW

I hit the following assert: https://github.com/llvm/llvm-project/blob/02804501af9c764126964a965c02dbee84690227/mlir/lib/IR/MLIRContext.cpp?plain=1#L420-L422

while running [ConvertToLLVM](https://github.com/llvm/llvm-project/blob/02804501af9c764126964a965c02dbee84690227/mlir/lib/Conversion/ConvertToLLVM/ConvertToLLVMPass.cpp) and [ConvertToEmitC](https://github.com/llvm/llvm-project/blob/02804501af9c764126964a965c02dbee84690227/mlir/lib/Conversion/ConvertToEmitC/ConvertToEmitCPass.cpp), **via** Transform Dialect's [transform.apply_registered_pass](https://mlir.llvm.org/docs/Dialects/Transform/#transformapply_registered_pass-transformapplyregisteredpassop).

**NOTE:** No assert is hit when _invoking the passes directly_ via `mlir-opt`, i.e.
```bash
mlir-opt -convert-to-{emitc|llvm} file.mlir
```

This implies that there is an issue with how dialects are registered when using Transform Dialect.

**Expected behavior:** `transform.apply_registered_pass` should behave equivalently to invoking the same pass via `mlir-opt`.

### HOW TO REPRODUCE

Take one of the examples below and run:
```bash
mlir-opt -transform-interpeter file.mlir
```

While I am able to reproduce this reliably on my M3 Pro using Apple clang version 16.0.0, it does not reproduce in Compiler Explorer:
* https://godbolt.org/z/1ox78rzsr

It does, however, reproduce in LLVM's pre-commit CI, as documented here:
* https://github.com/llvm/llvm-project/pull/177339#issuecomment-3786626607

Note that in pre-commit CI the assertions is hit for **X86**, but not for **AArch64**.

LLVM version locally: 59f815b047c8

### REPRO EXAMPLES
**EXAMPLE 1 (ConvertToLLVM)**
```mlir
module {
func.func @foo(%arg0: vector) -> vector {
%0 = vector.bitcast %arg0 : vector to vector
return %0 : vector
}
}

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%module:
!transform.any_op{transform.readonly}) {

%func_h = transform.structured.match ops{["func.func"]} in %module
: (!transform.any_op) -> !transform.any_op
%module_h = transform.get_parent_op %func_h {isolated_from_above} : (!transform.any_op) -> !transform.any_op

// NOTE THE PASS BELOW!
transform.apply_registered_pass "convert-to-llvm" to %module_h
: (!transform.any_op) -> !transform.op<"builtin.module">

transform.yield
}
}
```

**EXAMPLE 2 (ConvertToEmitC)**

```mlir
module {
func.func private @foo(%arg0: memref<2xf32>, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%c0 = arith.constant 0 : index
%c2 = arith.constant 2 : index
%c1 = arith.constant 1 : index
scf.for %arg3 = %c0 to %c2 step %c1 {
%0 = memref.load %arg0[%arg3] : memref<2xf32>
%1 = memref.load %arg1[%arg3] : memref<2xf32>
%2 = arith.addf %0, %1 : f32
memref.store %2, %arg2[%arg3] : memref<2xf32>
}
return
}
}

module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%module:
!transform.any_op{transform.readonly}) {

%func_h = transform.structured.match ops{["func.func"]} in %module
: (!transform.any_op) -> !transform.any_op
%module_h = transform.get_parent_op %func_h {isolated_from_above} : (!transform.any_op) -> !transform.any_op

// NOTE THE PASS BELOW!
transform.apply_registered_pass "convert-to-emitc" to %module_h
: (!transform.any_op) -> !transform.op<"builtin.module">

transform.yield
}
}
```

### NEXT STEPS

I am not that familiar with the TD infra and would appreciate some pointers. @ftynse , any suggestions?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.