Adding a new pass to the new PM degrades vectorisation

I’ve written a new pass and added it to the new pass manager as a plugin using the following code:

llvm::PassPluginLibraryInfo getAliasHintsPassPluginInfo() {
  return {LLVM_PLUGIN_API_VERSION, "AliasHints", LLVM_VERSION_STRING,
          [](PassBuilder &PB) {
            PB.registerLateLoopOptimizationsEPCallback(
                [](llvm::LoopPassManager &LPM, OptimizationLevel Level) {
                  LPM.addPass(AliasHintsPass());
                });
            PB.registerPipelineParsingCallback(
                [](StringRef Name, llvm::LoopPassManager &LPM,
                   ArrayRef<llvm::PassBuilder::PipelineElement>) {
                  if (Name == "aliashints") {
                    LPM.addPass(AliasHintsPass());
                    return true;
                  }
                  return false;
                });
          }};
}

#ifndef LLVM_ALIASHINTSPASS_LINK_INTO_TOOLS
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
  return getAliasHintsPassPluginInfo();
}
#endif

For some reason, building LLVM with -DLLVM_ALIASHINTSPASS_LINK_INTO_TOOLS=ON changes how vectorisation is done. I’ve noticed by looking at the IR output of clang -O3 for the linalg benchmark in coremark-pro that no loop versioning happens when my pass is enabled (i.e. loops being guarded with a runtime check against aliasing and then split into a vectorised and sequential version) when it did happen before.

If I recompile the same commit with -DLLVM_ALIASHINTSPASS_LINK_INTO_TOOLS=OFF, clang goes back to versioning the loops and generating much more vectorised code.

Having the loop versioning emitted by vectorisation passes is a big help in achieving the results I’m going for as it allows me to exploit the noalias metadata inserted. Is anyone able to help explain what’s happening?

The issue is likely something your AliasHintsPass is doing, not how it gets added, so without seeing the actual pass it’s impossible to tell what’s going wrong.

I’d recommend you check what changes your pass makes.

But I’ve registered my pass as a late loop optimization, so it ought to run after vectorisation anyway right?

All my pass does is change the address spaces of various loads by adding addrspacecast instructions above them.

Ok, my mistake - I tried setting the address space I change loads to to 0 and vectorisation happens again as normal now. I didn’t think changing the address space would have this big an impact?

Do you know of any way to make sure the vectorisation process I’m interested in happens before my pass runs? If not my easiest solution here might be to manually run my new pass with opt for now. Using address spaces is already a hack to communicate with the backend anyway so this doesn’t need to be production grade.