Search code examples
c++llvmllvm-clangllvm-c++-api

llvm builder adding terminator to basic block


If I have a basic block declared within function F like so:

BasicBlock* loopSetup = BasicBlock::Create(F.getContext(), "loop_setup", &F);

How would I add a terminator instruction to it? If I just do:

IRBuilder<> builder(loopSetup);
builder.SetInsertPoint(loopSetup);
BranchInst *end = builder.CreateBr(loopStart);

Then I get this error on running the pass with opt:

Basic Block in function 'main' does not have terminator!
label %loop_setup

The terminator is clearly not set as well since loopSetup->getTerminator(); returns 0.


Solution

  • The code you provided, with some changes, seems to work fine..

    #include "llvm/IR/LLVMContext.h"
    #include "llvm/IR/Module.h"
    #include "llvm/IR/IRBuilder.h"
    #include "llvm/Support/raw_ostream.h"
    #include <vector>
    #include <memory>
    #include <iostream>
    
    using namespace llvm;
    
    int main() {
        LLVMContext context;
    
        std::unique_ptr<Module> TheModule = std::make_unique<Module>(std::string("mod"), context);
    
        FunctionType *FT = FunctionType::get(Type::getVoidTy(context), std::vector<Type*>(), false);
    
        Function *F = Function::Create(FT, Function::ExternalLinkage, "main", TheModule.get());
    
        BasicBlock* loopSetup = BasicBlock::Create(context, "loop_setup", F);
    
        IRBuilder<> builder(loopSetup);
        builder.SetInsertPoint(loopSetup);
        BranchInst *end = builder.CreateBr(loopSetup);
    
        TheModule->print(errs(), nullptr);
    }
    

    This creates an endless loop. Calling loopSetup->getTerminator()->print(errs(), false) shows that the br used is the terminator of the block.

    The IR output seems fine too

    define void @main() {
    loop_setup:
      br label %loop_setup
    }
    

    The problem might be with loopStart you used, as you didn't show how you created it.