public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
@ 2020-11-17  7:07 ` luoxhu at gcc dot gnu.org
  2020-11-17  7:10 ` luoxhu at gcc dot gnu.org
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-17  7:07 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

luoxhu at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |luoxhu at gcc dot gnu.org,
                   |                            |pinskia at gcc dot gnu.org,
                   |                            |segher at kernel dot crashing.org

--- Comment #4 from luoxhu at gcc dot gnu.org ---
float foo(float f, float x, float y) {
return (fabs(f)*x+y);
}

the input of fabs is float type, so use fabsf is enough here, drafted a patch
to avoid double promotion when generating gimple if fabs could be replaced by
fabsf as argument[0] is float type.


diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index ecc3d2119fa..1a2d7e624cc 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -10470,6 +10470,20 @@ c_parser_postfix_expression_after_primary (c_parser
*parser,
                  && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
                  && vec_safe_length (exprlist) == 1)
                warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
+
+             if (fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
+                 && DECL_FUNCTION_CODE (expr.value) == BUILT_IN_FABS)
+               {
+                 tree arg0 = (*exprlist)[0];
+                 if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (expr.value)))
+                       > TYPE_PRECISION (TREE_TYPE (arg0))
+                     && TYPE_MODE (TREE_TYPE (arg0)) == E_SFmode)
+                   {
+                     tree abs_fun = get_identifier ("fabsf");
+                     expr.value = build_external_ref (expr_loc, abs_fun, true,
+                                                      &expr.original_type);
+                   }
+               }
            }

          start = expr.get_start ();


.006t.gimple:

__attribute__((noinline))
foo (float f, float x, float y)
{
  float D.4347;

  _1 = ABS_EXPR <f>;
  _2 = x * _1;
  D.4347 = y + _2;
  return D.4347;
}


