[llvm-dev] analysis based on nonnull attribute

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Fri Dec 16 11:49:29 PST 2016



On 12/16/2016 11:37 AM, Michael Kuperstein wrote:
> Calling an instruction a "source" is basically another way to say "we 
> can't dataflow through this".
>
> What I'm trying to say is that this is not really a property of the 
> instruction type.
> I agree we should be adding annotations sparingly - that is, we should 
> not annotate something we can infer. But that's a semantic property, 
> so I don't really see why that means we should prohibit annotating 
> certain instructions on the syntactic level.
I'm not opposed to this per se, but I see it as a slippery slope 
argument.  One of the foundational design principles of LLVM is that 
analysis results are inferred from the IR, not part of the IR.  This 
decision is hugely important for stability and extensibility of the 
framework.  If we ever got to the day where we were putting !range on an 
add instruction as part of a transform pass, that would clearly be 
several steps too far.
>
> Admittedly, the only example I have in mind right now is the one under 
> discussion above - if we have:
>
> %p = select i1 %a, i8* %x, i8 *y
> call void foo(i8* nonnull %p)
>
> Then after inlining foo, we lose the non-null information for %p 
> unless we annotate it - and we can't propagate it through the select. 
> The same would happen for a phi,
Are there cases where we loose information by inlining this example?  
Yes.  Are they common?  I don't know.  In particular, if foo contains an 
unconditional load from %p, we don't actually loose any information by 
inlining.  Similarly, we can frequently infer the non-null fact from 
another source.

Just to be clear, I want to spell out a distinction between having 
metadata available for frontend annotation and having the optimizer 
itself introduce metadata.  The former is a much easier request because 
it implies a much smaller maintenance burden.  If we screw something up 
(compile time say), then only the frontend that cared bears the cost.  
If we start having the optimizer itself introduce metadata (or assumes, 
etc..), then the justification has to sufficient for *all* frontends and 
use cases.  In practice, that's going to be a much higher bar to clear.

