re PR middle-end/57347 (wrong code for bitfield on x86_64-linux at -Os and above)
authorMartin Jambor <mjambor@suse.cz>
Thu, 23 May 2013 13:20:41 +0000 (15:20 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Thu, 23 May 2013 13:20:41 +0000 (15:20 +0200)
2013-05-22  Martin Jambor  <mjambor@suse.cz>

PR middle-end/57347
* tree.h (contains_bitfld_component_ref_p): Declare.
* tree-sra.c (contains_bitfld_comp_ref_p): Move...
* tree.c (contains_bitfld_component_ref_p): ...here.  Adjust its caller.
* ipa-prop.c (determine_known_aggregate_parts): Check that LHS does
not access a bit-field.  Assert all final offsets are byte-aligned.

testsuite/
* gcc.dg/ipa/pr57347.c: New test.

From-SVN: r199252

gcc/ChangeLog
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pr57347.c [new file with mode: 0644]
gcc/tree-sra.c
gcc/tree.c
gcc/tree.h

index 0c46d03ee9f145e6f20d57c19ceffc0b92caa145..a97a295a263b1672a9e8ddfcfe77e78a7517ec69 100644 (file)
@@ -1,3 +1,12 @@
+2013-05-22  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/57347
+       * tree.h (contains_bitfld_component_ref_p): Declare.
+       * tree-sra.c (contains_bitfld_comp_ref_p): Move...
+       * tree.c (contains_bitfld_component_ref_p): ...here.  Adjust its caller.
+       * ipa-prop.c (determine_known_aggregate_parts): Check that LHS does
+       not access a bit-field.  Assert all final offsets are byte-aligned.
+
 2013-05-23  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/57380
index ae2a823a4e51693f96c6a8c9d5875640c37102df..7129b302156aecbcdc398b08b03460fcbd93579b 100644 (file)
@@ -1327,7 +1327,9 @@ determine_known_aggregate_parts (gimple call, tree arg,
 
       lhs = gimple_assign_lhs (stmt);
       rhs = gimple_assign_rhs1 (stmt);
-      if (!is_gimple_reg_type (rhs))
+      if (!is_gimple_reg_type (rhs)
+         || TREE_CODE (lhs) == BIT_FIELD_REF
+         || contains_bitfld_component_ref_p (lhs))
        break;
 
       lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
@@ -1418,6 +1420,7 @@ determine_known_aggregate_parts (gimple call, tree arg,
            {
              struct ipa_agg_jf_item item;
              item.offset = list->offset - arg_offset;
+             gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
              item.value = unshare_expr_without_location (list->constant);
              jfunc->agg.items->quick_push (item);
            }
index 0a22b4a92bc30fe29683492c4f8bf795384377a6..b8e99a450112a4a38e726862e10d5d72c5cc4be0 100644 (file)
@@ -1,3 +1,8 @@
+2013-05-22  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/57347
+       * gcc.dg/ipa/pr57347.c: New test.
+
 2013-05-23  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/57380
diff --git a/gcc/testsuite/gcc.dg/ipa/pr57347.c b/gcc/testsuite/gcc.dg/ipa/pr57347.c
new file mode 100644 (file)
index 0000000..731b486
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+struct S1 { int f0; int f1 : 10; int f2 : 13; };
+int i;
+int *j = &i;
+
+static void
+foo (struct S1 s)
+{
+  int *p;
+  int l[88];
+  int **pp = &p;
+  *pp = &l[1];
+  l[0] = 1;
+  *j = 1 && s.f2;
+}
+
+int
+main ()
+{
+  struct S1 s = { 0, 0, 1 };
+  foo (s);
+  if (i != 1)
+    __builtin_abort ();
+  return 0;
+}
index c430c54bb7c3bdc3ea2cf378e9f41e75e46b7115..7e950aeecdf2d2a36b966ae1f8c129cab34ab0d4 100644 (file)
@@ -2998,23 +2998,6 @@ get_repl_default_def_ssa_name (struct access *racc)
   return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
 }
 
-/* Return true if REF has a COMPONENT_REF with a bit-field field declaration
-   somewhere in it.  */
-
-static inline bool
-contains_bitfld_comp_ref_p (const_tree ref)
-{
-  while (handled_component_p (ref))
-    {
-      if (TREE_CODE (ref) == COMPONENT_REF
-          && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
-        return true;
-      ref = TREE_OPERAND (ref, 0);
-    }
-
-  return false;
-}
-
 /* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
    bit-field field declaration somewhere in it.  */
 
@@ -3110,7 +3093,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
             ???  This should move to fold_stmt which we simply should
             call after building a VIEW_CONVERT_EXPR here.  */
          if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
-             && !contains_bitfld_comp_ref_p (lhs))
+             && !contains_bitfld_component_ref_p (lhs))
            {
              lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
              gimple_assign_set_lhs (*stmt, lhs);
index 62909b07b646f900485236137d6901ddb86e4bec..6c71025b6b4845717430ad9bcedf645090ae0914 100644 (file)
@@ -11785,4 +11785,21 @@ warn_deprecated_use (tree node, tree attr)
     }
 }
 
+/* Return true if REF has a COMPONENT_REF with a bit-field field declaration
+   somewhere in it.  */
+
+bool
+contains_bitfld_component_ref_p (const_tree ref)
+{
+  while (handled_component_p (ref))
+    {
+      if (TREE_CODE (ref) == COMPONENT_REF
+          && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
+        return true;
+      ref = TREE_OPERAND (ref, 0);
+    }
+
+  return false;
+}
+
 #include "gt-tree.h"
index f2dc1b10466ef03d65c597ba7c1713681ad020c4..1d2b252dec0a5150e64011d50a694be8feecc6c9 100644 (file)
@@ -5974,6 +5974,7 @@ extern tree block_ultimate_origin (const_tree);
 extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
 extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
                                     HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern bool contains_bitfld_component_ref_p (const_tree);
 
 /* In tree-nested.c */
 extern tree build_addr (tree, tree);