<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 30, 2012, at 4:19 PM, Dan Gohman <<a href="mailto:dan433584@gmail.com">dan433584@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">On Tue, Oct 30, 2012 at 2:25 PM, Michael Ilseman <span dir="ltr"><<a href="mailto:milseman@apple.com" target="_blank">milseman@apple.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Here's a new version of the RFC, incorporating and addressing the feedback from Krzysztof, Eli, Duncan, and Dan.<br>
<br>
<br>
Revision 1 changes:<br>
  * Removed Fusion flag from all sections<br>
  * Clarified and changed descriptions of remaining flags:<br>
    * Make 'N' and 'I' flags be explicitly concerning values of operands, and<br>
      producing undef values if a NaN/Inf is provided.<br>
    * 'S' is now only about distinguishing between +/-0.<br>
    * LangRef changes updated to reflect flags changes<br>
    * Updated Quesiton section given the now simpler set of flags<br>
    * Optimizations changed to reflect 'N' and 'I' describing operands and not<br>
      results<br>
  * Be explicit on what LLVM's default behavior is (no signaling NaNs, etc)<br>
  * Mention that this could be solved with metadata, and open the debate<br>
<div class="im"><br>
Introduction<br>
---<br>
<br>
LLVM IR currently does not have any support for specifying fine-grained control<br>
over relaxing floating point requirements for the optimizer. The below is a<br>
proposal to extend floating point IR instructions to support a number of flags<br>
that a creator of IR can use to allow for greater optimizations when<br>
desired. Such changes are sometimes referred to as fast-math, but this proposal<br>
is about finer-grained specifications at a per-instruction level.<br>
<br>
<br>
What this doesn't address<br>
---<br>
<br>
Default behavior is retained, and this proposal is only addressing relaxing<br>
</div>restrictions. LLVM currently by default:<br>
 - ignores signaling NaNs<br>
 - assumes default rounding mode<br>
 - assumes FENV_ACCESS is off<br>
<div class="im"><br>
Discussion on changing the default behavior of LLVM or allowing for more<br>
restrictive behavior is outside the scope of this proposal. This proposal does<br>
not address behavior of denormals, which is more of a backend concern.<br>
<br>
Specifying exact precision control or requirements is outside the scope of this<br>
proposal, and can probably be handled with the existing metadata implementation.<br>
<br>
This proposal covers changes to and optimizations over LLVM IR, and changes to<br>
codegen are outside the scope of this proposal. The flags described in the next<br>
section exist only at the IR level, and will not be propagated into codegen or<br>
the SelectionDAG.<br>
<br>
<br>
Flags<br>
---<br>
no NaNs (N)<br>
</div>  - The optimizer is allowed to optimize under the assumption that the operands'<br>
    values are not NaN. If one of the operands is NaN, the value of the result<br>
    is undefined.<br>
<br>
no Infs (I)<br>
  - The optimizer is allowed to optimize under the assumption that the operands'<br>
    values are not +/-Inf. If one of the operands is +/-Inf, the value of the<br>
    result is undefined.<br>
<br>
no signed zeros (S)<br>
  - The optimizer is allowed to not distinguish between -0 and +0 for the<br>
    purposes of optimizations.<br></blockquote><div><br></div><div>Ok, I checked LLVM CodeGen's existing -enable-no-infs-fp-math and -enable-no-nans-fp-math flags, and GCC's -ffinite-math-only flag, and they all say they apply to results as well as arguments. Do you have a good reason for varying from existing practice here?</div>
