It was noted that we now simplify pointer equality tests against
restrict qualified pointers which we can't do according to
reading of the fine-prints in the C standard done by Joseph.

Fixed as follows.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2016-05-12  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/71062
        * tree-ssa-alias.h (struct pt_solution): Add vars_contains_restrict
        field.
        * tree-ssa-structalias.c (set_uids_in_ptset): Set vars_contains_restrict
        if the var is a restrict tag.
        * tree-ssa-alias.c (ptrs_compare_unequal): If vars_contains_restrict
        do not disambiguate pointers against it.
        (dump_points_to_solution): Re-structure and adjust for new
        vars_contains_restrict flag.
        * gimple-pretty-print.c (pp_points_to_solution): Likewise.

        * gcc.dg/torture/pr71062.c: New testcase.

Index: gcc/tree-ssa-alias.h
===================================================================
*** gcc/tree-ssa-alias.h        (revision 236159)
--- gcc/tree-ssa-alias.h        (working copy)
*************** struct GTY(()) pt_solution
*** 47,53 ****
       includes memory at address NULL.  */
    unsigned int null : 1;
  
- 
    /* Nonzero if the vars bitmap includes a variable included in 'nonlocal'.  
*/
    unsigned int vars_contains_nonlocal : 1;
    /* Nonzero if the vars bitmap includes a variable included in 'escaped'.  */
--- 47,52 ----
*************** struct GTY(()) pt_solution
*** 55,60 ****
--- 54,62 ----
    /* Nonzero if the vars bitmap includes a anonymous heap variable that
       escaped the function and thus became global.  */
    unsigned int vars_contains_escaped_heap : 1;
+   /* Nonzero if the vars bitmap includes a anonymous variable used to
+      represent storage pointed to by a restrict qualified pointer.  */
+   unsigned int vars_contains_restrict : 1;
  
    /* Set of variables that this pointer may point to.  */
    bitmap vars;
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c        (revision 236159)
--- gcc/tree-ssa-alias.c        (working copy)
*************** ptrs_compare_unequal (tree ptr1, tree pt
*** 363,376 ****
    else if (obj1 && TREE_CODE (ptr2) == SSA_NAME)
      {
        struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr2);
!       if (!pi)
        return false;
        return !pt_solution_includes (&pi->pt, obj1);
      }
    else if (TREE_CODE (ptr1) == SSA_NAME && obj2)
      {
        struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr1);
!       if (!pi)
        return false;
        return !pt_solution_includes (&pi->pt, obj2);
      }
--- 363,379 ----
    else if (obj1 && TREE_CODE (ptr2) == SSA_NAME)
      {
        struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr2);
!       /* We may not use restrict to optimize pointer comparisons.
!          See PR71062.  So we have to assume that restrict-pointed-to
!        may be in fact obj1.  */
!       if (!pi || pi->pt.vars_contains_restrict)
        return false;
        return !pt_solution_includes (&pi->pt, obj1);
      }
    else if (TREE_CODE (ptr1) == SSA_NAME && obj2)
      {
        struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr1);
!       if (!pi || pi->pt.vars_contains_restrict)
        return false;
        return !pt_solution_includes (&pi->pt, obj2);
      }
*************** dump_points_to_solution (FILE *file, str
*** 521,537 ****
        fprintf (file, ", points-to vars: ");
        dump_decl_set (file, pt->vars);
        if (pt->vars_contains_nonlocal
!         && pt->vars_contains_escaped_heap)
!       fprintf (file, " (nonlocal, escaped heap)");
!       else if (pt->vars_contains_nonlocal
!              && pt->vars_contains_escaped)
!       fprintf (file, " (nonlocal, escaped)");
!       else if (pt->vars_contains_nonlocal)
!       fprintf (file, " (nonlocal)");
!       else if (pt->vars_contains_escaped_heap)
!       fprintf (file, " (escaped heap)");
!       else if (pt->vars_contains_escaped)
!       fprintf (file, " (escaped)");
      }
  }
  
