<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Skimming along, apologies if I'm repeating something which
      already got said.</p>
    <p>If I understand this correctly, the basic problem we're trying to
      solve is to use a local hint (the invariant.group) to make a
      global assumption about other code which might exist elsewhere
      outside the function.  The attribute proposed can basically be
      phrased as describing a universe of functions within which our
      desired global property holds.  There's an ambiguity about what is
      allowed to be assumed about code outside that universe.</p>
    <p>I think it's important to note that we have a precedent of
      something similar to this in TBAA.  TBAA information coming from
      different modules has the same base problem.  We solve it by using
      the "root" of the TBAA tree as a scope descriptor, and essentially
      making two TBAA nodes from distinct roots incomparable.  <br>
    </p>
    <p>Can someone explain concisely why a similar scheme couldn't be
      used to solve this problem?</p>
    <div class="moz-cite-prefix">On 12/4/18 11:24 AM, John McCall via
      llvm-dev wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:1C826C88-A140-49E7-A291-9DD3CB41AF23@apple.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
          <p dir="auto">On 4 Dec 2018, at 13:16, Sanjoy Das wrote:</p>
          <blockquote style="border-left:2px solid #777; color:#777;
            margin:0 0 5px; padding-left:5px">
            <p dir="auto">On Mon, Dec 3, 2018 at 11:49 PM John McCall <a
                href="mailto:jmccall@apple.com" style="color:#777"
                moz-do-not-send="true">jmccall@apple.com</a> wrote:</p>
            <blockquote style="border-left:2px solid #777; color:#999;
              margin:0 0 5px; padding-left:5px; border-left-color:#999">
              <p dir="auto">Piotr's proposal unfortunately doesn't give
                us a good name for the class<br>
                of optimizations that require being listed in
                supported_optimizations.<br>
                In earlier discussions I called them "brittle", but I
                can understand why<br>
                nobody wants to call their optimization that, so let's
                call them<br>
                "good-faith optimizations" instead since they rely on
                the good faith of<br>
                all the participating code.</p>
              <p dir="auto">Every optimization has to know how to
                maintain the structural rules of<br>
                LLVM IR; that's what makes them structural rules. We
                don't want the set of<br>
                structural rules to substantially change because
                such-and-such good-faith<br>
                optimization is in effect because that would require
                arbitrary transforms<br>
                to check the supported_optimizations list before they
                knew which rules to<br>
                follow. Instead, the burden is on the optimization
                designer to pick IR<br>
                constructs that won't be messed up by an arbitrary
                transform with no special<br>
                knowledge of the optimization. The only thing the
                optimization designer<br>
                can rely on is this:</p>
              <p dir="auto">other transforms will preserve the apparent
                semantics of the function and<br>
                other transforms will maintain the standard structural
                rules of LLVM IR.</p>
            </blockquote>
            <p dir="auto">Ok. Just to make sure we're on the same page,
              if this was all there<br>
              is we would not need this attribute right? All LLVM
              optimizations do<br>
              need to preserve semantics and structural properties
              anyway?</p>
          </blockquote>
          <p dir="auto">We need this attribute because interprocedural
            optimizations otherwise<br>
            break good-faith optimizations, so yes, my suummary here is
            missing some<br>
            qualification (that I included in the next paragraph, but
            with a slightly<br>
            different spin). So let me restate this.</p>
          <p dir="auto">The designer of a good-faith optimization can
            rely on this:</p>
          <ul>
            <li>other transforms will preserve the apparent semantics of
              the function,</li>
            <li>other transforms will maintain the standard structural
              rules of LLVM IR, and</li>
            <li>interprocedural transforms will honor
              supported_optimizations as mentioned
              in Piotr's proposal --- and, in particular, will intersect
              the
              supported_optimizations list whenever moving code into a
              function.</li>
          </ul>
          <p dir="auto">Note that IPO is generally permitted to
            partially inline or outline code,<br>
            and so good-faith optimizations that e.g. require two
            instructions to be moved<br>
            in tandem or not at all must use tokens to establish that
            unbreakable<br>
            relationship.</p>
        </div>
      </div>
    </blockquote>
    I think the way your framing this is dangerous.  We absolutely can
    not allow any annotation of this form to *weaken* the semantics of
    the existing IR.  We can and should impose a criteria that any
    extension of this variety strictly add information to the IR which
    might not have been previously inferred.  We can then design rules
    for how to preserve our new information as long as possible, but
    framing this in terms of disallowed transformations is really a
    non-starter.  <br>
    <blockquote type="cite"
      cite="mid:1C826C88-A140-49E7-A291-9DD3CB41AF23@apple.com">
      <div style="font-family:sans-serif">
        <div style="white-space:normal">
          <blockquote style="border-left:2px solid #777; color:#777;
            margin:0 0 5px; padding-left:5px">
            <blockquote style="border-left:2px solid #777; color:#999;
              margin:0 0 5px; padding-left:5px; border-left-color:#999">
              <p dir="auto">So the defining property of a good-faith
                optimization is that:<br>
                - there are rules which participating functions are
                expected to follow on<br>
                pain of undefined behavior but which LLVM IR doesn't
                require every function<br>
                to follow, and<br>
                - those rules will be preserved by any transform that
                doesn't move code<br>
                between functions and which preserves the apparent
                function semantics<br>
                and maintains the standard structural rules of LLVM IR.</p>
            </blockquote>
            <p dir="auto">In other words, certain things are UB in
              functions tagged with<br>
              supported_optimizations that are not UB otherwise? This
              breaks code<br>
              hoisting transformations right? I.e.<br>
              isSafeToSpeculativelyExecute(Inst) will have to return
              false if Inst<br>
              is in a function with a non-empty supported_optimizations?</p>
          </blockquote>
          <p dir="auto">Good question. I would consider that to be an
            unacceptable intrusion:<br>
            intraprocedural transforms should never have to be aware of<br>
            supported_optimizations (unless they're implementing a
            good-faith<br>
            optimization, of course) and interprocedural transforms
            should only have<br>
            to be aware of supported_optimizations in the narrow sense
            outlined<br>
            by Piotr. If something about the optimization's
            representation in IR<br>
            is unsafe to speculate, it should be made impossible to
            speculate for<br>
            standard semantic/structural reasons, like having apparently
            arbitrary<br>
            side-effects.</p>
          <p dir="auto">I think the right way to formalize this is to
            say that, while the<br>
            good-faith optimization may impose additional UB rules on
            the function,<br>
            it must guarantee that transforms that are well-behaved as
            described<br>
            above --- i.e. that preserve standard structure and
            semantics and which,<br>
            if interprocedural, appropriately honor
            supported_optimizations --- will<br>
            never introduce new UB.</p>
          <p dir="auto">John.</p>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
  </body>
</html>