New pass manager and memory sanitation issue

Following the documentation, I’ve created a small IR optimiser which adds a FunctionPass to a ModulePassManager using . This causes a segfault.

The code is:

#include "llvm/IRReader/IRReader.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Transforms/Scalar/InstSimplifyPass.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"

#include <iostream>
using namespace llvm;

int main(int argc, char **argv)
{
  llvm::ModuleAnalysisManager   module_analysis_manager;
  llvm::LoopAnalysisManager     loop_analysis_manager;
  llvm::FunctionAnalysisManager function_analysis_manager;
  llvm::CGSCCAnalysisManager    gscc_analysis_manager;

  llvm::PassBuilder pass_builder;
  pass_builder.registerModuleAnalyses(module_analysis_manager);
  pass_builder.registerCGSCCAnalyses(gscc_analysis_manager);
  pass_builder.registerFunctionAnalyses(function_analysis_manager);
  pass_builder.registerLoopAnalyses(loop_analysis_manager);

  pass_builder.crossRegisterProxies(loop_analysis_manager, function_analysis_manager,
                                    gscc_analysis_manager, module_analysis_manager);

  llvm::ModulePassManager mpm;

  mpm.addPass(createModuleToFunctionPassAdaptor(llvm::InstSimplifyPass()));

  /*
  // Issue also occurs with:
  llvm::FunctionPassManager fpm;
  mpm.addPass(createModuleToFunctionPassAdaptor(std::move(fpm)));

  // Or
  llvm::FunctionPassManager fpm;
  fpm.addPass(llvm::SimplifyCFGPass());
  mpm.addPass(createModuleToFunctionPassAdaptor(std::move(fpm)));
  */

  std::string             input_file = "./test.ll";
  LLVMContext             context;
  SMDiagnostic            err;
  std::unique_ptr<Module> module = llvm::parseIRFile(input_file, err, context);
  if (!module)
  {
    llvm::errs() << "Failed to load " << input_file << "\n";
    return 0;
  }

  mpm.run(*module, module_analysis_manager);

  return 0;
}

It is compiled with:

	clang++ -std=c++14 -fno-omit-frame-pointer -fsanitize=address,undefined -g -O0 -fno-sanitize-recover=all -I/usr/local/opt/llvm@13/include/  -L/usr/local/opt/llvm@13/lib -o test \
	-lm /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/lib/libz.tbd /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/lib/libcurses.tbd \
	/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/lib/libffi.tbd  \
					/usr/local/opt/llvm@13/lib/libLLVMCore.a \
					/usr/local/opt/llvm@13/lib/libLLVMIRReader.a \
					/usr/local/opt/llvm@13/lib/libLLVMPasses.a \
					/usr/local/opt/llvm@13/lib/libLLVMCoroutines.a \
					/usr/local/opt/llvm@13/lib/libLLVMipo.a \
					/usr/local/opt/llvm@13/lib/libLLVMAsmParser.a \
					/usr/local/opt/llvm@13/lib/libLLVMInstrumentation.a \
					/usr/local/opt/llvm@13/lib/libLLVMVectorize.a \
					/usr/local/opt/llvm@13/lib/libLLVMFrontendOpenMP.a \
					/usr/local/opt/llvm@13/lib/libLLVMLinker.a \
					/usr/local/opt/llvm@13/lib/libLLVMJITLink.a \
					/usr/local/opt/llvm@13/lib/libLLVMCFGuard.a \
					/usr/local/opt/llvm@13/lib/libLLVMGlobalISel.a \
					/usr/local/opt/llvm@13/lib/libLLVMSelectionDAG.a \
					/usr/local/opt/llvm@13/lib/libLLVMMCDisassembler.a \
					/usr/local/opt/llvm@13/lib/libLLVMExecutionEngine.a \
					/usr/local/opt/llvm@13/lib/libLLVMRuntimeDyld.a \
					/usr/local/opt/llvm@13/lib/libLLVMCodeGen.a \
					/usr/local/opt/llvm@13/lib/libLLVMScalarOpts.a \
					/usr/local/opt/llvm@13/lib/libLLVMAggressiveInstCombine.a \
					/usr/local/opt/llvm@13/lib/libLLVMInstCombine.a \
					/usr/local/opt/llvm@13/lib/libLLVMTarget.a \
					/usr/local/opt/llvm@13/lib/libLLVMBitWriter.a \
					/usr/local/opt/llvm@13/lib/libLLVMTransformUtils.a \
					/usr/local/opt/llvm@13/lib/libLLVMAnalysis.a \
					/usr/local/opt/llvm@13/lib/libLLVMObject.a \
					/usr/local/opt/llvm@13/lib/libLLVMBitReader.a \
					/usr/local/opt/llvm@13/lib/libLLVMMCParser.a \
					/usr/local/opt/llvm@13/lib/libLLVMMC.a \
					/usr/local/opt/llvm@13/lib/libLLVMTextAPI.a \
					/usr/local/opt/llvm@13/lib/libLLVMProfileData.a \
					/usr/local/opt/llvm@13/lib/libLLVMBinaryFormat.a \
					/usr/local/opt/llvm@13/lib/libLLVMRemarks.a \
					/usr/local/opt/llvm@13/lib/libLLVMBitstreamReader.a \
					/usr/local/opt/llvm@13/lib/libLLVMSupport.a \
					/usr/local/opt/llvm@13/lib/libLLVMDemangle.a \
					/usr/local/opt/llvm@13/lib/libLLVMObjCARCOpts.a \
					main.cpp

