<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <div class="moz-cite-prefix">On 07/11/2018 07:38 PM, Chandler
      Carruth wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAAwGriH3hXw-+ndzywK3Q+ELZt5_PG=KgXZ2PZb0FxrnDxPzfw@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div dir="ltr">+1 to plan
        <div><br>
        </div>
        <div>It would be good to include inference logic to promote to
          full `dereferenceable` when possible so that transforms which
          need that anyways can just use that.</div>
        <div><br>
        </div>
        <div>And/or we should ensure the APIs used always query both so
          that transform authors don't have to remember to do so...</div>
        <div><br>
        </div>
        <div>I still somewhat wish we could do with a single
          `dereferenceable`.</div>
      </div>
    </blockquote>
    <br>
    I definitely plan on having the APIs check both attributes
    appropriately. No one should need to remember to query both and,
    hopefully, there should be no changes necessary to existing passes
    (except enhancements to attribute inference, of course).<br>
    <br>
    Thanks again,<br>
    Hal<br>
    <br>
    <blockquote type="cite"
cite="mid:CAAwGriH3hXw-+ndzywK3Q+ELZt5_PG=KgXZ2PZb0FxrnDxPzfw@mail.gmail.com"><br>
      <div class="gmail_quote">
        <div dir="ltr">On Wed, Jul 11, 2018 at 5:21 PM Hal Finkel via
          llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org"
            moz-do-not-send="true">llvm-dev@lists.llvm.org</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">
          <div text="#000000" bgcolor="#FFFFFF">
            <p>Thanks, Richard.</p>
            <p>Based on the feedback from this thread, I'll move forward
              with the patches for nofree, nosync, adding a new
              corresponding dereferenceable attribute (my suggestion is
              to name this dereferenceable_on_entry; suggestions
              welcome), and updating Clang is emit this new attribute
              instead of the current one.<br>
            </p>
          </div>
          <div text="#000000" bgcolor="#FFFFFF">  -Hal</div>
          <div text="#000000" bgcolor="#FFFFFF"><br>
            <br>
            <div class="m_-277137984432361038moz-cite-prefix">On
              07/11/2018 06:43 PM, Richard Smith wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">
                <div class="gmail_quote">
                  <div dir="ltr">On Wed, 11 Jul 2018 at 16:13, Hal
                    Finkel via llvm-dev <<a
                      href="mailto:llvm-dev@lists.llvm.org"
                      target="_blank" moz-do-not-send="true">llvm-dev@lists.llvm.org</a>>
                    wrote:<br>
                  </div>
                  <blockquote class="gmail_quote" style="margin:0px 0px
                    0px 0.8ex;border-left:1px solid
                    rgb(204,204,204);padding-left:1ex">[+Richard]<br>
                    <br>
                    <br>
                    On 07/11/2018 08:29 AM, Sanjoy Das wrote:<br>
                    > I'm not sure if nosynch is sufficient.  What if
                    we had:<br>
                    ><br>
                    > void f(int& x) {<br>
                    >   if (false) {<br>
                    >     int r0 = x;<br>
                    >   }<br>
                    > }<br>
                    ><br>
                    > // other thread<br>
                    > free(<pointer to x>);<br>
                    ><br>
                    > The source program is race free, but LLVM may
                    speculate the read from<br>
                    > x (seeing that it is dereferenceable) creating
                    a race.<br>
                    <br>
                    Interestingly, I'm not sure. I trust that Richard
                    can answer this<br>
                    question. :-)<br>
                    <br>
                    So, if we had:<br>
                    <br>
                    int y = ...;<br>
                    ...<br>
                    f(y);<br>
                    <br>
                    then I think that Clang's use of dereferenceable is
                    almost certainly<br>
                    okay (because the standard explicitly says,
                    9.2.3.2p5, "A reference<br>
                    shall be initialized to refer to a valid object or<br>
                    function."). Because the reference must have been
                    valid when f(y) began<br>
                    executing, unless it synchronizes somehow with the
                    other thread, any<br>
                    asynchronous deletion of y must be a race.<br>
                    <br>
                    On the other hand, if we have:<br>
                    <br>
                    int &y = ...;<br>
                    ...<br>
                    f(y);<br>
                    <br>
                    do we know that, when f(y) begins executing, the
                    reference points to a<br>
                    valid object? My reading of 9.3.3p2, which says,
                    "Argument passing<br>
                    (7.6.1.2) and<br>
                    function value return (8.6.3) are initializations.",
                    combined with the<br>
                    statement above, implies that, perhaps surprisingly,
                    the same holds<br>
                    here. When the argument to f is initialized, it must
                    refer to a valid<br>
                    object (even if the initializer is another
                    reference).<br>
                    <br>
                    Richard, what do you think?<br>
                  </blockquote>
                  <div><br>
                  </div>
                  <div>First, see also <a href="http://wg21.link/cwg453"
                      target="_blank" moz-do-not-send="true">core issue
                      453</a>, under the guise of which we're fixing the
                    wording in [<span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">dcl.ref](9.2.3.2)p5
                      from</span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br>
                    </span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> 
                      "<span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">A
                        reference shall be initialized to refer to a
                        valid object or function."</span></span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br>
                      </span></span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">to
                        something like</span></span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br>
                      </span></span></div>
                  <div><span
style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span
style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> 
                        "</span></span>If an lvalue to which a reference
                    is directly bound designates neither an existing
                    object or function of an appropriate type (11.6.3
                    [dcl.init.ref]), nor a region of storage of suitable
                    size and alignment to contain an object of the
                    reference's type (4.5 [intro.object], 6.8
                    [basic.life], 6.9 [basic.types]), the behavior is
                    undefined."</div>
                  <div><br>
                  </div>
                  <div>My take is that, if the end of the duration of
                    the region of storage is unsequenced with respect to
                    the binding of the reference, then behavior is
                    undefined. Generally when we refer to a thing
                    happening while some condition is true, we mean that
                    the execution point when the condition became true
                    is sequenced before the thing happening, and the
                    execution point where it becomes not true again is
                    sequenced after.</div>
                  <div><br>
                  </div>
                  <div>So the behavior of that program is undefined
                    regardless of whether 'f' actually loads through
                    'x'.</div>
                  <div> </div>
                  <blockquote class="gmail_quote" style="margin:0px 0px
                    0px 0.8ex;border-left:1px solid
                    rgb(204,204,204);padding-left:1ex"> Thanks again,<br>
                    Hal<br>
                    <br>
                    P.S. If I'm right, then I might be happy, but it's
                    also somewhat scary<br>
                    (although we've been doing this optimization for
                    multiple releases and I<br>
                    don't think we have a bug along these lines), and
                    I'd at least smell the<br>
                    need for a sanitizer.<br>
                    <br>
                    ><br>
                    > -- Sanjoy<br>
                    > On Tue, Jul 10, 2018 at 7:01 PM Hal Finkel via
                    llvm-dev<br>
                    > <<a href="mailto:llvm-dev@lists.llvm.org"
                      target="_blank" moz-do-not-send="true">llvm-dev@lists.llvm.org</a>>
                    wrote:<br>
                    >> Hi, everyone,<br>
                    >><br>
                    >> I'd like to propose adding a nofree
                    function attribute to indicate that<br>
                    >> a function does not, directly or
                    indirectly, call a memory-deallocation<br>
                    >> function (e.g., free, C++'s operator
                    delete). Clang/LLVM can currently<br>
                    >> misoptimize functions that:<br>
                    >><br>
                    >>  1. Have a reference argument.<br>
                    >><br>
                    >>  2. Free the memory backing the object to
                    which the reference is bound<br>
                    >> during the function's execution.<br>
                    >><br>
                    >> Because we tag, in Clang, all reference
                    arguments using the<br>
                    >> dereferenceable attribute, LLVM assumes
                    that the pointer is<br>
                    >> unconditionally dereferenceable throughout
                    the course of the entire<br>
                    >> function. This isn't true, however, if the
                    memory is freed during the<br>
                    >> execution of the function. For more
                    information, please see the<br>
                    >> discussion in <a
                      href="https://reviews.llvm.org/D48239"
                      rel="noreferrer" target="_blank"
                      moz-do-not-send="true">https://reviews.llvm.org/D48239</a>.<br>
                    >><br>
                    >> To solve this problem, we need to give LLVM
                    more information in order to<br>
                    >> help it determine when a pointer, which is
                    dereferenceable when the<br>
                    >> functions begins to execute, will still be
                    dereferenceable later on in<br>
                    >> the function's execution. This nofree
                    attribute can be part of that<br>
                    >> solution. If we know that free (and
                    friends) are not called by the<br>
                    >> function (nor by any function called by the
                    function, and so on), then<br>
                    >> we know that pointers that started out
                    dereferenceable will stay that<br>
                    >> way (except as explained below).<br>
                    >><br>
                    >> I'm initially proposing this to be only a
                    function attribute, although<br>
                    >> one could easily imagine a parameter
                    attribute as well (that indicates<br>
                    >> that a particular pointer argument is not
                    freed by the function). This<br>
                    >> might be useful, but for the use case of
                    helping dereferenceable, it<br>
                    >> would be subtle to use, unless the
                    parameter was also marked as noalias,<br>
                    >> because you'd need to know that the
                    parameter was not also aliased with<br>
                    >> another argument (or had not been
                    captured). Another analysis would need<br>
                    >> to provide this kind of information.<br>
                    >><br>
                    >> Also, just because a function does not,
                    directly or indirectly, call<br>
                    >> free does not mean that it cannot cause
                    memory to be deallocated. The<br>
                    >> function might communicate (synchronize)
                    with another thread causing<br>
                    >> that other thread to delete the memory. For
                    this reason, to use<br>
                    >> dereferenceable as we currently do, we also
                    need to know that the<br>
                    >> function does not synchronize with any
                    other threads. To solve this<br>
                    >> problem, like nofree, I propose to add a
                    nosynch attribute (to indicate<br>
                    >> that a function does not use (non-relaxed)
                    atomics or otherwise<br>
                    >> synchronize with any other threads (e.g.,
                    perform I/O or, as a practical<br>
                    >> matter, use volatile accesses).<br>
                    >><br>
                    >> I've posted a patch for the nofree
                    attribute<br>
                    >> (<a href="https://reviews.llvm.org/D49165"
                      rel="noreferrer" target="_blank"
                      moz-do-not-send="true">https://reviews.llvm.org/D49165</a>).
                    nosynch's implementation would be<br>
                    >> very similar (except instead of looking for
                    calls to free, it would look<br>
                    >> for uses of non-relaxed atomics, volatile
                    ops, and known functions that<br>
                    >> are not I/O functions).<br>
                    >><br>
                    >> With both of these attributes (nofree and
                    nosynch), a function argument<br>
                    >> with the dereferenceable attribute will be
                    known to be dereferenceable<br>
                    >> throughout the execution of the attributed
                    function. We can update<br>
                    >> isDereferenceableAndAlignedPointer to
                    include these additional checks on<br>
                    >> the current function.<br>
                    >><br>
                    >> One more choice we have: We can, as I
                    proposed above, essentially weaken<br>
                    >> the current semantics of dereferenceable to
                    not exclude<br>
                    >> mid-function-execution deallocation. We can
                    also add a second attribute<br>
                    >> with the current, stronger, semantics. We
                    can keep the current attribute<br>
                    >> as-is, and add a second attribute with the
                    weaker semantics (and switch<br>
                    >> Clang to use that).<br>
                    >><br>
                    >> Please let me know what you think.<br>
                    >><br>
                    >> Thanks again,<br>
                    >><br>
                    >> Hal<br>
                    >><br>
                    >> --<br>
                    >> Hal Finkel<br>
                    >> Lead, Compiler Technology and Programming
                    Languages<br>
                    >> Leadership Computing Facility<br>
                    >> Argonne National Laboratory<br>
                    >><br>
                    >>
                    _______________________________________________<br>
                    >> LLVM Developers mailing list<br>
                    >> <a href="mailto:llvm-dev@lists.llvm.org"
                      target="_blank" moz-do-not-send="true">llvm-dev@lists.llvm.org</a><br>
                    >> <a
                      href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
                      rel="noreferrer" target="_blank"
                      moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
                    <br>
                    -- <br>
                    Hal Finkel<br>
                    Lead, Compiler Technology and Programming Languages<br>
                    Leadership Computing Facility<br>
                    Argonne National Laboratory<br>
                    <br>
                    _______________________________________________<br>
                    LLVM Developers mailing list<br>
                    <a href="mailto:llvm-dev@lists.llvm.org"
                      target="_blank" moz-do-not-send="true">llvm-dev@lists.llvm.org</a><br>
                    <a
                      href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
                      rel="noreferrer" target="_blank"
                      moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
                  </blockquote>
                </div>
              </div>
            </blockquote>
            <br>
            <pre class="m_-277137984432361038moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
          </div>
          _______________________________________________<br>
          LLVM Developers mailing list<br>
          <a href="mailto:llvm-dev@lists.llvm.org" target="_blank"
            moz-do-not-send="true">llvm-dev@lists.llvm.org</a><br>
          <a
            href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
            rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
        </blockquote>
      </div>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
  </body>
</html>