[llvm-dev] How can I make llvm intrinsic functions declarations survive from optimizations.

John Criswell via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 30 06:24:24 PDT 2016

Dear All,

To add to what Zhengyang has written, the choice to optimize away unused 
function declarations within the standard optimization pipeline changes 
how instrumentation passes are written.

Many instrumentation passes just add calls to functions. Therefore, they 
could be written as a FunctionPass, and this worked because any global 
changes that needed to be made could be done within the 
doInitialization() method.  To the best of my recollection, the LLVM 
optimization passes would not remove these declarations.

Now these declarations are removed before the runOnFunction() methods 
are called within the FunctionPasses.  For regular functions, this can 
be worked around by adding the functions to the llvm.compiler.used 
array, but it does not work for intrinsics (such as memset).  This means 
that some instrumentation passes that could be written as a FunctionPass 
can no longer be written this way (at least not without modifying the 
pass pipeline, which we try to avoid doing in SAFECode).

I suspect this is an untended consequence of a change to either the pass 
pipeline or the global optimization pass.  It probably affects very 
little code within LLVM, but it can affect a lot of external code that 
uses LLVM for instrumentation purposes.  I thought we should mention 
this behavior in case it is something that we want to change.


John Criswell

On 6/30/16 7:59 AM, Zhengyang Liu via llvm-dev wrote:
> Dear Sanjoy Das and community.
> I was tried to fix a bug in the pass InitAllocas from SAFECode. This 
> is a function pass and will insert a prototype of 
> 'llvm.memset.p0i8.i32' in the module at doInitialize() stage of the 
> pass. But, this prototype will be eliminated by strip unused function 
> optimization since there is no call on this function after 
> doInitialization(). Therefore there will be no prototype at the 
> runOnFunction() stage, and this will cause a fail. Previously I solve 
> this kind of bug by inserting the prototype of the function to 
> llvm.compiler.used. In this way, the compiler will not leave the 
> prototype alone. This time, the situation is a bit complicated, 
> inserting the intrinsic function to llvm.compiler.used will cause a 
> fail because only users of direct call/invokes are allowed on 
> intrinsic functions.
> Fortunately, after some discussion with my GSoC mentor, Prof. 
> Criswell, we chose to rewrite the pass to a module pass, this solves 
> this issue perfectly. Thanks for your patience.
> Best regards,
> Zhengyang.
> ------------------------------------------------------------------------
> *From:* Sanjoy Das <sanjoy at playingwithpointers.com>
> *Sent:* Thursday, June 23, 2016 3:44:09 PM
> *To:* Zhengyang Liu
> *Cc:* llvm-dev at lists.llvm.org
> *Subject:* Re: [llvm-dev] How can I make llvm intrinsic functions 
> declarations survive from optimizations.
> Hi Zhengyang,
> Do you mind sharing _why_ you need the intrinsic declarations to stay
> around?  It is possible that there is a better way of solving your
> problem.
> Thanks!
> -- Sanjoy
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

John Criswell
Assistant Professor
Department of Computer Science, University of Rochester

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160630/bcfdf940/attachment.html>

More information about the llvm-dev mailing list