IFNDR on UB? [was: Straw poll on shifts with out of range operands]
Matthias Kretz
m.kretz@gsi.de
Mon Jul 1 13:19:27 GMT 2024
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
──────────────────────────────────────────────────────────────────────────
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part.
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20240701/7767fc3d/attachment.sig>
More information about the Libstdc++
mailing list