https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93301
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 28 Jan 2020, ch3root at openwall dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93301 > > --- Comment #12 from Alexander Cherepanov <ch3root at openwall dot com> --- > (In reply to rguent...@suse.de from comment #9) > > This example simply shows that we're propagating the equivalence > > y == x - 1 in the way that the controlled x - 1 becomes y (that's > > possibly a QOI issue in this particular case where we _do_ see > > that y is not initialized - but as said in general we cannot know) > > and that we then optimize condition ? uninit : 5 as 5 (we're > > optimistically treating uninit equal to 5 here which is OK). > > Right, nothing new here, just a simpler example. (Building something upon my > first example was not fun. This one proved to be much nicer.) > > > Note the (void)&y doesn't do anything but it really looks like > > it is required to make the testcase conforming (otherwise you > > wouldn't use it?). > > This is just a ritual dance dedicated to Itanium. C11, 6.3.2.1p2, has the > following text added for DR 338[1]: > > "If the lvalue designates an object of automatic storage duration that could > have been declared with the register storage class (never had its address > taken), and that object is uninitialized (not declared with an initializer and > no assignment to it has been performed prior to use), the behavior is > undefined." OK, so the (void)&y doesn't prevent GCC from allocating y to a register. Of course the wording above requires declaration with "register" which would make writing &y invalid. > OTOH maybe it's worth to spent a minute on this DR given we are discussing > speculative execution. [2] has a nice explanation of the topic. IIUC you can > try to hoist a dereference of a pointer from a loop -- you will just get a NaT > (Not-a-Thing) value in a register instead of a crash if the pointer is bad. > But > if your speculatively executed hoisted code have to write to memory a value > from a register that corresponds to an uninitialized variable and this > register > contains a NaT, you get your crash back:-) > > According to [3] the whole thing is to be EOLed the next year, so not sure how > relevant this is. Trap representations are still relevant (sNaN exists on most IEEE conforming architectures), and most of your testcases would also translate to floating-point entities (with more careful handling of "equality").