This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/43907] yet another missed restrict optimization



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]