[llvm-dev] Help with bitcast instruction

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 12 11:50:19 PDT 2019


Hi Alberto,

On Tue, 12 Mar 2019 at 18:33, Alberto Barbaro <barbaro.alberto at gmail.com> wrote:
> call void bitcast (void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* @png_set_mem_fn to void (%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*)(%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* (%struct.png_struct_def*, i64)* %malloc_fn, void (%struct.png_struct_def*, i8*)* %free_fn) #15
>
> I'm pretty sure that this is a CallInst but when I try to call getCalledFunction() I receive a null pointer and that really surprise me.
>
> I would like to understand how to get the function that is called and its parameters. Can you tell me how please?

The problem is that getCalledFunction is pretty naive, it just takes
the getCalleeValue and dyn_cast<Function>s it. Because you've got a
cast in the IR itself your situation is a bit more complicated.

In this case, you could write a "findCalledFunction" something like:

    Function *findCalledFunction(CallBase &CI) {
      Value *Callee = CI.getCalledValue()->stripPointerCasts();
      if (auto F = dyn_cast<Function>(Callee))
        return F;
      return nullptr;
    }

Where the "stripPointerCast" is the key extra ingredient that looks
through the bitcast. (Someone could certainly argue that's what
getCalledFunction should be doing anyway, but there are subtleties on
weird targets like GPUs so it's not 100%).

It won't catch all callsites (e.g. virtual function calls could still
be plain %X values), but pretty much any algorithm has to be robust
against an unknown callee anyway.

> Am i right saying that:
>
> (void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* -> "old parameters type"
> (%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*) ->  "new parameters type"
> (%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* (%struct.png_struct_def*, i64)* %malloc_fn, void (%struct.png_struct_def*, i8*)* %free_fn) "the parameters passed to the png_set_mem_fn"

I think so, from what I understand. The essence of that cast is just
changing one pointer type to another, so it doesn't actually affect
how parameters are passed at all, and that is definitely the function
called.

As an aside, we're working towards a world where there's just one
"ptr" type in LLVM. I think this whole situation would disappear
completely there.

> sorry I forgot to mention, how can I extract the keyword bitcast? I would like to be able to distinguish the function name.

I think the answer to this question is the "stripPointerCasts"
function I mentioned above, though I'm not 100% sure.

Cheers.

Tim.


More information about the llvm-dev mailing list