--- 524,554 ----
        fprintf (file, ", points-to vars: ");
        dump_decl_set (file, pt->vars);
        if (pt->vars_contains_nonlocal
!         || pt->vars_contains_escaped
!         || pt->vars_contains_escaped_heap
!         || pt->vars_contains_restrict)
!       {
!         const char *comma = "";
!         fprintf (file, " (");
!         if (pt->vars_contains_nonlocal)
!           {
!             fprintf (file, "nonlocal");
!             comma = ", ";
!           }
!         if (pt->vars_contains_escaped)
!           {
!             fprintf (file, "%sescaped", comma);
!             comma = ", ";
!           }
!         if (pt->vars_contains_escaped_heap)
!           {
!             fprintf (file, "%sescaped heap", comma);
!             comma = ", ";
!           }
!         if (pt->vars_contains_restrict)
!           fprintf (file, "%srestrict", comma);
!         fprintf (file, ")");
!       }
      }
  }
  
Index: gcc/testsuite/gcc.dg/torture/pr71062.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr71062.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr71062.c      (working copy)
***************
*** 0 ****
--- 1,20 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ 
+ char bar;
+ 
+ int __attribute__((noinline,noclone))
+ foo (char *__restrict p)
+ {
+   if (p == &bar)
+     return 1;
+   return 0;
+ }
+ 
+ int main()
+ {
+   if (foo (&bar) != 1)
+     abort ();
+   return 0;
+ }
Index: gcc/gimple-pretty-print.c
===================================================================
*** gcc/gimple-pretty-print.c   (revision 236159)
--- gcc/gimple-pretty-print.c   (working copy)
*************** pp_points_to_solution (pretty_printer *b
*** 632,648 ****
        }
        pp_right_brace (buffer);
        if (pt->vars_contains_nonlocal
!         && pt->vars_contains_escaped_heap)
!       pp_string (buffer, " (nonlocal, escaped heap)");
!       else if (pt->vars_contains_nonlocal
!              && pt->vars_contains_escaped)
!       pp_string (buffer, " (nonlocal, escaped)");
!       else if (pt->vars_contains_nonlocal)
!       pp_string (buffer, " (nonlocal)");
!       else if (pt->vars_contains_escaped_heap)
!       pp_string (buffer, " (escaped heap)");
!       else if (pt->vars_contains_escaped)
!       pp_string (buffer, " (escaped)");
      }
  }
  
--- 633,669 ----
        }
        pp_right_brace (buffer);
        if (pt->vars_contains_nonlocal
!         || pt->vars_contains_escaped
!         || pt->vars_contains_escaped_heap
!         || pt->vars_contains_restrict)
!       {
!         const char *comma = "";
!         pp_string (buffer, " (");
!         if (pt->vars_contains_nonlocal)
!           {
!             pp_string (buffer, "nonlocal");
!             comma = ", ";
!           }
!         if (pt->vars_contains_escaped)
!           {
!             pp_string (buffer, comma);
!             pp_string (buffer, "escaped");
!             comma = ", ";
!           }
!         if (pt->vars_contains_escaped_heap)
!           {
!             pp_string (buffer, comma);
!             pp_string (buffer, "escaped heap");
!             comma = ", ";
!           }
!         if (pt->vars_contains_restrict)
!           {
!             pp_string (buffer, comma);
!             pp_string (buffer, "restrict");
!           }
!         pp_string (buffer, ")");
!       }
! 
      }
  }
  

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c  (revision 236167)
--- gcc/tree-ssa-structalias.c  (working copy)
*************** set_uids_in_ptset (bitmap into, bitmap f
*** 6254,6259 ****
--- 6254,6262 ----
          pt->vars_contains_escaped_heap = vi->is_heap_var;
        }
  
+       if (vi->is_restrict_var)
+       pt->vars_contains_restrict = true;
+ 
        if (TREE_CODE (vi->decl) == VAR_DECL
          || TREE_CODE (vi->decl) == PARM_DECL
          || TREE_CODE (vi->decl) == RESULT_DECL)
*************** make_pass_build_ealias (gcc::context *ct
*** 7505,7511 ****
  
  /* IPA PTA solutions for ESCAPED.  */
  struct pt_solution ipa_escaped_pt
!   = { true, false, false, false, false, false, false, false, NULL };
  
  /* Associate node with varinfo DATA. Worker for
     cgraph_for_symbol_thunks_and_aliases.  */
--- 7508,7514 ----
  
  /* IPA PTA solutions for ESCAPED.  */
  struct pt_solution ipa_escaped_pt
!   = { true, false, false, false, false, false, false, false, false, NULL };
  
  /* Associate node with varinfo DATA. Worker for
     cgraph_for_symbol_thunks_and_aliases.  */

Reply via email to