https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502
--- Comment #44 from rguenther at suse dot de <rguenther at suse dot de> --- On Mon, 20 Jan 2020, ch3root at openwall dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502 > > --- Comment #43 from Alexander Cherepanov <ch3root at openwall dot com> --- > The following example demonstrates that the instability taints the surrounding > code even if it's in dead code itself. In particular, this shows that even > making comparisons like `&x + 1 == &y` undefined will not help. > > ---------------------------------------------------------------------- > #include <stdlib.h> > #include <stdio.h> > > __attribute__((noipa)) // imagine it in a separate TU > static void *opaque(void *p) { return p; } > > __attribute__((noipa)) // imagine it in a separate TU > static void g(int a) > { > printf("%d\n", a); > exit(0); > } > > static void f(int c, void *p, void *q, void *r) > { > while (c) { > g(p == r); > > if (p != q && q == r) > puts("unreachable"); > } > } > > int main(int c, char **v) > { > (void)v; > > int x[5]; > int y[2]; > > void *p = &x; > void *q = &y + 1; > > opaque(q); // escaped > void *r = opaque(p); // hide the provenance of p > > f(c, p, q, r); > } > ---------------------------------------------------------------------- > $ gcc -std=c11 -pedantic -Wall -Wextra test.c && ./a.out > 1 > $ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out > 0 > ---------------------------------------------------------------------- > gcc x86-64 version: gcc (GCC) 10.0.1 20200120 (experimental) > ---------------------------------------------------------------------- Not sure what it proves but here the loop unswitching pass decides to unswitch on c != 0 and &y + 1 == r (aka q == r). That in itself doesn't look wrong but I guess it's (again) the conditional equivalence that somehow breaks things.