foo:
.LFB0:
        .cfi_startproc
        fabs 1,1
        fmadds 1,1,2,3
        blr

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
  2020-11-17  7:07 ` [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to luoxhu at gcc dot gnu.org
@ 2020-11-17  7:10 ` luoxhu at gcc dot gnu.org
  2020-11-17 10:21 ` pinskia at gcc dot gnu.org
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-17  7:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #5 from luoxhu at gcc dot gnu.org ---
With above hack, changing argument x from float to double could still generate
correct code with conversion of fabsf result:

float foo(float f, double x, float y) {
return (fabs(f)*x+y);
}

006t.gimple
__attribute__((noinline))
foo (float f, double x, float y)
{
  float D.4347;

  _1 = ABS_EXPR <f>;
  _2 = (double) _1;
  _3 = x * _2;
  _4 = (double) y;
  _5 = _3 + _4;
  D.4347 = (float) _5;
  return D.4347;
}

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
  2020-11-17  7:07 ` [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to luoxhu at gcc dot gnu.org
  2020-11-17  7:10 ` luoxhu at gcc dot gnu.org
@ 2020-11-17 10:21 ` pinskia at gcc dot gnu.org
  2020-11-17 21:56 ` joseph at codesourcery dot com
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu.org @ 2020-11-17 10:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to luoxhu from comment #4)
> float foo(float f, float x, float y) {
> return (fabs(f)*x+y);
> }
> 
> the input of fabs is float type, so use fabsf is enough here, drafted a
> patch to avoid double promotion when generating gimple if fabs could be
> replaced by fabsf as argument[0] is float type.

what about adding something to match.pd for:
ABS<(float_convert)f> into (float_convert)ABS<f>
This is only valid prompting and not reducing the precision.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2020-11-17 10:21 ` pinskia at gcc dot gnu.org
@ 2020-11-17 21:56 ` joseph at codesourcery dot com
  2020-11-18 15:22 ` segher at gcc dot gnu.org
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: joseph at codesourcery dot com @ 2020-11-17 21:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #7 from joseph at codesourcery dot com <joseph at codesourcery dot com> ---
I agree that match.pd is a sensible place for this (and the front end is 
not, we should be getting optimizations out of the front ends).

I'd encourage anyone looking at this also to look at convert_to_real_1, 
which has different, related optimizations (which also would be better off 
in match.pd rather than as part of convert).

The particular example test in this bug report would also need to pass 
that deals with fusing operations (when permitted by the fp-contract 
setting) to handle the case where promotions to a wider type (with the 
same radix) are involved; I don't know if it does handle that at present.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (3 preceding siblings ...)
  2020-11-17 21:56 ` joseph at codesourcery dot com
@ 2020-11-18 15:22 ` segher at gcc dot gnu.org
  2020-11-23  8:39 ` luoxhu at gcc dot gnu.org
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: segher at gcc dot gnu.org @ 2020-11-18 15:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

Segher Boessenkool <segher at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |segher at gcc dot gnu.org

--- Comment #8 from Segher Boessenkool <segher at gcc dot gnu.org> ---
The fmadd;frsp sequence is correct for this source code.  It does double
rounding of the result (first to DP float, then to SP float), so using
just fmadds is only correct for -ffast-math or similar.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (4 preceding siblings ...)
  2020-11-18 15:22 ` segher at gcc dot gnu.org
@ 2020-11-23  8:39 ` luoxhu at gcc dot gnu.org
  2020-11-23  8:44 ` luoxhu at gcc dot gnu.org
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-23  8:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #9 from luoxhu at gcc dot gnu.org ---
(In reply to Andrew Pinski from comment #6)
> (In reply to luoxhu from comment #4)
> > float foo(float f, float x, float y) {
> > return (fabs(f)*x+y);
> > }
> > 
> > the input of fabs is float type, so use fabsf is enough here, drafted a
> > patch to avoid double promotion when generating gimple if fabs could be
> > replaced by fabsf as argument[0] is float type.
> 
> what about adding something to match.pd for:
> ABS<(float_convert)f> into (float_convert)ABS<f>
> This is only valid prompting and not reducing the precision.

Thanks, this is already implemented in fold-const.c, though not using match.pd
and fabsf really.  fabs will always convert arguments to double type first in
front-end.  And there are 3 kind of cases for this issue:

1) "return fabs(x);"
tree
fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
{
...
    case ABS_EXPR:
      /* Convert fabs((double)float) into (double)fabsf(float).  */
      if (TREE_CODE (arg0) == NOP_EXPR
          && TREE_CODE (type) == REAL_TYPE)
        {
          tree targ0 = strip_float_extensions (arg0);
          if (targ0 != arg0)
            return fold_convert_loc (loc, type,
                                     fold_build1_loc (loc, ABS_EXPR,
                                                  TREE_TYPE (targ0),
                                                  targ0));
        }
      return NULL_TREE;
...
}

This piece of code could convert the code from "(float)fabs((double)x)" to
"(float)(double)(float)fabs(x)", then match.pd could remove the useless
convert.

2) "return fabs(x)*y;"

Frontend will generate "(float) (fabs((double) x) * (double) y)" expression
first, 
then fold-const.c:fold_unary_loc will Convert fabs((double)float) into
(double)fabsf(float) and get "(float)((double)fabs(x) * (double)y)", finally,
match.pd will convert (outertype)((innertype0)a+(innertype1)b) into
((newtype)a+(newtype)b) to remove the double conversion.

3)"return fabs(x)*y + z;"

Frontend produces: (float) ((fabs((double) float) * (double) y) + (double z))

So what we need here is to match the MUL&ADD in match.pd as followed, any
comments?

+(simplify (convert (plus (mult (convert@3 (abs @0)) (convert@4 @1)) (convert@5
@2)))
+ (if (( flag_unsafe_math_optimizations
+       && types_match (type, float_type_node)
+       && types_match (TREE_TYPE(@0), float_type_node)
+       && types_match (TREE_TYPE(@1), float_type_node)
+       && types_match (TREE_TYPE(@2), float_type_node)
+       && element_precision (TREE_TYPE(@3)) > element_precision (TREE_TYPE
(@0))
+       && element_precision (TREE_TYPE(@4)) > element_precision (TREE_TYPE
(@1))
+       && element_precision (TREE_TYPE(@5)) > element_precision (TREE_TYPE
(@2))
+   && ! HONOR_NANS (type)
+         && ! HONOR_INFINITIES (type)))
+  (plus (mult (abs @0) @1) @2) ))
+

