re PR tree-optimization/36343 (Wrong code due to bad TBAA pruning of points-to-sets...
authorRichard Guenther <rguenther@suse.de>
Thu, 29 May 2008 10:31:58 +0000 (10:31 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 29 May 2008 10:31:58 +0000 (10:31 +0000)
2008-05-29  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/36343
PR tree-optimization/36346
PR tree-optimization/36347
* tree-flow.h (clobber_what_p_points_to): Declare.
* tree-ssa-structalias.c (set_uids_in_ptset): Whether the
pointed-to variable is dereferenced is irrelevant to whether
the pointer can access the pointed-to variable.
(clobber_what_p_points_to): New function.
* tree-ssa-alias.c (set_initial_properties): Use it.
* tree-ssa.c (verify_flow_sensitive_alias_info): Adjust
call clobber check for NMTs.

* gcc.c-torture/execute/pr36343.c: New testcase.

From-SVN: r136152

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr36343.c [new file with mode: 0644]
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c

index 9c10b88973fa4af0e6ecc9b26e645e93630d196c..72477652d6d08bd305fad7f7332d128f09780069 100644 (file)
@@ -1,3 +1,17 @@
+2008-05-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/36343
+       PR tree-optimization/36346
+       PR tree-optimization/36347
+       * tree-flow.h (clobber_what_p_points_to): Declare.
+       * tree-ssa-structalias.c (set_uids_in_ptset): Whether the
+       pointed-to variable is dereferenced is irrelevant to whether
+       the pointer can access the pointed-to variable.
+       (clobber_what_p_points_to): New function.
+       * tree-ssa-alias.c (set_initial_properties): Use it.
+       * tree-ssa.c (verify_flow_sensitive_alias_info): Adjust
+       call clobber check for NMTs.
+
 2008-05-28  Seongbae Park  <seongbae.park@gmail.com>
        
        * value-prof.c (tree_ic_transform): Use HOST_WIDEST_INT_PRINT_DEC
index f52843acc82591479c34c850e62c6ec1cf45f15a..9f77f70634b9ed9102f56d5e040e347519574efc 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/36343
+       * gcc.c-torture/execute/pr36343.c: New testcase.
+
 2008-05-29  Arnaud Charlet  <charlet@adacore.com>
 
        * gnat.dg/abstract1.ad[sb]: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr36343.c b/gcc/testsuite/gcc.c-torture/execute/pr36343.c
new file mode 100644 (file)
index 0000000..44b9fb3
--- /dev/null
@@ -0,0 +1,32 @@
+extern void abort (void);
+
+void __attribute__((noinline))
+bar (int **p)
+{
+  float *q = (float *)p;
+  *q = 0.0;
+}
+
+float __attribute__((noinline))
+foo (int b)
+{
+  int *i = 0;
+  float f = 1.0;
+  int **p;
+  if (b)
+    p = &i;
+  else
+    p = (int **)&f;
+  bar (p);
+  if (b)
+    return **p;
+  return f;
+}
+
+int main()
+{
+  if (foo(0) != 0.0)
+    abort ();
+  return 0;
+}
+
index 8bc6cc8a0ca96093c729e7ff08dfe1dec4d5116f..94d5a69f69ccebb8f3a8c77ec1fba439179dfe52 100644 (file)
@@ -1167,6 +1167,7 @@ tree gimple_fold_indirect_ref (tree);
 
 /* In tree-ssa-structalias.c */
 bool find_what_p_points_to (tree);
+bool clobber_what_p_points_to (tree);
 
 /* In tree-ssa-live.c */
 extern void remove_unused_locals (void);
index 4f661543a55188c23c632afbacf57151ee39ddb5..1523aebac17aa0670ab94c8e7b88fd6b6e6a2591 100644 (file)
@@ -545,8 +545,14 @@ set_initial_properties (struct alias_info *ai)
     {
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
       tree tag = symbol_mem_tag (SSA_NAME_VAR (ptr));
-      
-      if (pi->value_escapes_p)
+
+      /* A pointer that only escapes via a function return does not
+         add to the call clobber or call used solution.
+        To exclude ESCAPE_TO_PURE_CONST we would need to track
+        call used variables separately or compute those properly
+        in the operand scanner.  */
+      if (pi->value_escapes_p
+         && pi->escape_mask & ~ESCAPE_TO_RETURN)
        {
          /* If PTR escapes then its associated memory tags and
             pointed-to variables are call-clobbered.  */
@@ -556,24 +562,13 @@ set_initial_properties (struct alias_info *ai)
          if (tag)
            mark_call_clobbered (tag, pi->escape_mask);
 
-         if (pi->pt_vars)
-           {
-             bitmap_iterator bi;
-             unsigned int j;         
-             EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi)
-               {
-                 tree alias = referenced_var (j);
-
-                 /* If you clobber one part of a structure, you
-                    clobber the entire thing.  While this does not make
-                    the world a particularly nice place, it is necessary
-                    in order to allow C/C++ tricks that involve
-                    pointer arithmetic to work.  */
-                 if (!unmodifiable_var_p (alias))
-                   mark_call_clobbered (alias, pi->escape_mask);
-               }
-           }
-         else if (pi->pt_anything)
+         /* Defer to points-to analysis if possible, otherwise
+            clobber all addressable variables.  Parameters cannot
+            point to local memory though.
+            ???  Properly tracking which pointers point to non-local
+            memory only would make a big difference here.  */
+         if (!clobber_what_p_points_to (ptr)
+             && !(pi->escape_mask & ESCAPE_IS_PARM))
            {
              any_pt_anything = true;
              pt_anything_mask |= pi->escape_mask;
index 7c79a3df68de8c4835e2193bdeadd47dd497c739..b6d73ce66f4f138db0b2cbd640f2d6d6f473314a 100644 (file)
@@ -4664,17 +4664,19 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
          || TREE_CODE (vi->decl) == RESULT_DECL)
        {
          /* Just add VI->DECL to the alias set.
-            Don't type prune artificial vars.  */
-         if (vi->is_artificial_var)
+            Don't type prune artificial vars or points-to sets
+            for pointers that have not been dereferenced or with
+            type-based pruning disabled.  */
+         if (vi->is_artificial_var
+             || !is_derefed
+             || no_tbaa_pruning)
            bitmap_set_bit (into, DECL_UID (vi->decl));
          else
            {
              alias_set_type var_alias_set, ptr_alias_set;
              var_alias_set = get_alias_set (vi->decl);
              ptr_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
-             if (no_tbaa_pruning
-                 || (!is_derefed && !vi->directly_dereferenced)
-                 || alias_sets_conflict_p (ptr_alias_set, var_alias_set))
+             if (alias_sets_conflict_p (ptr_alias_set, var_alias_set))
                bitmap_set_bit (into, DECL_UID (vi->decl));
            }
        }
@@ -4885,7 +4887,71 @@ find_what_p_points_to (tree p)
   return false;
 }
 
+/* Mark everything that p points to as call clobbered.  Returns true
+   if everything is done and false if all addressable variables need to
+   be clobbered because p points to anything.  */
 
+bool
+clobber_what_p_points_to (tree p)
+{
+  tree lookup_p = p;
+  varinfo_t vi;
+  struct ptr_info_def *pi;
+  unsigned int i;
+  bitmap_iterator bi;
+
+  if (!have_alias_info)
+    return false;
+
+  /* For parameters, get at the points-to set for the actual parm
+     decl.  */
+  if (TREE_CODE (p) == SSA_NAME
+      && TREE_CODE (SSA_NAME_VAR (p)) == PARM_DECL
+      && SSA_NAME_IS_DEFAULT_DEF (p))
+    lookup_p = SSA_NAME_VAR (p);
+
+  vi = lookup_vi_for_tree (lookup_p);
+  if (!vi)
+    return false;
+
+  /* We are asking for the points-to solution of pointers.  */
+  gcc_assert (!vi->is_artificial_var
+             && vi->size == vi->fullsize);
+
+  pi = get_ptr_info (p);
+
+  /* This variable may have been collapsed, let's get the real
+     variable.  */
+  vi = get_varinfo (find (vi->id));
+
+  /* Mark variables in the solution call-clobbered.  */
+  EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, i, bi)
+    {
+      varinfo_t vi = get_varinfo (i);
+
+      if (vi->is_artificial_var)
+       {
+         /* nothing_id and readonly_id do not cause any
+            call clobber ops.  For anything_id and integer_id
+            we need to clobber all addressable vars.  */
+         if (vi->id == anything_id
+             || vi->id == integer_id)
+           return false;
+       }
+
+      /* Only artificial heap-vars are further interesting.  */
+      if (vi->is_artificial_var && !vi->is_heap_var)
+       continue;
+
+      if ((TREE_CODE (vi->decl) == VAR_DECL
+          || TREE_CODE (vi->decl) == PARM_DECL
+          || TREE_CODE (vi->decl) == RESULT_DECL)
+         && !unmodifiable_var_p (vi->decl))
+       mark_call_clobbered (vi->decl, pi->escape_mask);
+    }
+
+  return true;
+}
 
 /* Dump points-to information to OUTFILE.  */
 
index 1c01d71bf6ef6e4db6154ef34b0e068299cc51e2..f71e3af7ff98b362491745a36faeb1ce3887e443 100644 (file)
@@ -571,7 +571,9 @@ verify_flow_sensitive_alias_info (void)
          goto err;
        }
 
-      if (pi->value_escapes_p && pi->name_mem_tag)
+      if (pi->value_escapes_p
+         && pi->escape_mask & ~ESCAPE_TO_RETURN
+         && pi->name_mem_tag)
        {
          tree t = memory_partition (pi->name_mem_tag);
          if (t == NULL_TREE)