<div><br></div></div></blockquote><div><br></div><div>The primary example I was trying to simplify with that change was x * 0 ==> 0. It can be performed if you assume NIS inputs, or NS inputs and N outputs. This is because Inf * 0 is NaN. In hindsight, this is all making things more confusing, so I think I'll go back to "arguments and results" and allow this optimization for NS. GCC gets around this by lumping Inf and NaN under the same command line option.</div><br><blockquote type="cite"><div class="gmail_quote"><div>Phrasing these from the perspective of the optimizer is a little confusing here. </div></div></blockquote><div><br></div><div>I think it might be clearer to change "The optimizer is allowed to …" to "Allow optimizations to …" and clean up the wording a bit.</div><br><blockquote type="cite"><div class="gmail_quote"><div>Also, "The optimizer is allowed to [not care about X]" read literally means that the semantics for X are unconstrained, which would be Undefined Behavior. For I and N here you have a second sentence which says only the result is undefined, but for S you don't. </div></div></blockquote><div><br></div><div><div>'S' shouldn't have any undefined behavior, it just allows optimizations to not distinguish between +/-0. <span style="background-color: rgb(255, 255, 255); font-family: arial, sans-serif; font-size: 13px; ">It's perfectly legal for the operation to receive a negative zero, the operation just might treat it exactly the same as a positive zero. I would rather have that than undefined behavior.</span></div><div><br></div><div>This is similar to how gcc defines <b style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">-fno-signed-zeros:</b></div><div><span style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">"Allow optimizations for floating point arithmetic that ignore the signedness of zero. </span><small style="font-family: arial, sans-serif; background-color: rgb(255, 255, 255); ">IEEE</small><span style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); "> arithmetic specifies the behavior of distinct +0.0 and -0.0 values, which then prohibits simplification of expressions such as x+0.0 or 0.0*x (even with </span><b style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">-ffinite-math-only</b><span style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">). This option implies that the sign of a zero result isn't significant."</span></div><div><span style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); "><br></span></div><div><span style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">I'll revise my description to also mention that the sign of a zero result isn't significant. </span></div></div><br><blockquote type="cite"><div class="gmail_quote"><div>Also, even when you do have the second sentence, it seems to contradict the first sentence.</div>
<div><br></div></div></blockquote><div><br></div><div>Why does it contradict the first sentence? I meant it as a clarification or reinforcement of the first, not a contradiction.</div><div><br></div><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">
<br>
unsafe algebra (A)<br>
  - The optimizer is allowed to perform algebraically equivalent transformations<br>
<div class="im">     that may dramatically change results in floating point. (e.g.<br>
     reassociation)<br>
<br>
Throughout I'll refer to these options in their short-hand, e.g. 'A'.<br>
Internally, these flags are to reside in SubclassData.<br>
<br>
<br>
======<br>
Question:<br>
<br>
Not all combinations make sense (e.g. 'A' pretty much implies all other flags).<br>
<br>
</div>Basically, I have the below lattice of sensible relations:<br>
  A > S > N<br>
  A > I > N<br>
Meaning that 'A' implies all the others, 'S' implies 'N', etc.<br></blockquote><div><br></div><div>Why does S still imply N?</div><div><br></div><div>Also, I'm curious if there's a specific motivation to have I imply N. LLVM CodeGen's existing options for these are independent.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
It might be desirable to simplify this into just being a fast-math level.<br></blockquote><div><br></div><div>What would make this desirable?</div><div> </div></div></blockquote><div><br></div><div>I think this "Question" I had no longer makes too much sense, so I'm going to delete this section.</div><br><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; ">
<div class="im">Changes to optimizations<br>
---<br>
<br>
Optimizations should be allowed to perform unsafe optimizations provided the<br>
instructions involved have the corresponding restrictions relaxed. When<br>
combining instructions, optimizations should do what makes sense to not remove<br>
restrictions that previously existed (commonly, a bitwise-AND of the flags).<br>
<br>
Below are some example optimizations that could be allowed with the given<br>
relaxations.<br>
<br>
N - no NaNs<br>
  x == x ==> true<br>
<br>
S - no signed zeros<br>
  x - 0 ==> x<br>
  0 - (x - y) ==> y - x<br>
<br>
</div>NIS - no signed zeros AND no NaNs AND no Infs<br>
<div class="im">  x * 0 ==> 0<br>
<br>
NI - no infs AND no NaNs<br>
  x - x ==> 0<br>
<br>
</div>A - unsafe-algebra<br>
  Reassociation<br>
    (x + y) + z ==> x + (y + z)<br>
<div><div class="h5">    (x + C1) + C2 ==> x + (C1 + C2)<br>
  Redistribution<br>
    (x * C) + x ==> x * (C+1)<br>
    (x * C) + (x + x) ==> x * (C + 2)<br>
  Reciprocal<br>
   x / C ==> x * (1/C)<br>
<br>
These examples apply when the new constants are permitted, e.g. not denormal,<br>
and all the instructions involved have the needed flags.<br></div></div></blockquote><div><br></div><div>I'm still confused by what you mean in this sentence. Why are you talking about constants, if you intend this optimizations to be valid for non-constants? And, it's not clear what you're trying to say about denormal values here.</div>
<div><br></div></div></blockquote><div><br></div><div>I was mentioning denormals for one of the optimizations. I think it would be more clear to say something like:</div><div><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; position: static; z-index: auto; "><div class="h5"> Reciprocal<br>   x / C ==> x * (1/C)  when (1/C) is not denormal</div></blockquote></div></blockquote><br></div><div>I was mostly trying to say that the optimizations are not blindly applied, but are applied when they are still legal. I think the sentence is more confusing than helpful, though.</div><br><blockquote type="cite"><div class="gmail_quote"><div>Dan</div><div><br></div></div>
</blockquote></div><br><div>Thanks!</div></body></html>