1) and 2) won't generate double conversion, only 3) has frsp in fast-math mode,
and it could be removed by above pattern.

PS: convert_to_real_1 seems to me not quite related here? It converts
(float)sqrt((double)x) where x is float into sqrtf(x), but with recursive call
to convert_to_real_1 and build_call_expr with new mathfn_built_in, I suppose it
a bit complicated to move them to match.pd?

The optimization should be under fast-math mode, is
flag_unsafe_math_optimizations enough to guard them?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (5 preceding siblings ...)
  2020-11-23  8:39 ` luoxhu at gcc dot gnu.org
@ 2020-11-23  8:44 ` luoxhu at gcc dot gnu.org
  2020-11-23 12:09 ` rguenther at suse dot de
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-23  8:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #10 from luoxhu at gcc dot gnu.org ---
Even we could optimize fabs to fabsf, it doesn't help here as y and z are
already promoted to double, then we still need a large pattern to match the
MUL&PLUS expression in match.pd, so fabs to fabsf seems not a reasonable
direction...

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (6 preceding siblings ...)
  2020-11-23  8:44 ` luoxhu at gcc dot gnu.org
@ 2020-11-23 12:09 ` rguenther at suse dot de
  2020-11-24 10:00 ` rsandifo at gcc dot gnu.org
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: rguenther at suse dot de @ 2020-11-23 12:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #11 from rguenther at suse dot de <rguenther at suse dot de> ---
On Mon, 23 Nov 2020, luoxhu at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326
> 
> --- Comment #10 from luoxhu at gcc dot gnu.org ---
> Even we could optimize fabs to fabsf, it doesn't help here as y and z are
> already promoted to double, then we still need a large pattern to match the
> MUL&PLUS expression in match.pd, so fabs to fabsf seems not a reasonable
> direction...

The larger expressions should be subject to a propagation pass and not
arbitrarily complex static pattern matching.  Maybe backprop is a suitable
one to wire this in.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (7 preceding siblings ...)
  2020-11-23 12:09 ` rguenther at suse dot de
@ 2020-11-24 10:00 ` rsandifo at gcc dot gnu.org
  2020-11-27  6:20 ` luoxhu at gcc dot gnu.org
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: rsandifo at gcc dot gnu.org @ 2020-11-24 10:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #12 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> ---
(In reply to rguenther@suse.de from comment #11)
> The larger expressions should be subject to a propagation pass and not
> arbitrarily complex static pattern matching.  Maybe backprop is a suitable
> one to wire this in.
Sounds good.  backprop was originally added to deal with a similar
“move things out of fold-const.c” problem (which is why it's currently
so special-purpose).

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (8 preceding siblings ...)
  2020-11-24 10:00 ` rsandifo at gcc dot gnu.org
@ 2020-11-27  6:20 ` luoxhu at gcc dot gnu.org
  2020-11-27  6:27 ` luoxhu at gcc dot gnu.org
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-27  6:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #13 from luoxhu at gcc dot gnu.org ---
Tried implementation with backprop, found that this model seems not suitable
for double promotion remove with BACK propagation.   i.e:

1) mad1.c

float foo (float x, float y, float z)
{
   return ( y * fabs (x) + z ); 
}

mad1.c.098t.cunrolli:

foo (float x, float y, float z)
{
  double _1;
  float _2;
  double _3;
  double _4;
  double _5;
  double _6;
  float _10;

  <bb 2> [local count: 1073741824]:
  _1 = (double) y_7(D);
  _2 = ABS_EXPR <x_8(D)>;
  _3 = (double) _2;
  _4 = _1 * _3;
  _5 = (double) z_9(D);
  _6 = _4 + _5;
  _10 = (float) _6;
  return _10;
}

mad1.c.099t.backprop:

[USE] _10 in return _10;
[USE] _6 in _10 = (float) _6;
  _6: convert from float to double not important
[DEF] Recording new information for _6 = _4 + _5;
  _6: convert from float to double not important
[USE] _5 in _6 = _4 + _5;
  _5: convert from float to double not important
[DEF] Recording new information for _5 = (double) z_9(D);
  _5: convert from float to double not important
[USE] _4 in _6 = _4 + _5;
  _4: convert from float to double not important