>
> On Fri, Dec 16, 2016 at 11:25 AM, Philip Reames 
> <listmail at philipreames.com <mailto:listmail at philipreames.com>> wrote:
>
>     The general idea to date has been only "sources" get annotations. 
>     If there's something we fundamentally *can't* analyze through,
>     that's where we annotate.  We try not to use annotations for
>     places where we could have but didn't.
>
>     e.g. call metadata/attributes allow us to model external calls,
>     load metadata allow us to model frontend knowledge of external
>     memory locations, etc..
>
>
>     On 12/16/2016 11:03 AM, Michael Kuperstein via llvm-dev wrote:
>>     By the way, I've been wondering - why can we only attach !nonnull
>>     and !range to loads (for both) and call/invoke (for !range)?
>>
>>     I mean, those are all instructions you can't do dataflow through
>>     - intraprocedurally, w/o memoryssa - but why only these
>>     instructions? Why not allow annotating any pointer def with
>>     !nonnull and any integer def with !range?
>>     Sure, that's redundant w.r.t llvm.assume, but so are the existing
>>     annotations.
>>
>>     On Wed, Dec 14, 2016 at 11:20 PM, Hal Finkel <hfinkel at anl.gov
>>     <mailto:hfinkel at anl.gov>> wrote:
>>
>>
>>
>>         ------------------------------------------------------------------------
>>
>>             *From: *"Michael Kuperstein"
>>             <michael.kuperstein at gmail.com
>>             <mailto:michael.kuperstein at gmail.com>>
>>             *To: *"Hal Finkel" <hfinkel at anl.gov <mailto:hfinkel at anl.gov>>
>>             *Cc: *"Sanjay Patel" <spatel at rotateright.com
>>             <mailto:spatel at rotateright.com>>, "llvm-dev"
>>             <llvm-dev at lists.llvm.org
>>             <mailto:llvm-dev at lists.llvm.org>>, "Michael Kuperstein"
>>             <mkuper at google.com <mailto:mkuper at google.com>>
>>             *Sent: *Thursday, December 15, 2016 1:13:07 AM
>>             *Subject: *Re: [llvm-dev] analysis based on nonnull attribute
>>
>>             I think what Sanjay is getting at is that it's not an
>>             integer, it's still a pointer - but it's not clear where
>>             information about non-nullness of the pointer should be
>>             propagated to.
>>
>>             In this particular case, since the def of %x in the
>>             caller is also an argument, we could propagate it to the
>>             def directly, e.g.
>>
>>             define i1 @foo(i32* nonnull %x) {
>>             %y.i = load i32, i32* %x   ; inlined, still known to be
>>             nonnull
>>
>>             And if the def of %x was a load, we could use !nonnull.
>>             But I'm not sure what we can do in the general case (say,
>>             %x = select...).
>>             The best I can think of is generating an llvm.assume for
>>             the condition.
>>
>>         True. In this case, the preferred thing would be to add the
>>         nonnull attribute to the caller's parameter. Adding
>>         llvm.assume is indeed a general solution.
>>
>>          -Hal
>>
>>
>>             Michael
>>
>>             On 14 December 2016 at 14:05, Hal Finkel via llvm-dev
>>             <llvm-dev at lists.llvm.org
>>             <mailto:llvm-dev at lists.llvm.org>> wrote:
>>
>>
>>                 ------------------------------------------------------------------------
>>
>>                     *From: *"Sanjay Patel" <spatel at rotateright.com
>>                     <mailto:spatel at rotateright.com>>
>>                     *To: *"Hal Finkel" <hfinkel at anl.gov
>>                     <mailto:hfinkel at anl.gov>>
>>                     *Cc: *"llvm-dev" <llvm-dev at lists.llvm.org
>>                     <mailto:llvm-dev at lists.llvm.org>>
>>                     *Sent: *Wednesday, December 14, 2016 4:03:40 PM
>>                     *Subject: *Re: [llvm-dev] analysis based on
>>                     nonnull attribute
>>
>>
>>
>>
>>                     On Wed, Dec 14, 2016 at 2:51 PM, Hal Finkel
>>                     <hfinkel at anl.gov <mailto:hfinkel at anl.gov>> wrote:
>>
>>
>>
>>                         ------------------------------------------------------------------------
>>
>>                             *From: *"Sanjay Patel via llvm-dev"
>>                             <llvm-dev at lists.llvm.org
>>                             <mailto:llvm-dev at lists.llvm.org>>
>>                             *To: *"llvm-dev" <llvm-dev at lists.llvm.org
>>                             <mailto:llvm-dev at lists.llvm.org>>
>>                             *Sent: *Wednesday, December 14, 2016
>>                             3:47:03 PM
>>                             *Subject: *[llvm-dev] analysis based on
>>                             nonnull attribute
>>
>>                             Does the nonnull parameter attribute give
>>                             us information about subsequent uses of
>>                             that value outside of the function that
>>                             has the attribute?
>>
>>                         Yes. We're guaranteeing that we never pass a
>>                         null value for the argument, so that
>>                         information can be used to optimize the
>>                         caller as well.
>>
>>
>>                     Thanks! I don't know if that will actually solve
>>                     our sub-optimal output for dyn_cast (!), but it
>>                     might help...
>>                     https://llvm.org/bugs/show_bug.cgi?id=28430
>>
>>
>>
>>                             Example:
>>
>>                             define i1 @bar(i32* nonnull %x) { ; %x
>>                             must be non-null in this function
>>                               %y = load i32, i32* %x
>>                               %z = icmp ugt i32 %y, 23
>>                               ret i1 %z
>>                             }
>>
>>                             define i1 @foo(i32* %x) {
>>                               %d = call i1 @bar(i32* %x)
>>                               %null_check = icmp eq i32* %x, null ;
>>                             check if null after call that guarantees
>>                             non-null?
>>                               br i1 %null_check, label %t, label %f
>>                             t:
>>                               ret i1 1
>>                             f:
>>                               ret i1 %d
>>                             }
>>
>>                             $ opt -inline nonnull.ll -S
>>                             ...
>>                             define i1 @foo(i32* %x) {
>>                               %y.i = load i32, i32* %x ; inlined and
>>                             non-null knowledge is lost?
>>
>>                         It should be replaced by !nonnull metadata on
>>                         the load. We might not be doing that today,
>>                         however.
>>
>>
>>                     We can't tag this load with !nonnull though
>>                     because this isn't a load of the pointer?
>>                     "The existence of the |!nonnull| metadata on the
>>                     instruction tells the optimizer that the value
>>                     loaded is known to never be null. This is
>>                     analogous to the |nonnull| attribute on
>>                     parameters and return values. This metadata can
>>                     only be applied to loads of a pointer type."
>>
>>                 True, but we have range metadata for integers.
>>
>>                  -Hal
>>
>>
>>
>>
>>
>>
>>                 -- 
>>                 Hal Finkel
>>                 Lead, Compiler Technology and Programming Languages
>>                 Leadership Computing Facility
>>                 Argonne National Laboratory
>>
>>                 _______________________________________________
>>                 LLVM Developers mailing list
>>                 llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>>                 http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>                 <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>>
>>
>>
>>
>>
>>         -- 
>>         Hal Finkel
>>         Lead, Compiler Technology and Programming Languages
>>         Leadership Computing Facility
>>         Argonne National Laboratory
>>
>>
>>
>>
>>     _______________________________________________
>>     LLVM Developers mailing list
>>     llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161216/2acd2430/attachment-0001.html>


More information about the llvm-dev mailing list