On Fri, Dec 11, 2020 at 10:44 AM Xionghu Luo <[email protected]> wrote:
>
>
> On 2020/12/11 15:47, Richard Biener wrote:
> >> Note that the add/sub sequence is different for (3) and (4) since
> >> -funsafe-math-optimizations is implicitly true. "fp-contract=fast" in
> >> (1) and (2) could avoid Inf as fmads could handle float overflow (verified
> >> it on Power, not sure other targets support this), but without float
> >> value-range info, it is unsafe to change computation from double to
> >> float even for only add/sub expressions.
> > Yes. As said it's difficult to second guess the programmer here.
> > The existing cases doing promotion look at unary functions,
> > doing exp->expf when arguments are promoted floats and the
> > return value is casted back to float. That's also a common programmer
> > "error" not knowing expf or assuming some kind of magic overloading.
>
> Yes, that is "(float) fabs (float)" -> "(float) fabsf (float)" as (1),
> that seems should be done in front end to generate fabsf or "warning" to
> programmer?
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326#c4, refused by Andew and
> Joseph,
> reason is front end shouldn't do any optimization there.)
>
> Currently, gimple code already generates below code(though no ABSF_EXPR or
> EXPF_EXPR),
> but due to ABS_EXPR return double, many double conversions are also produced
> for the MUL and ADD operations, and that why I propose to do it in match.pd.
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326#c9, also refused by you
> due to
> complex static pattern matching, also it will cause potential Inf issue like
> last mail.)
>
> 1) cat liv.c.006t.gimple
> __attribute__((noinline))
> foo (float x, float y, float z)
> {
> float D.4356;
>
> _1 = ABS_EXPR <x>;
> _2 = (double) _1;
> _3 = (double) y;
> _4 = _2 * _3;
> _5 = (double) z;
> _6 = _4 + _5;
> D.4356 = (float) _6;
> return D.4356;
> }
>
> For "(float) fabs (double)" like (2), it is not quite reasonable to do fabs
> -> fabsf.
what's the error case you are worried about in this particular case?
> 2) cat liv.c.006t.gimple
> __attribute__((noinline))
> foo (double x, float y, float z)
> {
> float D.4356;
>
> _1 = ABS_EXPR <x>;
> _2 = (double) y;
> _3 = _1 * _2;
> _4 = (double) z;
> _5 = _3 + _4;
> D.4356 = (float) _5;
> return D.4356;
> }
>
> >
> > So I'm not entirely convinced such transform is a good idea, at least
> > by default with -ffast-math. Maybe have a -fassume-float-limited-range
> > or so documented as that we assume that double or long double values
> > used fit in floats?
>
> Thanks for the idea, just to confirm where should this option work, In
> match.pd
> or gimple pass for only abs/exp to absf/expf, etc? Even with the option, I am
> afraid the option is still not effective for computation?
I still think that covering all "good" cases in match.pd will require excessive
matching and that it is better done in a pass (this would include removing
the frontend handling for math functions). Note that for example
(float)((double)x + (double)y) with float x and y is also eligible to demotion
to float, likewise may some compositions like
(float)(sin((double)x)*cos ((double)y))
for float x and y since we can constrain ranges here. Likewise
(float)((double)x + fabs ((double)y)) for float x and y. The
propagation would need
to stop when the range needed increases in unknown ways.
>
> Thanks,
> Xionghu
>
>