PassManager::nest generating weird asm

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

Could it be that this compiler somehow evaluated the std::move before the nest? That seems weird though. The assembly snippet with ud2 generally indicates some undefined behavior somewhere.

I don’t quite get what function is the assembly for? 10unique_ptrINS_4PassESt14default_deleteIS5_EE is a partial name and does not seem to match addPotentiallyNestedPass?

Yeah, I couldn’t get all the line due to character limit, but it’s definitely the addPotentiallyNestedPass

Could you try running with ubsan and asan?