https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93301
--- Comment #9 from rguenther at suse dot de <rguenther at suse dot de> --- On Sun, 26 Jan 2020, ch3root at openwall dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93301 > > --- Comment #4 from Alexander Cherepanov <ch3root at openwall dot com> --- > (In reply to Richard Biener from comment #1) > > guess DOM would also happily propagate equivalences > > Yeah, this gives a simpler testcase: > > ---------------------------------------------------------------------- > #include <stdio.h> > > __attribute__((noipa)) // imagine it in a separate TU > static int opaque(int i) { return i; } > > int main() > { > unsigned char x = opaque(1); > unsigned char y; > (void)&y; > > if (x - 1 == y) { > printf("x = %d; x - 1 = %d\n", x, opaque(1) ? x - 1 : 5); > opaque(y); > } > } > ---------------------------------------------------------------------- > $ gcc -std=c11 test.c && ./a.out > x = 1; x - 1 = 0 > $ gcc -std=c11 -O3 test.c && ./a.out > x = 1; x - 1 = 5 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). 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?). If it is supposed to make y allocated to memory then I have to say it doesn't (but yeah, allocating it to memory would make it's value somewhat stable until we start optimizing loads from uninitialized memory to a random uninitialized register...). That said, the stmt doesn't have any persistent effect on GCCs IL (it's eliminated quickly as not needed).