Search code examples
llvm-c++-api

What is the difference between llvm::CallBase::getArgOperand() and llvm::UnaryInstruction::getOperand()?


I'm learning LLVM core librarry. I know that getArgOperand(i) would return the i-th operand of callable instruction in the form of llvm::Value* . But what is purpose of getOperand() ? In the following code, it seems that these two functions have similar funtionality (i'm not sure). I can't find detail explanation in the following offcial doc. https://llvm.org/doxygen/classllvm_1_1CallBase.html#ab2caa29167597390ab2fc3cf30d70389 https://llvm.org/doxygen/classllvm_1_1UnaryInstruction.html#a71927e1ef55b2829d11000662d80c60b

//This is used for extracting the first argument of cudaMalloc(**void, int)
Value *MemAllocInfo::getTarget() {
  Value *ans = Alloc->getArgOperand(0);
  if (isa<LoadInst>(ans)) ans = dyn_cast<LoadInst>(ans)->getOperand(0);
  if (isa<BitCastInst>(ans)) ans = dyn_cast<BitCastInst>(ans)->getOperand(0);
  return ans;
}

My Questions are:

  • Is the funtionality of getArgOperand() and getOperand() equivalent?
  • and, if possible, what is the purpose of two if statements?

Update1:

I understand what you mean, @Nick Lewycky. But I write a function Pass and demo.ll as follow.

llvm::PreservedAnalyses CountIRPass::run(
        llvm::Function& F,llvm::FunctionAnalysisManager& AM){
    for(llvm::BasicBlock& BB:F){
        for(llvm::Instruction& I:BB){
            if(llvm::isa<llvm::CallInst>(I)){
                llvm::CallInst& ci=llvm::cast<llvm::CallInst>(I);
                llvm::errs() << ci.getNumOperands() <<'\n'; 
                llvm::errs() << ci.getArgOperand(0) <<'\n';
                llvm::errs() << ci.getOperand(0) <<'\n';
                llvm::errs() << *(ci.getArgOperand(0)) <<'\n';
            }
            }
    }
    return llvm::PreservedAnalyses::all();
}
define internal i32 @special_func(i32 %a){
    ret i32 0
}

define dso_local i32 @main(i32 %a){
    %b=call i32 @special_func(i32 %a)
    ret i32 %a 
}

The output is:

2
0x55be3770bf20
0x55be3770bf20
i32 %a

The output shows that the results of getArgOperand(0) and getOperand(0) are indentical, which is i32 %a. My LLVM version is 15.0.0 Is it possible about version issue?


Solution

  • The first operand to a call or invoke instruction is the callee, then comes the arguments. getArgOperand(0) returns the first argument to the call, while getOperand(0) would return the callee.

    The function you quoted then checks whether the first argument to the function call is a load and if so switches out ans for the pointer that was being loaded. Then if ans is a bitcast, it peeks through the bitcast to replace ans with the casted value. Why it does this is not clear from the context (what about multiple bitcasts?), but that's what it does.

    Update1: I think it's a version issue. It looks like right now all getArgOperand(i) does is return getOperand(i). Instead getCalledOperand(), which returns the callee, now does getOperand(-1)! Regardless, this is why getArgOperand() was originally added.