------- Comment #3 from rguenth at gcc dot gnu dot org 2010-04-27 10:33 ------- (In reply to comment #2) > > restrict only disambiguates against other restrict pointers. > Can you please support that assertion with a reference? > > ISO/IEC 9899:TC2 Committee Draft May 6, 2005, 6.7.3 paragraph 7 > > An object that is accessed through a restrict-qualified > > pointer has a special association with that pointer. > > This association, defined in 6.7.3.1 below, requires > > that all accesses to that object use, directly or > > indirectly, the value of that particular pointer) > > The intended use of the restrict qualifier (like the > > register storage class) is to promote optimization, > > and deleting all instances of the qualifier from all > > preprocessing translation units composing a conforming > > program does not change its meaning (i.e., observable > > behavior). > > As far as I understand that paragraph it says nothing about _other_ restrict > pointers. > It plainly says that any access to the memory which "b" points to will be made > using "b" or its derivatives. And since "b" points to "const int" that memory > can not be modified inside the "f" procedure.
const qualification is arbitrary and does not impose any semantic restrictions on the program. The following is valid: int f(int *a, const int *b) { *a = 0; return *b; } int main() { int x = 1; if (f (&x, &x) != 0) abort (); } the const qualification only restricts the use of the pointer, it doesn't say anything about the pointed-to object. (In fact you can cast away the const qualifier and store through the pointer - the program is only undefined at runtime if the pointed-to object was declared const). > Since I wasn't sure I first asked that question in gcc-help mailing list [1]. > Ian Lance Taylor [2] and Manuel López-Ibáñez [3] agreed that it > is a missed optimization. > > [1] http://gcc.gnu.org/ml/gcc-help/2010-04/msg00233.html > [2] http://gcc.gnu.org/ml/gcc-help/2010-04/msg00250.html > [3] http://gcc.gnu.org/ml/gcc-help/2010-04/msg00256.html Well, that is certainly not what is implemented and I am not sure that doing so (even if one could maybe read that into the formal definition when one considers not the examples in 6.7.3.1) wouldn't break existing programs. Note that it is not possible to implement the lexical block restrictions in 6.7.3.1 and thus one has to cope with more complex situations after inlining. The following patch would fix your testcase: Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 158770) +++ gcc/tree-ssa-alias.c (working copy) @@ -284,9 +284,14 @@ ptr_derefs_may_alias_p (tree ptr1, tree /* If both pointers are restrict-qualified try to disambiguate with restrict information. */ if (TYPE_RESTRICT (TREE_TYPE (ptr1)) - && TYPE_RESTRICT (TREE_TYPE (ptr2)) - && !pt_solutions_same_restrict_base (&pi1->pt, &pi2->pt)) - return false; + || TYPE_RESTRICT (TREE_TYPE (ptr2))) + { + if (!pi1->pt.vars && !pi2->pt.vars) + return true; + if (!pi1->pt.vars || !pi2->pt.vars) + return false; + return bitmap_intersect_p (pi1->pt.vars, pi2->pt.vars); + } /* ??? This does not use TBAA to prune decls from the intersection that not both pointers may access. */ I am not sure though that this is what is intended (the current implementation is based on previous consensus). You probably also suggest that int i; int f (int * restrict p) { int x = *p; i++; x += *p return x; } shall load from *p only once? -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |UNCONFIRMED Component|rtl-optimization |middle-end Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43907