<div dir="ltr">On Fri, Jun 21, 2013 at 5:11 PM, Erik Schnetter <span dir="ltr"><<a href="mailto:schnetter@cct.lsu.edu" target="_blank">schnetter@cct.lsu.edu</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="im">On Fri, Jun 21, 2013 at 7:54 AM, David Tweed <span dir="ltr"><<a href="mailto:david.tweed@arm.com" target="_blank">david.tweed@arm.com</a>></span> wrote:<br>
</div><div class="gmail_extra"><div class="gmail_quote"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>| LLVM does not currently have special lowering handling for round(), and<br>
I'll propose a patch to add that, but the larger question is this: should<br>
fast-math change the tie-breaking behavior of<br>
| rint/nearbyint/round, etc. and, if so, should we make a specific effort to<br>
have all backends provide the same guarantee (or lack of a guarantee) in<br>
this regard?<br>
<br>
</div>I don't know, primarily because I've never really been involved in anything<br>
where I've cared about using exotic rounding modes. But in general I'm of<br>
the opinion that -fast-math is the "nuclear option" that's allowed to do<br>
lots of things which may well invoke backend specific behaviour. (That's<br>
also why I think that most FP transformations shouldn't be "only" guarded by<br>
fast-math but a more precise option.)</blockquote><div><br></div></div><div>The functions rint and round and standard libm functions commonly used to round floating point values to integers. Both round to the nearest integer, but break ties differently -- rint uses IEEE tie breaking (towards even), round uses mathematical tie breaking (away from zero).</div>

<div><br></div><div>The question here is: Is this optimization worthwhile, or would it surprise too many people? Depending on this, it should either be disallowed, or possibly implemented for other back-ends as well.</div>
</div></div></div></blockquote><div><br></div><div>After some consideration, I have come to the conclusion that this optimization (changing rint to round) is not worthwhile. There are some floating point operations that can provide an exact result, and not obtaining this exact result is surprising. For example, I would expect that adding/multiplying two small integers gives the exact result, or that fmin/fmax give the correct result if no nans are involved, or that comparisons yield the correct answer (again in the absence of nans, denormalized numbers etc.).</div>
<div><br></div><div>The case here -- rint(0.5) -- involves an input that can be represented exactly, and an output that can be represented exactly (0.0). Neither nans, infinities, nor denormalized numbers are involved. In this case I do expect the correct answer, even with full floating point operations that ignore nans, infinities, denormalized numbers, or that re-associate etc.</div>
<div><br></div><div>-erik</div><div><br></div><div>PS:</div><div><br></div><div>I think that</div><div><br></div><div>rint(x) = x + copysign(M,x) - copysign(M,x)</div><div><br></div><div>where M is a magic number, and where the addition and subtraction cannot be optimized. I believe M=2^52. This should work fine at least for "reasonably small" numbers.</div>
</div><div><br></div>-- <br>Erik Schnetter <<a href="mailto:schnetter@cct.lsu.edu" target="_blank">schnetter@cct.lsu.edu</a>><br><a href="http://www.perimeterinstitute.ca/personal/eschnetter/" target="_blank">http://www.perimeterinstitute.ca/personal/eschnetter/</a>
</div></div>