[DEF] Recording new information for _4 = _1 * _3;
  _4: convert from float to double not important
[USE] _3 in _4 = _1 * _3;
  _3: convert from float to double not important
[DEF] Recording new information for _3 = (double) _2;
  _3: convert from float to double not important
[USE] _2 in _3 = (double) _2;
  _2: convert from float to double not important
[DEF] Recording new information for _2 = ABS_EXPR <x_8(D)>;
  _2: convert from float to double not important
[USE] _1 in _4 = _1 * _3;
  _1: convert from float to double not important
[DEF] Recording new information for _1 = (double) y_7(D);
  _1: convert from float to double not important

gimple_simplified to _10 = _13;
Deleting _6 = z_9(D) + _12;
Deleting _5 = (double) z_9(D);
Deleting _4 = _2 * y_7(D);
Deleting _3 = (double) _2;
Deleting _1 = (double) y_7(D);


__attribute__((noinline))
foo (float x, float y, float z)
{
  float _2;
  float _10;
  float _12;
  float _13;

  <bb 2> [local count: 1073741824]:
  _2 = ABS_EXPR <x_8(D)>;
  _12 = _2 * y_7(D);
  _13 = z_9(D) + _12;
  _10 = _13;
  return _10;

}


All convert and promotions could be removed. But if change float x to double x,
it doesn't work now:

2)  mad2.c

float foo (double x, float y, float z)
{
   return ( y * fabs (x) + z ); 
}


mad2.c.098t.cunrolli:

foo (double x, float y, float z)
{
  double _1;
  double _2;
  double _3;
  double _4;
  double _5;
  float _9;

  <bb 2> [local count: 1073741824]:
  _1 = (double) y_6(D);
  _2 = ABS_EXPR <x_7(D)>;
  _3 = _1 * _2;
  _4 = (double) z_8(D);
  _5 = _3 + _4;
  _9 = (float) _5;
  return _9;

}

mad2.c.099t.backprop:

[USE] _9 in return _9;
[USE] _5 in _9 = (float) _5;
  _5: convert from float to double not important
[DEF] Recording new information for _5 = _3 + _4;
  _5: convert from float to double not important
[USE] _4 in _5 = _3 + _4;
  _4: convert from float to double not important
[DEF] Recording new information for _4 = (double) z_8(D);
  _4: convert from float to double not important
[USE] _3 in _5 = _3 + _4;
  _3: convert from float to double not important
[DEF] Recording new information for _3 = _1 * _2;
  _3: convert from float to double not important
[USE] _2 in _3 = _1 * _2;
  _2: convert from float to double not important
[DEF] Recording new information for _2 = ABS_EXPR <x_7(D)>;
  _2: convert from float to double not important
[USE] _1 in _3 = _1 * _2;
  _1: convert from float to double not important
[DEF] Recording new information for _1 = (double) y_6(D);
  _1: convert from float to double not important

Deleting _4 = (double) z_8(D);
Deleting _1 = (double) y_6(D);


EMERGENCY DUMP:

__attribute__((noinline))
foo (double x, float y, float z)
{
  double _2;
  double _3;
  double _5;
  float _9;

  <bb 2> [local count: 1073741824]:
  _2 = ABS_EXPR <x_7(D)>;
  _3 = _2 * y_6(D);
  _5 = _3 + z_8(D);
  _9 = (float) _5;
  return _9;

}

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (9 preceding siblings ...)
  2020-11-27  6:20 ` luoxhu at gcc dot gnu.org
@ 2020-11-27  6:27 ` luoxhu at gcc dot gnu.org
  2020-11-27  7:12 ` rguenther at suse dot de
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-27  6:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #14 from luoxhu at gcc dot gnu.org ---
(In reply to luoxhu from comment #13)
> 
> 2)  mad2.c
> 
> float foo (double x, float y, float z)
> {
>    return ( y * fabs (x) + z ); 
> }
> 
> 
> mad2.c.098t.cunrolli:
> 
> foo (double x, float y, float z)
> {
>   double _1;
>   double _2;
>   double _3;
>   double _4;
>   double _5;
>   float _9;
> 
>   <bb 2> [local count: 1073741824]:
>   _1 = (double) y_6(D);
>   _2 = ABS_EXPR <x_7(D)>;
>   _3 = _1 * _2;
>   _4 = (double) z_8(D);
>   _5 = _3 + _4;
>   _9 = (float) _5;
>   return _9;
> 
> }
> 

Maybe should use forward propagation here to save [_1, _2, _3 ... _9] to m_vars
and set ignore_convert status in usage_info if rhs of the expression could
remove double conversion, for stmt which has two rhs, need intersect status
with AND operation of rhs1 ignore_convert and rhs2 ignore_convert, also clear
the ignore_convert status if any of it is false.  Not sure whether this works,
also a bit more complicated then expected...

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (10 preceding siblings ...)
  2020-11-27  6:27 ` luoxhu at gcc dot gnu.org
