[Bug tree-optimization/81786] New: local restricted pointer can be relied on in alias analysis
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Aug 9 20:26:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81786
Bug ID: 81786
Summary: local restricted pointer can be relied on in alias
analysis
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
I've been looking for opportunities to improve code generation by relying on
explicit guarantees about aliasing properties that commonly hold but that GCC
cannot otherwise rely on due to the lack of contextual information. For
instance, it's common for a function that takes a non-const pointer argument
(say Q) to modify the object it points to (say X), then call some other
function (say FOO), and then read X's value again via *Q. Unless GCC knows the
semantics of FOO it must assume that every call to it changes the value of X,
even though it's quite rare in practice for that to happen. It would be nice
to be able to express this guarantee to GCC to let it generate more efficient
code.
As it turns out, according to the C aliasing rules, locally declaring a
restrict-qualified pointer P as a copy of an unknown pointer Q (such as a
function argument) can be used to express the guarantee that the object X the
pointers point to isn't modified during P's lifetime. (This is 6.7.3.1, p4.)
So with this simple notation, GCC could rely on this guarantee to optimize the
program below as indicated in the comments. Note that neither functions need
to make use of the restrict qualifier in its interface. This is helpful
because relatively few functions do.
$ cat x.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout x.c
void foo (void);
void bar (int *q)
{
int* restrict p = q;
*p = 123;
foo (); // must not modify *P
if (*p != 123) // cannot be true
__builtin_abort (); // can be eliminated
}
int x;
void baz (void)
{
x = 789;
bar (&x);
}
;; Function bar (bar, funcdef_no=0, decl_uid=1817, cgraph_uid=0,
symbol_order=0)
bar (int * q)
{
int _1;
<bb 2> [100.00%] [count: INV]:
*q_2(D) = 123;
foo ();
_1 = *q_2(D);
if (_1 != 123)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
return;
}
;; Function baz (baz, funcdef_no=1, decl_uid=1822, cgraph_uid=1,
symbol_order=2)
baz ()
{
int _2;
<bb 2> [100.00%] [count: INV]:
x = 123;
foo ();
_2 = x;
if (_2 != 123)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
return;
}
More information about the Gcc-bugs
mailing list