re PR tree-optimization/58984 (wrong code at -Os and above on x86_64-linux-gnu in...
authorJakub Jelinek <jakub@redhat.com>
Tue, 5 Nov 2013 12:05:37 +0000 (13:05 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 5 Nov 2013 12:05:37 +0000 (13:05 +0100)
PR tree-optimization/58984
* ipa-prop.c (ipa_load_from_parm_agg_1): Add SIZE_P argument,
set *SIZE_P if non-NULL on success.
(ipa_load_from_parm_agg, ipa_analyze_indirect_call_uses): Adjust
callers.
(ipcp_transform_function): Likewise.  Punt if size of access
is different from TYPE_SIZE on v->value's type.

* gcc.c-torture/execute/pr58984.c: New test.

From-SVN: r204385

gcc/ChangeLog
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr58984.c [new file with mode: 0644]

index eecf65b91fe36920a1525dfbf37572240afb5174..06515889f6a9552e41e69cc6855b782f41827dc3 100644 (file)
@@ -1,3 +1,13 @@
+2013-11-05  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58984
+       * ipa-prop.c (ipa_load_from_parm_agg_1): Add SIZE_P argument,
+       set *SIZE_P if non-NULL on success.
+       (ipa_load_from_parm_agg, ipa_analyze_indirect_call_uses): Adjust
+       callers.
+       (ipcp_transform_function): Likewise.  Punt if size of access
+       is different from TYPE_SIZE on v->value's type.
+
 2013-11-05  Tobias Burnus  <burnus@net-b.de>
 
        * doc/invoke.texi (-fopenmp-simd): Document new option.
index d9ea5dc08bfff2cd313e59444c97e76b80f5e931..07af67724f5df71c5a04bf4a48aab4a3d723ce0c 100644 (file)
@@ -852,7 +852,7 @@ static bool
 ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors,
                          struct param_analysis_info *parms_ainfo, gimple stmt,
                          tree op, int *index_p, HOST_WIDE_INT *offset_p,
-                         bool *by_ref_p)
+                         HOST_WIDE_INT *size_p, bool *by_ref_p)
 {
   int index;
   HOST_WIDE_INT size, max_size;
@@ -870,6 +870,8 @@ ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors,
        {
          *index_p = index;
          *by_ref_p = false;
+         if (size_p)
+           *size_p = size;
          return true;
        }
       return false;
@@ -912,6 +914,8 @@ ipa_load_from_parm_agg_1 (vec<ipa_param_descriptor_t> descriptors,
     {
       *index_p = index;
       *by_ref_p = true;
+      if (size_p)
+       *size_p = size;
       return true;
     }
   return false;
@@ -926,7 +930,7 @@ ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
                        bool *by_ref_p)
 {
   return ipa_load_from_parm_agg_1 (info->descriptors, NULL, stmt, op, index_p,
-                                  offset_p, by_ref_p);
+                                  offset_p, NULL, by_ref_p);
 }
 
 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
@@ -1826,7 +1830,7 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node,
   if (gimple_assign_single_p (def)
       && ipa_load_from_parm_agg_1 (info->descriptors, parms_ainfo, def,
                                   gimple_assign_rhs1 (def), &index, &offset,
-                                  &by_ref))
+                                  NULL, &by_ref))
     {
       struct cgraph_edge *cs = ipa_note_param_call (node, index, call);
       cs->indirect_info->offset = offset;
@@ -4567,7 +4571,7 @@ ipcp_transform_function (struct cgraph_node *node)
        struct ipa_agg_replacement_value *v;
        gimple stmt = gsi_stmt (gsi);
        tree rhs, val, t;
-       HOST_WIDE_INT offset;
+       HOST_WIDE_INT offset, size;
        int index;
        bool by_ref, vce;
 
@@ -4594,13 +4598,15 @@ ipcp_transform_function (struct cgraph_node *node)
          continue;
 
        if (!ipa_load_from_parm_agg_1 (descriptors, parms_ainfo, stmt,
-                                      rhs, &index, &offset, &by_ref))
+                                      rhs, &index, &offset, &size, &by_ref))
          continue;
        for (v = aggval; v; v = v->next)
          if (v->index == index
              && v->offset == offset)
            break;
-       if (!v || v->by_ref != by_ref)
+       if (!v
+           || v->by_ref != by_ref
+           || tree_low_cst (TYPE_SIZE (TREE_TYPE (v->value)), 0) != size)
          continue;
 
        gcc_checking_assert (is_gimple_ip_invariant (v->value));
index 0686afa26f9c70d3d174add75ca77e34274c651d..d95fc2c64dedfd7d916b1babe9ae3852124d8e79 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-05  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58984
+       * gcc.c-torture/execute/pr58984.c: New test.
+
 2013-11-05  Andreas Schwab  <schwab@suse.de>
 
        * g++.dg/ext/sync-4.C: Require sync_long_long_runtime support.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58984.c b/gcc/testsuite/gcc.c-torture/execute/pr58984.c
new file mode 100644 (file)
index 0000000..e0f7669
--- /dev/null
@@ -0,0 +1,57 @@
+/* PR tree-optimization/58984 */
+
+struct S { int f0 : 8; int : 6; int f1 : 5; };
+struct T { char f0; int : 6; int f1 : 5; };
+
+int a, *c = &a, e, n, b, m;
+
+static int
+foo (struct S p)
+{
+  const unsigned short *f[36];
+  for (; e < 2; e++)
+    {
+      const unsigned short **i = &f[0];
+      *c ^= 1;
+      if (p.f1)
+       {
+         *i = 0;
+         return b;
+       }
+    }
+  return 0;
+}
+
+static int
+bar (struct T p)
+{
+  const unsigned short *f[36];
+  for (; e < 2; e++)
+    {
+      const unsigned short **i = &f[0];
+      *c ^= 1;
+      if (p.f1)
+       {
+         *i = 0;
+         return b;
+       }
+    }
+  return 0;
+}
+
+int
+main ()
+{
+  struct S o = { 1, 1 };
+  foo (o);
+  m = n || o.f0;
+  if (a != 1)
+    __builtin_abort ();
+  e = 0;
+  struct T p = { 1, 1 };
+  bar (p);
+  m |= n || p.f0;
+  if (a != 0)
+    __builtin_abort ();
+  return 0;
+}