@ 2020-11-27  7:12 ` rguenther at suse dot de
  2020-11-27  9:24 ` rsandifo at gcc dot gnu.org
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: rguenther at suse dot de @ 2020-11-27  7:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #15 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 27 Nov 2020, luoxhu at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326
> 
> --- Comment #14 from luoxhu at gcc dot gnu.org ---
> (In reply to luoxhu from comment #13)
> > 
> > 2)  mad2.c
> > 
> > float foo (double x, float y, float z)
> > {
> >    return ( y * fabs (x) + z ); 
> > }
> > 
> > 
> > mad2.c.098t.cunrolli:
> > 
> > foo (double x, float y, float z)
> > {
> >   double _1;
> >   double _2;
> >   double _3;
> >   double _4;
> >   double _5;
> >   float _9;
> > 
> >   <bb 2> [local count: 1073741824]:
> >   _1 = (double) y_6(D);
> >   _2 = ABS_EXPR <x_7(D)>;
> >   _3 = _1 * _2;
> >   _4 = (double) z_8(D);
> >   _5 = _3 + _4;
> >   _9 = (float) _5;
> >   return _9;
> > 
> > }
> > 
> 
> Maybe should use forward propagation here to save [_1, _2, _3 ... _9] to m_vars
> and set ignore_convert status in usage_info if rhs of the expression could
> remove double conversion, for stmt which has two rhs, need intersect status
> with AND operation of rhs1 ignore_convert and rhs2 ignore_convert, also clear
> the ignore_convert status if any of it is false.  Not sure whether this works,
> also a bit more complicated then expected...

I think backprop would need a way to "materialize" necessary converts
on select arms of expressions so that double + (double)float can
continue as "unneeded" on the arm to the float?  So basically you
do a optimistic back-propagation followed by a forward propagation
step cancelling optimistic assumptions that didn't work out.

Maybe it already works that way.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (11 preceding siblings ...)
  2020-11-27  7:12 ` rguenther at suse dot de
@ 2020-11-27  9:24 ` rsandifo at gcc dot gnu.org
  2020-11-30  8:31 ` luoxhu at gcc dot gnu.org
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: rsandifo at gcc dot gnu.org @ 2020-11-27  9:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #16 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> ---
> 2)  mad2.c
> 
> float foo (double x, float y, float z)
> {
>    return ( y * fabs (x) + z ); 
> }
> 
> 
> mad2.c.098t.cunrolli:
> 
> foo (double x, float y, float z)
> {
>   double _1;
>   double _2;
>   double _3;
>   double _4;
>   double _5;
>   float _9;
> 
>   <bb 2> [local count: 1073741824]:
>   _1 = (double) y_6(D);
>   _2 = ABS_EXPR <x_7(D)>;
>   _3 = _1 * _2;
>   _4 = (double) z_8(D);
>   _5 = _3 + _4;
>   _9 = (float) _5;
>   return _9;
> 
> }
> 
> mad2.c.099t.backprop:
> 
> [USE] _9 in return _9;
> [USE] _5 in _9 = (float) _5;
>   _5: convert from float to double not important
> [DEF] Recording new information for _5 = _3 + _4;
>   _5: convert from float to double not important
> [USE] _4 in _5 = _3 + _4;
>   _4: convert from float to double not important
> [DEF] Recording new information for _4 = (double) z_8(D);
>   _4: convert from float to double not important
> [USE] _3 in _5 = _3 + _4;
>   _3: convert from float to double not important
> [DEF] Recording new information for _3 = _1 * _2;
>   _3: convert from float to double not important
> [USE] _2 in _3 = _1 * _2;
>   _2: convert from float to double not important
> [DEF] Recording new information for _2 = ABS_EXPR <x_7(D)>;
>   _2: convert from float to double not important
> [USE] _1 in _3 = _1 * _2;
>   _1: convert from float to double not important
> [DEF] Recording new information for _1 = (double) y_6(D);
>   _1: convert from float to double not important
> 
> Deleting _4 = (double) z_8(D);
> Deleting _1 = (double) y_6(D);
> 
> 
> EMERGENCY DUMP:
> 
> __attribute__((noinline))
> foo (double x, float y, float z)
> {
>   double _2;
>   double _3;
>   double _5;
>   float _9;
> 
>   <bb 2> [local count: 1073741824]:
>   _2 = ABS_EXPR <x_7(D)>;
>   _3 = _2 * y_6(D);
>   _5 = _3 + z_8(D);
>   _9 = (float) _5;
>   return _9;
> 
> }
Maybe I'm misunderstanding the point, but isn't this
just an issue with the way that the results of the
analysis are applied to the IL, rather than a problem
in the analysis itself?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (12 preceding siblings ...)
  2020-11-27  9:24 ` rsandifo at gcc dot gnu.org
