On Mon, Sep 8, 2025 at 2:22 PM Iain Sandoe <i...@sandoe.co.uk> wrote: > > > > > On 8 Sep 2025, at 12:46, Richard Biener <richard.guent...@gmail.com> wrote: > > > > On Mon, Sep 8, 2025 at 1:04 PM Ville Voutilainen > > <ville.voutilai...@gmail.com> wrote: > >> > >> On Mon, 8 Sept 2025 at 13:54, Richard Biener <richard.guent...@gmail.com> > >> wrote: > >>> That said, I see no point in std::observable_checkpoint to be represented > >>> in the IL at all if all it is is to cater to FUD around what compilers > >>> might > >>> think is a correct transform? > >> > >> It's not just to cater to FUD. I have seen Clang remove a complete CFG > >> edge that lead to a non-return from > >> a non-void function. If observable_checkpoint works correctly, the > >> debug prints my junior colleague added trying > >> to see how the execution flows would've worked when used with the > >> checkpoint, whereas clang happily > >> removed them along with everything else on that CFG edge proven to > >> lead to UB. I am unable to find > >> any specification rationale that would make such a transformation > >> incorrect, and with observable_checkpoint, > >> that situation changes. > > > > So the situation is sth like > > > > int foo () > > { > > printf ("what?"); > > } > > > > that was optimized away completely by clang and you want to fix that with > > > > int foo () > > { > > printf ("what?"); > > std::observable_checkpoint (); > > } > > > > ? But this is again a clang bug. printf could call > > std::observable_checkpoint () itself, no? > > Even if clang can conclude that printf("what?") always will return > > normally there's a > > side-effect to be preserved (printing 'what?'). > > > > If this isn't the actual testcase, can you share it? I do not see > > clang (version 19) > > optimizing away the printf in the above testcase. > > I also do not think it is all FUD - although clang is/was more likely > to exhibit it. In the discussions there have been many proposed > cases in which a problem could occur - most of them are hard > to reproduce (even if the compiler might technically do the thing > in practice GCC does not). > > —— however... > > For the testcase attached to the patch. > > Do we consider that the addition to x is considered observable? > - because it is now extern and therefore can be seen by some > other TU,
We consider the addition to be observable, but it's not a "side-effect", aka there's no "synchronous observation point", and thus we can elide it. I think the point about the other TU is moot, since no other thread can rely on being scheduled after the increment but before the UB happens (likewise we don't consider asynchronous events of any kind). If you add a thread synchronization primitive this would have the same effect as the possible implementations of the std:: function we discussed. If you make it poor-mans "threadsafe" aka volatile it should be preserved as well. That's why I asked what the standard library wants to guarantee. For the increment to 'x' to be preserved there needs to be a user of 'x' in the IL that is a "synchronous observation point". > Then is it a bug in GCC that we elide that increment when it is > followed by UB? I don't necessarily think so. But do we? > === > > we can also have things like > > char *p = something; > if (p == nullptr) > { > __builtin_printf (“bad pointer\n”); > __builtin_abort (); > } > > …. > some UB…. > > which gets reduced to an unconditional print and abort. "things like" ... int foo (int i) { if (i == 0) __builtin_abort (); } is reduced to __builtin_abort () (for C++). That's because it's __builtin_unreachable () at the end. I am not aware of any other "UB" than missed return that we turn into unreachable(), even unsigned int foo (unsigned int i) { if (i < 33) __builtin_abort (); return i << i; } isn't handled this way. But sure we could, in the future. std::... before the return would help in case it is considered a barrier that might not continue to the UB. Richard. > (I agree that this is allowed, but it is unexpected to many users) > that kind of check can also be guarded. > > Iain > > > > Thanks, > > Richard. >