[LLVMdev] code generation goes into an infinite loop

Daniel Wilkerson daniel.wilkerson at gmail.com
Sat Oct 3 15:06:23 PDT 2009


We seem to be creating an infinite loop in llvm while trying to
implement the simplest possible code generation.  Specifically, we are
trying to emit code for the following program, as it is easily
testable from the command-line:

    int main(int argc) { return argc; }

We got our code generator to build and link with llvm.  When we run
it, it pauses when running the PrintModulePass and then exits with a
bus error.  I suspect that this is an infinite loop leading to a stack
overflow.

While many kinds of errors we could fix by looking at other people's
examples or reading the docs, I suspect that this should be considered
to be a bug in the verifier pass: clearly we generated wrong LLVM
datastructures somehow and the verifier is not catching it before the
emitter falls off a cliff.  Please comment.

Daniel

// modified from:
  // llvm/docs/tutorial/JITTutorial1.html

  // make an LLVM module
  printf("%s:%d make module\n", __FILE__, __LINE__);
//   Module* Mod = makeLLVMModule();
  llvm::Module *mod = new llvm::Module("test");

  // make a function object
  printf("%s:%d make function\n", __FILE__, __LINE__);
//   Constant* c = mod->getOrInsertFunction
//     ("mul_add",
//      /*ret type*/ IntegerType::get(32),
//      /*args*/ IntegerType::get(32),
//      IntegerType::get(32),
//      IntegerType::get(32),
//      /*varargs terminated with null*/ NULL);
  llvm::Constant *c = mod->getOrInsertFunction
    ("main",                    // function name
     llvm::IntegerType::get(32), // return type
     llvm::IntegerType::get(32), // one argument (argc)
     NULL                       // terminate list of varargs
     );
  llvm::Function *main_function = llvm::cast<llvm::Function>(c);
  main_function->setCallingConv(llvm::CallingConv::C);

  // make the body of the function
  printf("%s:%d make body\n", __FILE__, __LINE__);
  llvm::Function::arg_iterator args = main_function->arg_begin();
  llvm::Value* arg1 = args++;
  arg1->setName("argc");

  printf("%s:%d make block\n", __FILE__, __LINE__);
  llvm::BasicBlock *block = llvm::BasicBlock::Create("entry", main_function);
  llvm::IRBuilder<> builder(block);
  builder.CreateRet(arg1);

  // verify the module
  printf("%s:%d verify\n", __FILE__, __LINE__);
  verifyModule(*mod, llvm::PrintMessageAction);

  // render the module
  printf("%s:%d render\n", __FILE__, __LINE__);
  llvm::PassManager PM;
  llvm::ModulePass *pmp = llvm::createPrintModulePass(0); // (&llvm::cout);
  PM.add(pmp);
  PM.run(*mod);

  // delete the module
  printf("%s:%d delete module\n", __FILE__, __LINE__);
  delete mod;



More information about the llvm-dev mailing list