https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92963
Bug ID: 92963 Summary: Optimization with `restrict`: is `p == q ? p : q` "based" on `p`? Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ch3root at openwall dot com Target Milestone: --- The question: is `p == q ? p : q` "based" on `p` (as in C11, 6.7.3.1p3)? First, suppose that the answer is "yes". Then the following program should be strictly conforming and should always print "2": ---------------------------------------------------------------------- #include <stdio.h> __attribute__((__noinline__)) // imagine it in a separate TU static int f(int *restrict p, int *restrict q) { *p = 1; int *r; if (p == q) r = p; else r = q; // is r "based" on p? *r = 2; return *p; } int main() { int x; printf("%d\n", f(&x, &x)); } ---------------------------------------------------------------------- $ gcc -std=c11 test.c && ./a.out 2 $ gcc -std=c11 -O3 test.c && ./a.out 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.0 20191216 (experimental) ---------------------------------------------------------------------- Ok, fair enough, `p == q ? p : q` is always equal to `q`, doesn't change when `p` changes and, thus, is not "based" on `p`. Then the following program (3 differences are marked) should be fine according to the standard and should always print "2": ---------------------------------------------------------------------- #include <stdio.h> __attribute__((__noinline__)) // imagine it in a separate TU static int f(int *restrict p, int *restrict q) { *q = 1; // 1) changed p -> q int *r; if (p == q) r = p; else r = q; // is r "based" on p? if (p == q) // 2) added if *r = 2; return *q; // 3) changed p -> q } int main() { int x; printf("%d\n", f(&x, &x)); } ---------------------------------------------------------------------- $ gcc -std=c11 test.c && ./a.out 2 $ gcc -std=c11 -O3 test.c && ./a.out 1 ---------------------------------------------------------------------- Either way, there is a problem...