Richard Biener wrote:
>On Thu, Jan 4, 2018 at 10:27 PM, Marc Glisse <marc.gli...@inria.fr> wrote:

>> I don't understand how the check you added helps.

It simply blocks the transformation for infinity:

+      (if (!REAL_VALUE_ISINF (TREE_REAL_CST (@0)))
+       (switch
+       (if (real_less (&dconst0, TREE_REAL_CST_PTR (@0)))
+        (op @1 @2))
+       /* For C < 0, use the inverted operator.  */
+       (if (real_less (TREE_REAL_CST_PTR (@0), &dconst0))
+        (neg_op @1 @2)))))))

I can't see what is potentially problematic here, it excludes infinity. I can 
replace
the flag_unsafe_math_optimizations with HONOR variants and then the infinity 
check is no longer required.


>>> We could change C / x > 0 to x >= 0 so the underflow case is included.
>>> However that still means x == 0.0 would behave differently - so the
>>> question is
>>> what exactly does -funsafe-math-optimization allow?
>>
>>
>> That is indeed unclear. HONOR_SIGNED_ZEROS, HONOR_NANS, HONOR_INFINITIES are
>> better defined and could also see some use.
>>
>> 1/X>=0: if X can be zero (and the inverse can be infinite), the result
>> depends on the sign of that zero. If !HONOR_SIGNED_ZEROS ||
>> !HONOR_INFINITIES, it looks like we can simplify to either X>0 or X>=0,
>> doesn't matter which.

Agreed.

>> 1/X>=0 is true iff X is not NaN and the sign bit is not set, so with
>> !HONOR_NANS it could also be turned into a bit test.

That's unlikely more efficient than a compare with zero.

>> It works the same for C/X>=0 with 0<C<infinity. For C=infinity, the main
>> difference is that X=infinity now gives false (if HONOR_NANS).

Yes that's why C=infinity is excluded in the latest version. However if we 
already
check HONOR_INFINITIES it wouldn't be needed.

>> C/X>0 is more tricky because small/big may round to zero. For C large enough
>> (assuming denormals, 1 is large enough for instance), the only new issue is
>> X=infinity. For smaller C, we start getting wrong results for finite values
>> of X, and presumably that's where flag_unsafe_math_optimizations comes into
>> play.

Well we can change C/X > 0 to X >= 0. That deals with underflow cases when
X is a normal, and results in the same cases that are wrong as C/X >= 0
(X = -0 and X = +Inf assuming C>0), so  !HONOR_SIGNED_ZEROS && 
!HONOR_INFINITIES should be sufficient for all cases.

>> If we consider flag_unsafe_math_optimizations as a kitchen sink that implies
>> !HONOR_SIGNED_ZEROS && !HONOR_INFINITIES, then you don't even need your
>> REAL_VALUE_ISINF test.

Indeed. Changing it to use more descriptive tests is a good idea indeed as it 
makes it
more explicit which cases are not supported.


> Without looking at the latest patch -funsafe-math-optimizations is a
> kitchen-sink
> we should avoid at all cost.  In the past we somewhat decided to break it up
> properly (-fassociative-math and friends have been added for example),
> and we really
> don't want to add more stuff under this umbrella (there's too much
> under it already).
> I'm not sure if C / x op 0.0 to x op 0.0 is association though (I'm
> quite sure it isn't),
> so citing association examples doesn't work for me here ;)

Marc's proposal to use HONOR_* instead of flag_unsafe_math_optimizations
should work, I'll give it a go. Maybe in the future we should aim to replace all
existing uses.

> It might be we need some new flag like -fassume-infinite-precision-math to
> cover the underflow issue?  We do have -ffinite-math-only but that
> shouldn't allow
> GCC to possibly introduce +-Inf for overflow - GCC just can assume there are
> no overflows in the original user expression.

We can avoid the underflow for normal numbers, so I don't think there is need
for a new flag.

Wilco
    

Reply via email to