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

--- Comment #25 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Alexander Cherepanov from comment #24)
> (In reply to Vincent Lefèvre from comment #11)
> > But what does "internal consistency" mean?
> That's a good question. Here we talk about cases (like
> -funsafe-math-optimizations) that are not covered by any standards. Other
> PRs (like pr61502 or pr93301) discuss possible changes to the standard. So
> we need some basic rules to decide what is good and what is bad.
> 
> pr61502 taught me that discussing which value is the right result for a
> particular computation is very interesting but not very conclusive. So now
> I'm looking for contradictions. If you can derive a contradiction then you
> can derive any statement, so it's an ultimate goal. How to apply this to a
> compiler? I thought the following is supposed to always hold: if you
> explicitly write a value into a variable (of any type) then you should get
> back the same value at every future read no matter how the results of other
> reads are used or what control flow happens (without other writes to the
> variable, of course). That is, after `int x = 0;` all `printf("x = %d", x);`
> should output the same no matter how many `if (x == ...)` there are
> in-between -- either `printf` doesn't fire at all or it prints `x = 0`. If
> we demonstrated that it's broken then we demonstrated a contradiction
> (nonsense). And I hoped that it would be uncontroversial:-(

It's at least a very easy to describe and obviously useful thing.  I also
agree it's a very good QOI goal to target.

Just to clarify - this is for a single execution of the abstract machine,
not for the single "source" instance when the same two values are involved?
So

float foo(float x) { return x + 1; }
void bar()
{
  float f1 = foo(1.);
  float f2 = foo(1.);
}

here x + 1 need not evaluate to the same value?  This would make transforms
such as loop unrolling or tail duplication "safe" since those do not involve
evaluating the same expression more times than in the untransformed abstract
machine evaluations.

[...]

> (In reply to Richard Biener from comment #3)
> > But you asked for that.  So no "wrong-code" here, just another case
> > of "instabilities" or how you call that via conditional equivalence
> > propagation.
> Just to be sure: you are saying that everything works as intended -- the
> testcase doesn't contain UB and the result it prints is one of the allowed?
> (It could also be read as implying that this pr is a dup of another bug
> about conditional equivalence propagation or something.) Then we just
> disagree.

I think that -funsafe-optimization makes the result acceptable.  I see
(and somewhat agree) that this is unfortunate for the QOI design goal
of "stable" values.

But the instability is just a result of optimizers working as intended.
There is no designed mechanism in GCC that avoids "opening up" an expression
and recomputing (parts of) it [in different contexts differently].  And
I have a hard time coming up with a way to implement such a thing that
wouldn't be detrimental to desired optimizations :/

As we see in other testcases "conditional equivalences" and replacing
one variable with another under them is a source of various problems,
but simply disabling those propagations likely will not address the
fundamental issue.

> Discussion went to specifics of particular optimizations. IMHO it's not
> important at all for deciding whether comment 1 demonstrates a bug or not.
> Again, IMHO either the testcase contains UB or it shouldn't print nonsense
> (in the sense described above). And it doesn't matter which options are
> used, whether it's a standards compliant mode, etc.

Overall I'm not sure how to address these bugs (but thanks for raising
awareness and for creating those testcases!).  It's tempting to paper over
the individual issues (like not allow conditional propagation of FP values
or disabling forwarding of once computed, many used FP conditionals) but
I think there's a more fundametal issue around all this which is not
fully understood and which we should try to address in a more coordinated
fashion (also given "artificial" wrong-code testcases don't put a very high
pressure on finding a workaround for them).

Just compare to the very old issue regarding the lack of barriers of FP
arithmetic with FP environment access.

Would it help if we had some --param no-conditional-propagation to turn
off such propagation in the two places I'm aware we do it?  That way
you could see if you can find testcases not involving such propagation
(I think it's most easy to get them there though).

Reply via email to