This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/81008] New: missing optimization for restricted pointers passed to functions
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 07 Jun 2017 19:54:47 +0000
- Subject: [Bug tree-optimization/81008] New: missing optimization for restricted pointers passed to functions
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81008
Bug ID: 81008
Summary: missing optimization for restricted pointers passed to
functions
Product: gcc
Version: 7.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: ---
While exploring ways to annotate C++ classes or member functions to indicate
that accessing an object of the class does not change a different object of
that class I noticed that GCC doesn't take full advantage of the basic
guarantee on restrict-qualified pointers: that if one is used to access an
object, the same object may only be modified through an [lvalue] based on the
same pointer.
In the example below, the call to foo() is guaranteed not to modify the object
at *p because p is a restricted pointer and there is no other pointer based on
p can exist.
Clang emits optimal code for the test case (i.e., just a jump to foo()).
$ cat t.c && gcc -O3 -S -Wall -Wrestrict -fdump-tree-optimized=/dev/stdout t.c
void f (void);
void g (int* restrict p)
{
int x = *p;
f ();
if (x != *p)
__builtin_abort ();
}
;; Function g (g, funcdef_no=0, decl_uid=1795, cgraph_uid=0, symbol_order=0)
g (int * restrict p)
{
int x;
int _1;
<bb 2> [100.00%]:
x_4 = *p_3(D);
f ();
_1 = *p_3(D);
if (_1 != x_4)
goto <bb 3>; [0.04%]
else
goto <bb 4>; [99.96%]
<bb 3> [0.04%]:
__builtin_abort ();
<bb 4> [99.96%]:
return;
}
In the above, the only way f() could modify *p is like so:
int *q;
void f (void) { *q = 0; }
and
void h (void)
{
int d = 0;
q = &d;
g (&d);
}
but such a modification is undefined thanks to the access to d in f() through a
restricted pointer.