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...