[llvm-dev] How to efficiently extract the calledFunction from a complex CallInst?

622 views
Skip to first unread message

Shen Liu via llvm-dev

unread,
Nov 12, 2015, 10:27:47 PM11/12/15
to llvm...@lists.llvm.org
Hi all,

Usually if we want to get the called Function we can directly use CallInst->getCalledFunction(), however, today i encounter an unusual CallInst as follows:

 %call11 = call double (...)* bitcast (double ()* @quantum_frand to double (...)*)()

the original C source involve type cast:

float u,v;
extern double quantum_frand();
   u = 2 * quantum_frand() - 1;
   v = 2 * quantum_frand() - 1;

In this case, CallInst->getCalledFunction() returns a nullptr unusually, I printed out the getOperand(0) and found the operand is the whole thing of  "double (...)* bitcast (double ()* @quantum_frand to double (...)*)()". Any member function calling on that fails so i don't know whether there is an efficient way to exactly get the called function @quantum_frand(...) here? Thanks!


Best regards,

Shen



David Blaikie via llvm-dev

unread,
Nov 12, 2015, 10:48:10 PM11/12/15
to Shen Liu, llvm-dev
What you have is a BitCastInst, so you'd have to downcast the Value* to that, then look through the bitcast.

But realize you may never actually find a function in the end:

void func(void (*f)(void)) {
  f();
}

the f call is a call to a function pointer, so there is no statically knowable called function here. Your code will probably need to handle the case where this arises.

- David
 
Thanks!


Best regards,

Shen




_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


Shen Liu via llvm-dev

unread,
Nov 12, 2015, 11:50:21 PM11/12/15
to David Blaikie, llvm-dev
Thanks for your helpful answer David! But one thing still makes me confused is when i use isa<CallInst> to check the original instruction the answser is yes.
, which implies it is a callinst. Since it is not a BitcastInst, why does llvm add an opcode "call" before it? It looks a little weird here.  

David Blaikie via llvm-dev

unread,
Nov 12, 2015, 11:59:36 PM11/12/15
to Shen Liu, llvm-dev
On Thu, Nov 12, 2015 at 8:51 PM, Shen Liu <shl...@lehigh.edu> wrote:
Thanks for your helpful answer David! But one thing still makes me confused is when i use isa<CallInst> to check the original instruction the answser is yes.
, which implies it is a callinst. Since it is not a CallInst, why does llvm add an opcode "call" before it? It looks a little weird here.  

It is a CallInst, hence whwy you can call getCalledFunction - but you just don't get an answer. It's a call, but not to a function. It's a call to a bitcast of a function. So the operand(0) is not a Function, but a BitCastInst (or a constant, I forget how they work).
 

Shen

On Thu, Nov 12, 2015 at 10:48 PM, David Blaikie <dbla...@gmail.com> wrote:

John Criswell via llvm-dev

unread,
Nov 13, 2015, 8:45:05 AM11/13/15
to Shen Liu, llvm...@lists.llvm.org
On 11/12/15 10:27 PM, Shen Liu via llvm-dev wrote:
Hi all,

Usually if we want to get the called Function we can directly use CallInst->getCalledFunction(), however, today i encounter an unusual CallInst as follows:

 %call11 = call double (...)* bitcast (double ()* @quantum_frand to double (...)*)()

As others have noted, Function::getCalledFunction() is returning null because the function that is being called is first casted.  For some reason, Function::getCalledFunction() does not strip off pointer casts on its first argument.

However, you can do that easily.  Just use:

Function * calledFunc = dyn_cast<Function>(CallInst->getCalledValue()->stripPointerCasts())

If calledFunc is non-zero, it's a pointer to the called function.  Otherwise, you have an indirect call.

As an aside, note that indirect calls are sometimes the result of a select instruction that picks between one of two functions.  It's therefore worth checking to see if the called value is a SelectInst and, if it is, see if both operands to the SelectInst are Functions.

Regards,

John Criswell


the original C source involve type cast:

float u,v;
extern double quantum_frand();
   u = 2 * quantum_frand() - 1;
   v = 2 * quantum_frand() - 1;

In this case, CallInst->getCalledFunction() returns a nullptr unusually, I printed out the getOperand(0) and found the operand is the whole thing of  "double (...)* bitcast (double ()* @quantum_frand to double (...)*)()". Any member function calling on that fails so i don't know whether there is an efficient way to exactly get the called function @quantum_frand(...) here? Thanks!


Best regards,

Shen





_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


-- 
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell

Shen Liu via llvm-dev

unread,
Nov 13, 2015, 12:32:21 PM11/13/15
to John Criswell, llvm-dev
Appreciate your advice, John! It works well as you said, thanks very much!
Reply all
Reply to author
Forward
0 new messages