2

I have the following snippet of code:

static LLVMContext TempContext;
Type * RetTy = Type::getVoidTy(TempContext)
for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    RetTy = I->getOperand(0)->getType();
    break
  }
}

Where I am trying to capture the RetTy of a instruction, void or not, so I can use it on

getOrInsertFunction("TempF", FunctionType::get(RetTy, ArgsTys,false));

This code works as long as the ret instruction is not a ret void.

I tried to add a second if to check the void case, but this does not seem to work, and execution stops on the in the FunctionType::get(...) function, printing a back trace.

for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    if ( I->getOperand(0)->getType() != Type::getVoidTy(TempContext)) {
      RetTy = I->getOperand(0)->getType();
      break
    }
  }
}                                            

Note that removing the for loop all together works and execution continues, as the function FunctionType::get(...) handles the initialized Type * RetTy = Type::getVoidTy(TempContext) "void" value for RetTy just fine. But then I can't capture when a llvm function returns non-void values.


How do I know when an instruction I is a return instruction and it is returning Void in LLVM IR?

1 Answer 1

5

The problem with your current code is that ret void does not have an operand, so calling getOperand(0) accesses invalid data.

Replacing your if with:

if (ReturnInst *ri = dyn_cast<ReturnInst>(I))
{
  if (ri->getNumOperands() == 0)
  {
    errs() << "VOID: " << *ri << "\n";
  }
  else
  {
    errs() << "NON-VOID: " << *ri << "\n";
  }
}

Now, this code will output VOID: ret void, having correctly detected the instruction.

As an alternative, you could retrieve the return type for the function using any instruction by relying on instructions being contained by a function I->getFunction()->getReturnType(); however, this would assume that the function is well-formed and its ReturnInst matches its type and the instruction is part of a function.

Sign up to request clarification or add additional context in comments.

1 Comment

I did not see this while reading the docs. Now, that you highlighted it, I see that IRBuilder calls ReturnInst::Create method that initializes a TerminatorInst (in InstrTypes.h) with NumOps argument set to 0. Thank you for the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.