[LLVMdev] Optimize away sqrt in simple cases?

Stephen Lin swlin at post.harvard.edu
Tue Apr 23 23:53:40 PDT 2013


On Wed, Apr 24, 2013 at 1:50 AM, Owen Anderson <resistor at mac.com> wrote:
>
> On Apr 23, 2013, at 7:15 PM, Stephen Lin <swlin at post.harvard.edu> wrote:
>
>>> This is not true.  The mathematically correct result for sqrt might not be a representable value in floating point, so rounding may occur between the two steps.  In that case, pow2(sqrt(x)) != x.
>>
>> I think what Christoph is saying is that x will always be at least as
>> accurate as pow2(sqrt(x)), so it's only unsafe in so far as one's code
>> is actually depending on an imprecise result.
>
> Giving more-than-expected precision can be just as bad for the user as less.  It tends to come up in situations where the optimization would break some symmetry, the same way that aggressively forming FMAs can break user code.  Consider this example:
>
> float foo(float a, float b) {
>   return pow2(a) - pow2(sqrt(b));
> }
>
> float bar(float c) {
>   return foo(sqrt(b), b);
> }
>
> The author *should* be able to assume that for any positive c, the only possible output values are Inf and zero.  However, if we apply the pow2/sqrt peephole, suddenly non-zero finite outputs are possible.  The equivalent example for FMA formation is x*x - x*x.  If we convert that to "fma x, x, (-x*x)", you can get a non-zero finite result.
>
> It boils down to the fact that giving excess precision in some-places-but-not-others can lead to bad behavior.
>
> --Owen

OK, that makes sense--just clarifying what I thought Christoph meant.
In any case, maybe it ought to be at least an option for "fast math"
or in some other setting where mathematical identities that may gain
or lose precision are taken advantage of. (I know GCC's version of
"fast math" allows lots of things that are potentially more unsafe
than this; I'm not familiar of the state of clang's equivalent).

Stephen




More information about the llvm-dev mailing list