<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hi Vit,</p>
    <p>Yes, please file a bug report. DAGCombiner::visitFDIV should call
      BuildReciprocalEstimate, and then MachineLICM should hoist the
      reciprocal-generation out of the loop. I imagine that the problem
      here is really in X86TargetLowering::getRecipEstimate, which says
      this:</p>
    <p>  // It is likely not profitable to do this for f64 because a
      double-precision<br>
        // reciprocal estimate with refinement on x86 prior to FMA
      requires<br>
        // 15 instructions: convert to single, rcpss, convert back to
      double, refine<br>
        // (3 steps = 12 insts). If an 'rcpsd' variant was added to the
      ISA<br>
        // along with FMA, this could be a throughput win.<br>
    </p>
    <p>It seems like we need to be a bit smarter about this.</p>
    <p> -Hal<br>
    </p>
    <div class="moz-cite-prefix">On 03/06/2017 06:11 AM, vit9696 via
      llvm-dev wrote:<br>
    </div>
    <blockquote cite="mid:4A869D35-C388-465A-9466-8DE3A7D5F9C7@avp.su"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      Hello,
      <div class=""><br class="">
      </div>
      <div class="">Recently I have stumbled across an almost double
        performance decrease in one of my codebases when compiling with
        clang instead of gcc. I was testing with the currently latest
        3.9.1 as well as 4.0.0 rc2 targeting x86-64 darwin with -Ofast,
        and after some investigation was able to narrow down the code to
        the following snippet:</div>
      <div class=""><br class="">
      </div>
      <div class="">
        <div class="">__attribute__ ((noinline)) bool calculate(double
          c) {</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>uint32_t
          b = 0;</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>uint32_t
          a = 0;</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>while
          (b < 0xFFFFFFFF) {</div>
        <div class=""><span class="Apple-tab-span" style="white-space: pre;">         </span>if
          ((uint64_t)(b / c) % 2 == 0)</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">                   </span>a++;</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>b++;</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>}</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>return
          a;</div>
        <div class="">}</div>
      </div>
      <div class=""><br class="">
      </div>
      <div class="">The culprit here is the division, which is not
        hoisted out of the loop and replaced with a multiplication by
        a reciprocal. From what I understand the current implementation
        of combineRepeatedFPDivisors responsible for floating point
        division conversion does that given that the following
        preconditions are met:</div>
      <div class="">— unsafe math optimisations are enabled;</div>
      <div class="">— the amount of the divisions by the same divisor in
        a single basic block is above the threshold (2 for x86-64).</div>
      <div class=""><br class="">
      </div>
      <div class="">According to the IR the divisions are in two
        separate blocks, and I guess that it must be the reason for the
        optimisation not taking place. This seems to be proven by using
        an even loop count like 0xFFFFFFF0 to avoid a middle check. In
        this case the optimisation works just fine. Here are the IR
        samples: <a moz-do-not-send="true"
          href="https://ghostbin.com/paste/r4td2" class="">https://ghostbin.com/paste/r4td2</a>.</div>
      <div class=""><br class="">
      </div>
      <div class="">At this point the thoughts arising on my side are:</div>
      <div class="">— Should this be considered a bug and reported to
        llvm-bugs or a desired behaviour?</div>
      <div class="">— If this is considered a bug, how is one supposed
        to fix it? With the exact sample provided the compiler could
        generally predict the amount of iterations being over the
        threshold and optimise the output, however, the real world
        examples (including mine) will unlikely be that simple. Loop
        body would be much larger, the conditions would be more
        complicated, the divisions would likely occur in several
        different basic blocks for various reasons, and I think in
        general it is not possible to predict the iteration count.</div>
      <div class="">
        <div class="">— From what I can tell at least current gcc
          (6.3.0) and icc (17.0.2) are capable of doing that, with both
          this snippet and even when the loop count depends on an
          another argument, which means they are not capable to
          determine whether there would only be 0 iterations or many
          more, however, the optimisation would still be applied (<a
            moz-do-not-send="true"
            href="https://ghostbin.com/paste/ttnrz" class="">https://ghostbin.com/paste/ttnrz</a>).
          Perhaps llvm could also be more permissive when it sees a
          loop?</div>
      </div>
      <div class=""><br class="">
      </div>
      <div class="">Best regards,</div>
      <div class="">Vit</div>
      <div class=""><br class="">
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <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>
    <br>
    <pre class="moz-signature" cols="72">-- 
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
  </body>
</html>