@ 2020-11-30  8:31 ` luoxhu at gcc dot gnu.org
  2020-12-11 13:49 ` segher at gcc dot gnu.org
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-11-30  8:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #17 from luoxhu at gcc dot gnu.org ---
(In reply to rsandifo@gcc.gnu.org from comment #16)
> > 2)  mad2.c
> > 
> > float foo (double x, float y, float z)
> > {
> >    return ( y * fabs (x) + z ); 
> > }
> > 
> > 
> > mad2.c.098t.cunrolli:
> > 
> > foo (double x, float y, float z)
> > {
> >   double _1;
> >   double _2;
> >   double _3;
> >   double _4;
> >   double _5;
> >   float _9;
> > 
> >   <bb 2> [local count: 1073741824]:
> >   _1 = (double) y_6(D);
> >   _2 = ABS_EXPR <x_7(D)>;
> >   _3 = _1 * _2;
> >   _4 = (double) z_8(D);
> >   _5 = _3 + _4;
> >   _9 = (float) _5;
> >   return _9;
> > 
> > }
> > 
> > mad2.c.099t.backprop:
> > 
> > [USE] _9 in return _9;
> > [USE] _5 in _9 = (float) _5;
> >   _5: convert from float to double not important
> > [DEF] Recording new information for _5 = _3 + _4;
> >   _5: convert from float to double not important
> > [USE] _4 in _5 = _3 + _4;
> >   _4: convert from float to double not important
> > [DEF] Recording new information for _4 = (double) z_8(D);
> >   _4: convert from float to double not important
> > [USE] _3 in _5 = _3 + _4;
> >   _3: convert from float to double not important
> > [DEF] Recording new information for _3 = _1 * _2;
> >   _3: convert from float to double not important
> > [USE] _2 in _3 = _1 * _2;
> >   _2: convert from float to double not important
> > [DEF] Recording new information for _2 = ABS_EXPR <x_7(D)>;
> >   _2: convert from float to double not important
> > [USE] _1 in _3 = _1 * _2;
> >   _1: convert from float to double not important
> > [DEF] Recording new information for _1 = (double) y_6(D);
> >   _1: convert from float to double not important
> > 
> > Deleting _4 = (double) z_8(D);
> > Deleting _1 = (double) y_6(D);
> > 
> > 
> > EMERGENCY DUMP:
> > 
> > __attribute__((noinline))
> > foo (double x, float y, float z)
> > {
> >   double _2;
> >   double _3;
> >   double _5;
> >   float _9;
> > 
> >   <bb 2> [local count: 1073741824]:
> >   _2 = ABS_EXPR <x_7(D)>;
> >   _3 = _2 * y_6(D);
> >   _5 = _3 + z_8(D);
> >   _9 = (float) _5;
> >   return _9;
> > 
> > }
> Maybe I'm misunderstanding the point, but isn't this
> just an issue with the way that the results of the
> analysis are applied to the IL, rather than a problem
> in the analysis itself?

