<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54859>54859</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[MLIR] Dependent dialects of passes in dynamic pass pipelines are not loaded
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
rrbutani
</td>
</tr>
</table>
<pre>
## what
Since f9dc2b7079350d0fed3bb3775f496b90483c9e42, passes are encouraged to register the dialects they depend on with `getDependentDialects`. Dialects that are registered this way are then loaded by [`PassManager::run`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L663-L668) (which ultimately [calls `OpToOpPassAdaptor::runPipeline`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L393-L395) to actually run the passes in the pipeline).
This works well for ordinary pass pipelines but doesn't seem to work for _dynamic_ pass pipelines that are added using [`Pass::runPipeline`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/include/mlir/Pass/Pass.h#L191-L196). Pipelines that are run this way are executed via the registered [`pipelineExecutor`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/include/mlir/Pass/Pass.h#L195) ([this lambda](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L376-L395)) which then calls [`OpToOpPassAdaptor::runPipeline`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L393) without loading dependent dialects. This leads to errors when dynamic pass pipeline passes try to use their dependent dialects.
Is this intended behavior? If not, it _seems_ like adding [these lines](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L663-L668) to [`dynamicPipelineCallback`](https://github.com/llvm/llvm-project/blob/64d3e163d8e35d2d67e060c1bd5a1f1e8d7cfa8f/mlir/lib/Pass/Pass.cpp#L388) would yield the expected behavior.
## example
Here's a small program that reproduces the error:
```c++
#include "mlir/Dialect/AMX/AMXDialect.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/DialectRegistry.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Pass/PassManager.h"
namespace m = mlir;
struct PassWithDependentDialects
: public m::PassWrapper<PassWithDependentDialects,
m::OperationPass<m::func::FuncOp>> {
void getDependentDialects(m::DialectRegistry ®istry) const override {
llvm::errs() << "! PassWithDependentDialects deps\n";
registry.insert<m::amx::AMXDialect>();
}
void runOnOperation(void) override {
m::OpBuilder b(getOperation());
b.create<m::amx::TileZeroOp>(
/* loc: */ getOperation()->getLoc(),
/* ret: */ m::VectorType::get({1, 1}, b.getF32Type())
);
}
};
struct ExamplePass
: public m::PassWrapper<ExamplePass,
m::OperationPass<m::ModuleOp>> {
static std::unique_ptr<m::OperationPass<m::ModuleOp>> create() {
return std::make_unique<ExamplePass>();
}
void getDependentDialects(m::DialectRegistry &_registry) const override {
llvm::errs() << "! ExamplePass deps\n";
}
void runOnOperation(void) override {
m::ModuleOp f = getOperation();
m::OpPassManager pipeline(m::ModuleOp::getOperationName());
pipeline.nest<m::func::FuncOp>().addPass(std::make_unique<PassWithDependentDialects>());
if (m::failed(runPipeline(pipeline, f.getOperation()))) {
return signalPassFailure();
}
}
};
int main(int argc, char **argv) {
m::MLIRContext context;
context.getOrLoadDialect<m::func::FuncDialect>();
auto input = R"(
module {
func.func @test(%x: i64) -> i64 {
return %x : i64
}
}
)";
m::OwningOpRef<m::ModuleOp> module = m::parseSourceString<m::ModuleOp>(input, &context);
m::PassManager pm(&context);
pm.addPass(ExamplePass::create());
if (m::failed(pm.run(module.get()))) {
module->emitError();
return 1;
}
module->dump();
}
```
`PassWithDependentDialects` is a (nonsensical) pass that makes use of an unregistered dialect; despite registering it in its `getDependentDialects` method, it encounters a runtime error when trying to create an op in the `AMX` dialect.
### example, as a Bazel workspace
[Here](https://github.com/llvm/llvm-project/files/8469736/dynamic-pipeline-example.zip) is a nix flake/Bazel workspace with the above (`nix develop` + `bazel run //:example`).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzVWUtv4zgS_jXKhYghS37p4ENsdzANdE8a6cbuYi8BJVI2p_Uaikri-fXzFUVZcqJkkkUfsoEgyRRZ7_qKxcSlOK69IMTFHg7ceP7O86_a-3dVJJKlkUiCeOkvo3DuCz-VIozjcLmcp7NoEUf-bBUmkZwFXrBlFa9rWTOuJZNFUjaa76VgpmRa7lVtpGbmIJlQPJOJqenHkQlZyUKwsmAPyhyYt_D30uzsoCzMzs3F8ITt-oXcWC4dXeJyUDV74Ec7DsoFy0ou8CE-Mm--AYFvkO4rLyCT9sIrXLopMOzNd16wOhhT1TQcXOPaQ5QmniRljh9Zdt89Litd_gER8DPOyhiPxUyEcroIxUqGcxGIxVL6Cz-ZxmLOp-lUrsQySfkqxdQ8U5roKFpHwrjHJKkq2P_LYhFe4rbygohBooeDSg6syYzKuZGZ1SLhWVaTjW6qH-VNRauvBK9M2Wv0TVUyU4X8SJqFETQLozlphmjgiWmgyJFBXBsRLm6U-9VpEESTYTz-sB4u9U_cZZaxtNSs1EIVXB8tidPKmsWNYaKUdeEFS8NqKXNiTIvtsjtxLHiukrun606RxQXFTlOrYj8In49gZWRl1gjZDwwNfiBzT6PpJW4LMiD79ly31uyDdJGPMmkM9L1X3LpgkFet8p2FPtmZCLePqffc5Q6EtgpmPI8F_zh5sFx0eUCCthluscoltrX1_11uW13Au0TSEehSzogOwU9wP2E2gTPJRU3JKLUuNWKQ1HfpeJ6NHSwYpDfmN7XFdaXHaA9x4nPdRrcqDE1DBZAHfq_Ijtfsc8qK0lCxUobdETDUdyxTP23Gu2QHF_CySfNhzDwsDjBGGynObF1YbBFEMU9-fqjwWFmRH8omE-yoZCYswMjHChwHvjnzoNuQyEeeV5kcfvkNmARIxx6D1TnUZZB9r3negpuW-CmaxIKdbCOM1G8JwCr2SrxgQ1fHygELcCNw2riNBt6uvv6nvbshAprgTSuvmwKMrj_fuvebqv6nxXbuplEo-cWVMVqhisl3rXonkx_H6o3036j-cO6trSH6-KY1X798vt2WSNjHf-TxBPZfn6pr2b-8g7LbJw5X2DvyTdYVx744Z164Y3ZluBlOgc5NYhhR-Tcy7vlW1s5i-ENosqqJMwBf3mK8XaR5VdEWdfsyiWDbU3nlz1G9ATluVFm0W5itG04pQu1bG59e-AkX85abjvh9qQQb3Y4HK0fkibNhzYV275T3SVnUhpX3SEVFtu5pM2YhyBLBVyJpi3e4xUVO8YLpy0akGgBw3hY0MRwQ7ZhPVAGPm15bnj-2L30yk8KW64CCt9wNnelsgNp7U5zMiEU0SuKOa3ayO-WZQNsDcFzBjkMK7R7gTHZgs5bY648I_UNl8r9Sl62XsPrM_Rbfr1B7yZ_4RYDPnvO7xFqMfsE0x387SkdLM6DjRPkXDFZqQoz2NwgRleVmSsV0SnbDM55g_DoM7LyTkn3Ev2BrvIwm0ae2Ati4fXPaDBf9kkT5ipqSyecJ0pGuDRYleIh2flOoPxt5Vxnd03gbaed_lwrLs7g2jS56Hjn_Ke9aRk9UfnNQvzux735hZg8kfiGXf2UmdmZmqUXtkVQMx9J3UAkGXenqme9cPpxo_o4q8TzFewYdrQl2mOZ1QLZUJtibtuG8eiEAXi4Vp3AYlUSlrFco5UAZGHM1bDWCVa_5lqWTcRhrG5oz0_cxq_YFz0jCazBotBwx-cnZr6ICdvQs54r40ivX-4SESg5ct2h1haH7J5J03up3GBS79BxI4EasdvoLephTiRh3zosVpCPI0SWjA6nQElHE3dqwH8B2boPnqcWIyYRuzJv5hoKDqM-pCDC1mJFmBOL0_nTpydw0n3ULBhMGJj63N_lumHhd-D8U6IduqluZjuLVSQXaBrVfK9pmfS8bncjv2L4W-3GgI-_BMOQ6oErnjBEjDuD9lIa5NcnYKuRVPsiUM0wkMkNwHeM2ngugSeeE-GA1mLi692LYt9PISzJX5pNtQZ7Hu_PV9DW86ymJJq-extlpdtfWnDVQ7XHVOCIsfKaogQLFAiAui1olPCNFbPttOylCl9q23GXKeMGaYnAkJLrg3wC660qZ_sCIOmg01qrAvX7lMJfl0hxK4fpwe1gMf2oSC9Y2KnfdW3s8gJJDhJFRrQ9JorLqzgtBjto0EHWCjfSSw3YSPDkx2vC_ZNYeKNKO_mzRfGM7zf-ti04ROtRIrGaLaBku8OYa9csOSi-dLJO_VEWGt_4o1CNLMxieGrRz2dqzcVKWxyh09ohr4dMCIe9lVlakPXpaskVsl9IZXyswVWGnOYIExeRCrEMRhRG_MMpkcg1lCRyhLNs9O1kh__fHs6PnNO2Bf1Ead-J-0ehs_W6jqbpurNXms9U8ujisRTpPw3nE6V8M0k_iKJrPwkAEQbiQs0iuLjIey6wm8YFfhXxglgRh2Xx3odaBHwT-bBr48-ks9Cd-HHPprwTHI13BKzNfopZkE5JjUur9hV5bkeJmX-Njhniu-49QGGVMWmsRfeD7odRrrdGj80JdWN5rK_vfEKmp5w">