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

--- Comment #18 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 21 Feb 2020, bugdal at aerifal dot cx wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806
> 
> --- Comment #12 from Rich Felker <bugdal at aerifal dot cx> ---
> To me the meaning of internal consistency is very clear: that the semantics of
> the C language specification are honored and that the only valid
> transformations are those that follow the "as-if rule". Since C without Annex 
> F
> allows arbitrarily awful floating point results, your example in comment 11 is
> fine. Each instance of 1/a can evaluate to a different value. They could even
> evaluate to random values. However, if you had written:
> 
>   int b = 1/a == 1/0.;
>   int c = b;
>   return b == c;
> 
> then the function must necessarily return 1, because the single instance of
> 1/a==1/0. in the abstract machine has a single value, either 0 or 1, and in 
> the
> abstract machine that value is stored to b, then copied to c, and b and c
> necessarily have the same value. While I don't think it's likely that GCC 
> would
> mess up this specific example, it seems that it currently _can_ make
> transformations such that a more elaborate version of the same idea would be
> broken.

GCC indeed happily evaluates a floating-point expression multiple times,
for example for

void foo(float a, float b, float *x, float *y)
{
  float tem = a + b;
  *x = tem - a;
  *y = tem - b;
}

I would expect GCC to turn this into

  *x = (a + b) - a;
  *y = (a + b) - b;

and then simplify further to b and a.  Does this violate the "as-if rule"?
It certainly affects the result when a + b == a.

Note the fortran frontend uses the PAREN_EXPR which is an association
barrier to prevent optimizations across boundaries the language
standard places (parens IIRC).  That still doesn't prevent GCC from
evaluating a single expression multiple times and possibly
doing different association inside the expression - so it still
violates the as-if rule.  Classical transforms involve tail-duplication
of blocks but also loop unrolling if we happen to duplicate loop
invariant expressions.

So I guess the "as-if rule" can practically not be honored by an
optimized compiler.

Reply via email to