Yes, the optimize operations on Gimple is a bit uncertain.
Do you mean add convert from double to float at proper place
like below to avoid ICE caused by type mismatch ICE in verify_ssa?
Which one will be better, and whether it is correct for all kind
of math operations like pow/exp, etc under fast-math?  If so, no
cancelling is needed again as Richi mentioned?

1) convert before ABS_EXPR:

foo (double x, float y, float z)
{
  float _9;
  float _11;
  float _12;
  float _13;
  float _14;

  <bb 2> [local count: 1073741824]:
  _11 = (float) x_6(D);
  _12 = ABS_EXPR <_11>;
  _13 = y_7(D) * _12;
  _14 = z_8(D) + _13;
  _9 = _14;
  return _9;

}

foo:
.LFB0:
        .cfi_startproc
        frsp 0,1
        fabs 0,0
        fmadds 1,2,0,3
        blr


2) OR convert after ABS_EXPR:

foo (double x, float y, float z)
{
  double _1;
  float _9;
  float _11;
  float _12;
  float _13;

  <bb 2> [local count: 1073741824]:
  _1 = ABS_EXPR <x_6(D)>;
  _11 = (float) _1;
  _12 = y_7(D) * _11;
  _13 = z_8(D) + _12;
  _9 = _13;
  return _9;

}

foo:
.LFB0:
        .cfi_startproc
        fabs 0,1
        frsp 0,0
        fmadds 1,2,0,3
        blr

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (13 preceding siblings ...)
  2020-11-30  8:31 ` luoxhu at gcc dot gnu.org
@ 2020-12-11 13:49 ` segher at gcc dot gnu.org
  2020-12-11 14:24 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: segher at gcc dot gnu.org @ 2020-12-11 13:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #18 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Why is it correct to convert the double x to single precision here?!

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (14 preceding siblings ...)
  2020-12-11 13:49 ` segher at gcc dot gnu.org
@ 2020-12-11 14:24 ` rguenth at gcc dot gnu.org
  2020-12-11 17:51 ` segher at gcc dot gnu.org
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 22+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-12-11 14:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #18)
> Why is it correct to convert the double x to single precision here?!

For

float foo(float f, float x, float y) {
return (fabs(f)*x+y);
}

it is not unless when using FMA intermediate _overflow_ is also "ignored"
(as opposed to just performing one rounding step and thus requiring one bit
more precision).

Note that the set of inputs where it is errorneous (producing +-Inf rather than
a finite number) is small and thus it might fall into the realms of
-funsafe-math-optimizations (even a 1 ulp change can make a big difference
when in the divisor for example).

These kind of FP "optimizations" are always tricky.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (15 preceding siblings ...)
  2020-12-11 14:24 ` rguenth at gcc dot gnu.org
@ 2020-12-11 17:51 ` segher at gcc dot gnu.org
  2020-12-11 19:24 ` rguenther at suse dot de
  2020-12-14  7:21 ` luoxhu at gcc dot gnu.org
  18 siblings, 0 replies; 22+ messages in thread
From: segher at gcc dot gnu.org @ 2020-12-11 17:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #20 from Segher Boessenkool <segher at gcc dot gnu.org> ---
Yes, that is clear...  But we have ***double*** x in that example even,
as the declared type of the parameter, so converting that to float is
almost certainly a bad idea?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (16 preceding siblings ...)
  2020-12-11 17:51 ` segher at gcc dot gnu.org
@ 2020-12-11 19:24 ` rguenther at suse dot de
  2020-12-14  7:21 ` luoxhu at gcc dot gnu.org
  18 siblings, 0 replies; 22+ messages in thread
From: rguenther at suse dot de @ 2020-12-11 19:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #21 from rguenther at suse dot de <rguenther at suse dot de> ---
On December 11, 2020 6:51:05 PM GMT+01:00, "segher at gcc dot gnu.org"
<gcc-bugzilla@gcc.gnu.org> wrote:
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326
>
>--- Comment #20 from Segher Boessenkool <segher at gcc dot gnu.org> ---
>Yes, that is clear...  But we have ***double*** x in that example even,
>as the declared type of the parameter, so converting that to float is
>almost certainly a bad idea?

