]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Guenther <rguenther@suse.de>
Wed, 4 Jan 2012 11:54:18 +0000 (11:54 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 4 Jan 2012 11:54:18 +0000 (11:54 +0000)
2012-01-04  Richard Guenther  <rguenther@suse.de>

Backport from mainline
2012-01-04  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/49651
* tree-ssa-structalias.c (type_can_have_subvars): New function.
(var_can_have_subvars): Use it.
(get_constraint_for_1): Only consider subfields if there
can be any.

2011-07-14  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/49651
* tree-ssa-structalias.c (get_constraint_for_1): Properly
handle dereferences with subvariables.

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

From-SVN: r182870

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr49651.c [new file with mode: 0644]
gcc/tree-ssa-structalias.c

index 148276d819f6d0d5c18186559e6111804cde83f2..4a1a3e04f2f684e2b5326c291b9a369577e63124 100644 (file)
@@ -1,3 +1,20 @@
+2012-01-04  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2012-01-04  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49651
+       * tree-ssa-structalias.c (type_can_have_subvars): New function.
+       (var_can_have_subvars): Use it.
+       (get_constraint_for_1): Only consider subfields if there
+       can be any.
+
+       2011-07-14  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49651
+       * tree-ssa-structalias.c (get_constraint_for_1): Properly
+       handle dereferences with subvariables.
+
 2012-01-03  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
index 52d9121408cad2f45d8692b75a6f64e56374a3f0..137f5af8adbf3c37e8d675e4c7eab7b4fa981aff 100644 (file)
@@ -1,3 +1,11 @@
+2012-01-04  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2011-07-14  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49651
+       * gcc.dg/torture/pr49651.c: New testcase.
+
 2012-01-03  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/torture/pr49651.c b/gcc/testsuite/gcc.dg/torture/pr49651.c
new file mode 100644 (file)
index 0000000..c58fe94
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+struct X {
+    int *p;
+    int *q;
+};
+
+void __attribute__((noinline, noclone))
+foo (struct X x) { *x.q = 0; }
+
+volatile int what;
+struct X y;
+
+int main()
+{
+  int i, j;
+  struct X x, *p;
+  x.p = &i;
+  x.q = &j;
+  if (what)
+    p = &y;
+  else
+    p = &x;
+  j = 1;
+  foo (*p);
+  if (j != 0)
+    abort ();
+  return 0;
+}
index b2ba385be0a7cdd35d96561f18a62df557e1eeb8..0d39a3e90762559d4db80ee88a79c9542ded14ca 100644 (file)
@@ -266,6 +266,7 @@ static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
 static varinfo_t first_or_preceding_vi_for_offset (varinfo_t,
                                                   unsigned HOST_WIDE_INT);
 static varinfo_t lookup_vi_for_tree (tree);
+static inline bool type_can_have_subvars (const_tree);
 
 /* Pool of variable info structures.  */
 static alloc_pool variable_info_pool;
@@ -3187,10 +3188,51 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,
          {
          case INDIRECT_REF:
            {
+             struct constraint_expr cs;
+             varinfo_t vi, curr;
              get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
                                    lhs_p);
              do_deref (results);
-             return;
+
+             /* If we are not taking the address then make sure to process
+                all subvariables we might access.  */
+             if (address_p)
+               return;
+
+             cs = *VEC_last (ce_s, *results);
+             if (cs.type == DEREF
+                 && type_can_have_subvars (TREE_TYPE (t)))
+               {
+                 /* For dereferences this means we have to defer it
+                    to solving time.  */
+                 VEC_last (ce_s, *results)->offset = UNKNOWN_OFFSET;
+                 return;
+               }
+             if (cs.type != SCALAR)
+               return;
+
+             vi = get_varinfo (cs.var);
+             curr = vi->next;
+             if (!vi->is_full_var
+                 && curr)
+               {
+                 unsigned HOST_WIDE_INT size;
+                 if (host_integerp (TYPE_SIZE (TREE_TYPE (t)), 1))
+                   size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (t)));
+                 else
+                   size = -1;
+                 for (; curr; curr = curr->next)
+                   {
+                     if (curr->offset - vi->offset < size)
+                       {
+                         cs.var = curr->id;
+                         VEC_safe_push (ce_s, heap, *results, &cs);
+                       }
+                     else
+                       break;
+                   }
+                }
+              return;
            }
          case ARRAY_REF:
          case ARRAY_RANGE_REF:
@@ -4201,6 +4243,15 @@ sort_fieldstack (VEC(fieldoff_s,heap) *fieldstack)
         fieldoff_compare);
 }
 
+/* Return true if T is a type that can have subvars.  */
+
+static inline bool
+type_can_have_subvars (const_tree t)
+{
+  /* Aggregates without overlapping fields can have subvars.  */
+  return TREE_CODE (t) == RECORD_TYPE;
+}
+
 /* Return true if V is a tree that we can have subvars for.
    Normally, this is any aggregate type.  Also complex
    types which are not gimple registers can have subvars.  */
@@ -4216,11 +4267,7 @@ var_can_have_subvars (const_tree v)
   if (!DECL_P (v))
     return false;
 
-  /* Aggregates without overlapping fields can have subvars.  */
-  if (TREE_CODE (TREE_TYPE (v)) == RECORD_TYPE)
-    return true;
-
-  return false;
+  return type_can_have_subvars (TREE_TYPE (v));
 }
 
 /* Return true if T is a type that does contain pointers.  */