<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 29, 2017, at 4:39 AM, Hal Finkel <<a href="mailto:hfinkel@anl.gov" class="">hfinkel@anl.gov</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
  
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type" class="">
  
  <div bgcolor="#FFFFFF" text="#000000" class="">
    <div class="moz-cite-prefix">On 06/28/2017 05:33 PM, Peter Lawrence
      wrote:<br class="">
    </div>
    <blockquote cite="mid:37027DE0-B3CC-47C2-907C-C5A7A5A97BD1@sbcglobal.net" type="cite" class="">Chandler,
      <div class="">               where we disagree is in whether the
        current project is moving the issue</div>
      <div class="">forward.  It is not.  It is making the compiler more
        complex for no additional value.</div>
      <div class=""><br class="">
      </div>
      <div class="">The current project is not based in evidence, I have
        asked for any SPEC benchmark</div>
      <div class="">that shows performance gain by the compiler taking
        advantage of “undefined behavior”</div>
      <div class="">and no one can show that.</div>
    </blockquote>
    <br class="">
    I can't comment on SPEC, but this does remind me of code I was
    working on recently. To abstract the relevant parts, it looked
    something like this:<br class="">
    <br class="">
    template <typename T><br class="">
    int do_something(T mask, bool cond) {<br class="">
      if (mask & 2)<br class="">
        return 1;<br class="">
    <br class="">
      if (cond) {<br class="">
        T high_mask = mask >> 48;<br class="">
        if (high_mask > 5)<br class="">
          do_something_1(high_mask);<br class="">
        else if (high_mask > 3)<br class="">
          do_something_2();<br class="">
      }<br class="">
    <br class="">
      return 0;<br class="">
    }<br class="">
    <br class="">
    This function ended up being instantiated on different types T (e.g.
    unsigned char, unsigned int, unsigned long, etc.) and, dynamically,
    cond was always false when T was char. The question is: Can the
    compiler eliminate all of the code predicated on cond for the
    smaller types? In this case, this code was hot, and moreover,
    performance depended on the fact that, for T = unsigned char, the
    function was inlined and the branch on cond was eliminated. In the
    relevant translation unit, however, the compiler would never see how
    cond was set.<br class="">
    <br class="">
    Luckily, we do the right thing here currently. In the case where T =
    unsigned char, we end up folding both of the high_mask tests as
    though they were false. That entire part of the code is eliminated,
    the function is inlined, and everyone is happy.<br class="">
    <br class="">
    Why was I looking at this? As it turns out, if the 'else if' in this
    example is just 'else', we don't actually eliminate both sides of
    the branch. The same is true for many other variants of the
    conditionals (i.e. we don't recognize all of the code as dead).</div></div></blockquote><div><div><br class=""></div><div><br class=""></div><div>I apologize in advance if I have missed something here and am misreading your example...</div><div class=""><br class=""></div></div><div>This doesn’t make sense to me, a shift amount of 48 is “undefined” for unsigned char,</div><div>How do we know this isn’t a source code bug,</div><div>What makes us think the the user intended the result to be “0”.</div><div><br class=""></div><div>This strikes me as odd, we are mis-interpreting the user’s code </div><div>In such a way so as to improve performance, but that isn’t necessarily what the user intended.</div><div><br class=""></div><div>Here’s one way to look at this issue, if something is “C undefined behavior” then</div><div>The standard says, among other things, that we could trap here</div><div>Why aren’t we doing that rather than optimizing it ?</div><div><br class=""></div><div>Here’s another way to look at it, no one has ever filed a bug that reads</div><div>“I used undefined behavior in my program, but the optimizer isn’t taking advantage of it”</div><div>But if they do I think the response should be </div><div>“you should not expect that, standard says nothing positive about what undefined behavior does"</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div bgcolor="#FFFFFF" text="#000000" class=""> Once
    we have a self-consistent model for undef, we should be able to fix
    that. The user was confused, however, why seemingly innocuous
    changes to the code changed the performance characteristics of their
    application. The proposed semantics by John, et al. should fix this
    uniformly.<br class="">
    <br class="">
    In any case, to your point about:<br class="">
    <br class="">
    <blockquote type="cite" class="">
      <div style="margin: 0px; font-size: 14px; line-height: normal;
        font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures:
          no-common-ligatures" class="">  if (a == a)</span></div>
      <div style="margin: 0px; font-size: 14px; line-height: normal;
        font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures:
          no-common-ligatures" class="">    S;</span></div>
    </blockquote>
    <br class="">
    I have the same thought. If a == undef here, the code should be
    dead. Dead code must be aggressively dropped to enable inlining and
    further optimization. This is an important way we eliminate
    abstraction penalties. Dead code also has costs in terms of register
    allocation, speculative execution, inlining, etc.<br class="">
    <br class=""></div></div></blockquote><div><br class=""></div><div>And yet  IIRC Sanjoy in his last email was arguing for consistent behavior in cases like</div><div>If (x != 0) {</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>/* we can optimize in the then-clause assuming x != 0 */</div><div>}</div><div>And in the case above when it is a function that gets inlined</div><div><br class=""></div><div>Here’s what Sanjoy said about the function-inline case</div><div><br class="">> This too is fixed in the semantics mentioned in the paper.  This also<br class="">> isn't new to us, it is covered in section 3.1 "Duplicate SSA Uses".<br class=""></div><div><br class=""></div><div>So this issue seems to be up in the air</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div bgcolor="#FFFFFF" text="#000000" class="">
    I've also seen cases where templated types are used with fixed-sized
    arrays where the compiler to leveraged knowledge of UB on
    uninitialized values and out-of-bounds accesses to eliminate
    unnecessary part of the code. In short, "optimizing on undefined
    behavior" can end up being an important tool.<br class="">
    <br class=""></div></div></blockquote><div><br class=""></div><div>As you can tell from my first comments, I am not yet convinced, and would still like to see real evidence</div><div><br class=""></div><div><br class=""></div><div>Peter Lawrence.</div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div bgcolor="#FFFFFF" text="#000000" class="">
     -Hal<br class="">
    <pre class="moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
  </div>

</div></blockquote></div><br class=""></body></html>