I had an issue building an MLIR project, mainly with the following function:
static void addPotentiallyNestedPass(mlir::PassManager &pm,
std::unique_ptr<Pass> pass) {
if (!pass->getOpName() || *pass->getOpName() == "builtin.module") {
pm.addPass(std::move(pass));
} else {
pm.nest(*pass->getOpName()).addPass(std::move(pass));
}
}
The program was segfaulting at pm.nest(*pass->getOpName()).addPass(std::move(pass))
A non-obvious fix (to me at least) was to first get the reference to the OpPassManager
then call addPass
static void addPotentiallyNestedPass(mlir::PassManager &pm,
std::unique_ptr<Pass> pass) {
if (!pass->getOpName() || *pass->getOpName() == "builtin.module") {
pm.addPass(std::move(pass));
} else {
mlir::OpPassManager& p = pm.nest(*pass->getOpName());
p.addPass(std::move(pass));
}
}
I tried to find out why the segfault was happening, and found out in the assembly code of the function that there is no actual call to the nest
method, and the corresponding assembly was as follow
10unique_ptrINS_4PassESt14default_deleteIS5_EE+342> mov rax,QWORD PTR ds:0x10 <-- Segfault │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+350> mov QWORD PTR [rbx],0x0 │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+357> mov QWORD PTR [rsp],rax │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+361> mov rax,QWORD PTR ds:0x18 │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+369> mov QWORD PTR [rsp+0x8],rax │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+374> mov rax,QWORD PTR ds:0x20 │
│10unique_ptrINS_4PassESt14default_deleteIS5_EE+382> ud2 <-- Why is this even here?
It’s worth noting that the initial code was working fine with c++ 10.3. However, it started segfaulting when I tried it on the docker image quay.io/pypa/manylinux_2_24_x86_64
based on Debian 9, having c++ 6.3
Everything works fine with the new code, but I’m just curious to know if the initial code was actually bad, or why this set of erroneous instructions were generated