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.