On Sunday, 30 June 2024 08:33:35 GMT+2 Martin Uecker wrote: > Am Sonntag, dem 30.06.2024 um 05:03 +0200 schrieb Matthias Kretz: > > On Saturday, 29 June 2024 16:20:55 GMT+2 Martin Uecker wrote: > > > Am Samstag, dem 29.06.2024 um 08:50 -0500 schrieb Matthias Kretz via Gcc: > > > > I.e. once UB becomes IFNDR, the dreaded time-travel optimizations > > > > can't > > > > happen anymore. Instead precondition checks bubble up because > > > > otherwise > > > > the program is ill-formed. > > > > > > It is not clear to mean what you mean by this? > > > > It would help if you could point out what is unclear to you. I assume you > > know IFNDR? And I gave an example for the "bubbling up" of precondition > > checks directly above your quoted paragraph. > > I think I understood it now: You want to make UB be IFNDR so > that the compiler is allowed to diagnose it at translation > time in certain cases (although this would not generally be > required for IFNDR).
Right, diagnosis of the error depends on const-prop and thus on compiler abilities and compiler flags. Which is why I'm asking for IFNDR on UB. > > > Note that in C time-travel optimizations are already not allowed. > > > > Then, calling __builtin_unreachable is non-conforming for C? ... at least > > in the English sense of "this code is impossible to reach", which implies > > that the condition leading up to it must be 'false', allowing time-travel > > optimization. Or how would C define 'unreachable'? > > __builtin_uneachable is an extension, it can do whatever it wants. Sure. But it's nice ;) if the behavior of a function/builtin is reflected by its name (or the other way around). > But note that compilers do not seem to eliminate the control flow path > leading to it: > > https://godbolt.org/z/coq9Yra1j It seems like GCC and Clang consider function calls and volatile stores to have side effects that could potentially make the __builtin_unreachable unreachable :) If you drop the 'volatile' like in int i = 0; int g(int x) { if (x) { i = 1; __builtin_unreachable(); } return i; } ... then the store to i is elided. > So even if it is defined in terms of C's UB, these implementations > would still be conforming to C. > > > > But I am not sure how this is relevant here as this affects only > > > observable behavior and the only case where GCC does not seem to > > > already conform to this is volatile. > > > > Now you lost me. > > Consider the following example: > > int f(int x) > { > int r = 0; > if (x < 10) > r = 1; > if (x < 10) > __builtin_unreachable(); > return r; > } > > But removing the store to 'r' here as GCC does: > > https://godbolt.org/z/h7qqrGsbz > > can simply be justified by the "as if" principle as > any other optimization, it does not need to rely on a weird > intepretation that the UB from __builin_unreachable() travels > back in time. I don't know of anybody saying that "time-travel optimization" refers to anything different than what you're showing here. The part that people find scary is when this "as if" happens at a distance, like in https://godbolt.org/z/jP4x1c3E6 > > > Of course, C++ may be different but I suspect that some of the > > > discussion is confusing compiler bugs with time-travel: > > "some of the discussion" is referring to what? > > To discussions inside WG21 that seems to believe that it > is important that compilers can do time-travel optimizations, > when this is actually not the case. In light of the above clarification (what we mean with "time-travel optimization"), this is simply about allowing inlining and as-if transformations. Therefore, yes, it is important. > > [...] > > I think it is a good idea. The compiler can optionally treat UB as > a translation time error. We discussed similar ideas in the past > in WG14. But this will only work for very specific instances of UB > under certain conditions. Yes. But it's an exact match of the "time-travel" cases. I.e. whenever const- prop determines "unreachable" the code could be ill-formed. > > > Also IMHO this should be split up from > > > UBsan which has specific semantics and upstream dependencies > > > which are are not always ideal. (But UBSan could share the > > > same infrastructure) > > > > I'm not sure what you're thinking of here. UBsan detects UB at runtime > > whereas my '-fharden=1' proposal is about flagging UB as ill-formed on > > compile-time. So UBsan is a more verbose '-fharden=2' then? > > Yes, I was talking about the -fharden=2 case. In principle UBSan > with traps instead of diagnostics would do this. In practice, > I think we need something which is not tied to UBSan. Yes, basically a deployable variant of UBsan? On Sunday, 30 June 2024 08:56:41 GMT+2 Martin Uecker wrote: > 0) nothing > 1) expands to __builtin_unreachable() > 2) expands to __builtin_trap() > 3) expands to a __builtin_warning (as suggested before > by Martin Sebor) that causes the backend to emit an error > in a very late pass when the __builtin_warning has not > been removed during optimization. This __builtin_warning seems to be equivalent to my __error() function, using a [[gnu::warning]] attribute instead of [[gnu::error]]. Which is certainly another viable build/-fharden/whateverwecallit mode. - Matthias -- ────────────────────────────────────────────────────────────────────────── Dr. Matthias Kretz https://mattkretz.github.io GSI Helmholtz Center for Heavy Ion Research https://gsi.de std::simd ──────────────────────────────────────────────────────────────────────────
signature.asc
Description: This is a digitally signed message part.