OH... Most definitely.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
                   ` (17 preceding siblings ...)
  2020-12-11 19:24 ` rguenther at suse dot de
@ 2020-12-14  7:21 ` luoxhu at gcc dot gnu.org
  18 siblings, 0 replies; 22+ messages in thread
From: luoxhu at gcc dot gnu.org @ 2020-12-14  7:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326

--- Comment #22 from luoxhu at gcc dot gnu.org ---
https://gcc.gnu.org/pipermail/gcc/2020-December/234474.html

So this issue seems invalid since "fabs(x)*y+z” or "fabs(x)+y+z"(x,y,z are
float) could result in -+Inf sometimes, while it won't getting float overflow
under double computation.  Float value range info is required here.



Quoto Richard's reply:

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.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-6528@http.gcc.gnu.org/bugzilla/>
  2006-08-21  6:08 ` pinskia at gcc dot gnu dot org
@ 2007-07-09  6:08 ` pinskia at gcc dot gnu dot org
  1 sibling, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-07-09  6:08 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from pinskia at gcc dot gnu dot org  2007-07-09 06:08 -------
Related to PR 32685.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
OtherBugsDependingO|                            |32685
              nThis|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
       [not found] <bug-22326-6528@http.gcc.gnu.org/bugzilla/>
@ 2006-08-21  6:08 ` pinskia at gcc dot gnu dot org
  2007-07-09  6:08 ` pinskia at gcc dot gnu dot org
  1 sibling, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2006-08-21  6:08 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from pinskia at gcc dot gnu dot org  2006-08-21 06:08 -------
I think to fix this one, we need a real pass to remove the promotions.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to
  2005-07-06 15:40 [Bug tree-optimization/22326] New: " pinskia at gcc dot gnu dot org
@ 2005-07-12 20:37 ` pinskia at gcc dot gnu dot org
  0 siblings, 0 replies; 22+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-07-12 20:37 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-07-12 20:26 -------
Confirmed.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
   Last reconfirmed|0000-00-00 00:00:00         |2005-07-12 20:26:50
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22326


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2020-12-14  7:21 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <bug-22326-4@http.gcc.gnu.org/bugzilla/>
2020-11-17  7:07 ` [Bug tree-optimization/22326] promotions (from float to double) are not removed when they should be able to luoxhu at gcc dot gnu.org
2020-11-17  7:10 ` luoxhu at gcc dot gnu.org
2020-11-17 10:21 ` pinskia at gcc dot gnu.org
2020-11-17 21:56 ` joseph at codesourcery dot com
2020-11-18 15:22 ` segher at gcc dot gnu.org
2020-11-23  8:39 ` luoxhu at gcc dot gnu.org
2020-11-23  8:44 ` luoxhu at gcc dot gnu.org
2020-11-23 12:09 ` rguenther at suse dot de
2020-11-24 10:00 ` rsandifo at gcc dot gnu.org
2020-11-27  6:20 ` luoxhu at gcc dot gnu.org
2020-11-27  6:27 ` luoxhu at gcc dot gnu.org
2020-11-27  7:12 ` rguenther at suse dot de
2020-11-27  9:24 ` rsandifo at gcc dot gnu.org
2020-11-30  8:31 ` luoxhu at gcc dot gnu.org
2020-12-11 13:49 ` segher at gcc dot gnu.org
2020-12-11 14:24 ` rguenth at gcc dot gnu.org
2020-12-11 17:51 ` segher at gcc dot gnu.org
2020-12-11 19:24 ` rguenther at suse dot de
2020-12-14  7:21 ` luoxhu at gcc dot gnu.org
     [not found] <bug-22326-6528@http.gcc.gnu.org/bugzilla/>
2006-08-21  6:08 ` pinskia at gcc dot gnu dot org
2007-07-09  6:08 ` pinskia at gcc dot gnu dot org
2005-07-06 15:40 [Bug tree-optimization/22326] New: " pinskia at gcc dot gnu dot org
2005-07-12 20:37 ` [Bug tree-optimization/22326] " pinskia at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).