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.

Reply via email to