On Fri, Sep 05, 2025 at 08:35:43AM +0200, Richard Biener wrote:
> > i.e. keep it as a call to an optimization barrier until runtime
> > but don't really do anything at that point.
> 
> That's probably equivalent to the builtin.

But to a builtin which is preserved until end of expansion (not sure
in what form, we can easily have just inline asm for optimization
barriers in RTL, or perhaps emit a CALL_INSN and somehow optimize
it away during final.
The reason to use inline function was just not to commit to it
as ABI for now, of course we could just also export a dummy
nop function from libstdc++.so and just use some attributes on it.

> I'll note that both are
> less strong of a barrier than setjmp() or longjmp() which we
> arrange to have abnormal incoming/outgoing edges so even
> register computations cannot be moved across them.  So
> for extra barrier-ness you want to add returns_twice.

Guess that depends on what exact side-effects we are fighting against.
The paper in short says that UB which happens after calling these
functions should not modify program behavior before these calls.
I'd say we need to treat like that any external function we don't
know anything about (e.g. because the function can possibly exit (0)
or call this std::observable_checkpoint () function).
So I think anything that acts as a (or possible) call to external unknown
function (at least until final, doesn't have to be assembled as a call
but unsure if we can assemble it on all targets as nothing) should have
the right behavior.  E.g. if we have
[[gnu::const]] int bar ();
void baz ();
void
foo (int *p)
{
  int a = 42;
  if (p == nullptr)
    a = bar ();
  baz ();
  *p = a;
}
we can't really optimize away the p == nullptr check because the baz ()
function could call exit (0).

        Jakub

Reply via email to