and when running, with test.ll given as:

; ModuleID = 'test'
source_filename = "test"

define void @main()  {
entry:
  ret void
}

it produces:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==35474==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x00010e34a18c bp 0x7ff7b1ded230 sp 0x7ff7b1ded200 T0)
==35474==The signal is caused by a READ memory access.
==35474==Hint: this fault was caused by a dereference of a high value address (see register values below).  Disassemble the provided pc to learn which register was used.
    #0 0x10e34a18c in llvm::DenseMapBase<llvm::DenseMap<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Function*>, llvm::detail::DenseMapPair<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > > > >, llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Function*>, llvm::detail::DenseMapPair<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > > > >::clear()+0x8c (test:x86_64+0x10023918c)
    #1 0x10e34a0d4 in llvm::detail::AnalysisResultModel<llvm::Module, llvm::InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Function>, llvm::Module>, llvm::InnerAnalysisManagerProxy<llvm::AnalysisManager<llvm::Function>, llvm::Module>::Result, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator, true>::~AnalysisResultModel()+0x84 (test:x86_64+0x1002390d4)
    #2 0x10e406b4e in llvm::DenseMap<llvm::Module*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Module*>, llvm::detail::DenseMapPair<llvm::Module*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > > > > > >::~DenseMap()+0x8e (test:x86_64+0x1002f5b4e)
    #3 0x10efd15e8 in llvm::DenseMap<llvm::Module*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Module*>, llvm::detail::DenseMapPair<llvm::Module*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Module, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>::Invalidator> > > > > > > >::~DenseMap() DenseMap.h:753
    #4 0x10efd1539 in llvm::AnalysisManager<llvm::Module>::~AnalysisManager() PassManager.h:899
    #5 0x10efb1288 in llvm::AnalysisManager<llvm::Module>::~AnalysisManager() PassManager.h:899
    #6 0x10efafc40 in main main.cpp:51
    #7 0x119db551d in start+0x1cd (dyld:x86_64+0x551d)

==35474==Register values:
rax = 0xbebebebebebebebe  rbx = 0xbebebebebebebebe  rcx = 0x000061b000001b80  rdx = 0xfffffffffffff000
rdi = 0x00007ff7b1ded418  rsi = 0x000000010fb440e0  rbp = 0x00007ff7b1ded230  rsp = 0x00007ff7b1ded200
 r8 = 0x0000000000000020   r9 = 0x0000000000000000  r10 = 0x00000fffffffffff  r11 = 0x0000000000000038
r12 = 0x000061d000000a80  r13 = 0x000061d000000a88  r14 = 0x0000602000000850  r15 = 0x000061d000001280
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (test:x86_64+0x10023918c) in llvm::DenseMapBase<llvm::DenseMap<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Function*>, llvm::detail::DenseMapPair<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > > > >, llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > >, llvm::DenseMapInfo<llvm::Function*>, llvm::detail::DenseMapPair<llvm::Function*, std::__1::list<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > >, std::__1::allocator<std::__1::pair<llvm::AnalysisKey*, std::__1::unique_ptr<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator>, std::__1::default_delete<llvm::detail::AnalysisResultConcept<llvm::Function, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>::Invalidator> > > > > > > >::clear()+0x8c
==35474==ABORTING
zsh: abort      ./test

It would be great with a hint to whether I am doing something wrong or if this is a bug in the librarry. For reference:

% llvm-config --version
13.0.1

% clang++ --version
Homebrew clang version 13.0.1
Target: x86_64-apple-darwin21.4.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin

If you’re going to do development with LLVM, I’d recommend developing against a build with assertions turned on (CMake flag -DLLVM_ENABLE_ASSERTIONS=On). If you do something wrong, you’ll usually see a somewhat descriptive assertion failure rather than a segfault.

I don’t see anything obviously wrong at first glance, but I’m haven’t looked at the pass manager boilerplate in a while.