Prevent SRA from removing type changing assignment
authorMartin Jambor <mjambor@suse.cz>
Fri, 8 Dec 2017 12:11:02 +0000 (13:11 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 8 Dec 2017 12:11:02 +0000 (13:11 +0100)
2017-12-08  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/83141
* tree-sra.c (contains_vce_or_bfcref_p): Move up in the file, also
test for MEM_REFs implicitely changing types with padding.  Remove
inline keyword.
(build_accesses_from_assign): Added contains_vce_or_bfcref_p checks.

testsuite/
* gcc.dg/tree-ssa/pr83141.c: New test.
* gcc.dg/guality/pr54970.c: XFAIL tests querying a[0].

From-SVN: r255510

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr54970.c
gcc/testsuite/gcc.dg/tree-ssa/pr83141.c [new file with mode: 0644]
gcc/tree-sra.c

index 0bc97035a8ee744ad7daf1e9f7aef3daadc3b147..8184c66e8c8db31808124060660c5b05735da69f 100644 (file)
@@ -1,3 +1,11 @@
+2017-12-08  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/83141
+       * tree-sra.c (contains_vce_or_bfcref_p): Move up in the file, also
+       test for MEM_REFs implicitely changing types with padding.  Remove
+       inline keyword.
+       (build_accesses_from_assign): Added contains_vce_or_bfcref_p checks.
+
 2017-12-08  Jakub Jelinek  <jakub@redhat.com>
 
        * config/arc/arc.c (arc_attribute_table): Add exclusions to
index cae9220a63d770cfb8597bad82141636e91a1332..7d03796f215892420d4d25391b45f917ca2b322d 100644 (file)
@@ -1,3 +1,9 @@
+2017-12-08  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/83141
+       * gcc.dg/tree-ssa/pr83141.c: New test.
+       * gcc.dg/guality/pr54970.c: XFAIL tests querying a[0].
+
 2017-12-08  Jan Hubicka  <hubicka@ucw.cz>
 
        PR middle-end/83609
index a9b8c064d8b301c6dd77ccacad9ba5eb64ff4b54..1819d023e21f509523464f34058f285634634087 100644 (file)
@@ -24,23 +24,23 @@ main ()
                                /* { dg-final { gdb-test 25 "*p" "13" } } */
   asm volatile (NOP);          /* { dg-final { gdb-test 25 "*q" "12" } } */
   __builtin_memcpy (&a, (int [3]) { 4, 5, 6 }, sizeof (a));
-                               /* { dg-final { gdb-test 31 "a\[0\]" "4" } } */
+                               /* { dg-final { gdb-test 31 "a\[0\]" "4" { xfail { *-*-* } } } } */
                                /* { dg-final { gdb-test 31 "a\[1\]" "5" } } */
                                /* { dg-final { gdb-test 31 "a\[2\]" "6" } } */
                                /* { dg-final { gdb-test 31 "*p" "6" } } */
   asm volatile (NOP);          /* { dg-final { gdb-test 31 "*q" "5" } } */
-  *p += 20;                    /* { dg-final { gdb-test 36 "a\[0\]" "4" } } */
+  *p += 20;                    /* { dg-final { gdb-test 36 "a\[0\]" "4" { xfail { *-*-* } } } } */
                                /* { dg-final { gdb-test 36 "a\[1\]" "5" } } */
                                /* { dg-final { gdb-test 36 "a\[2\]" "26" } } */
                                /* { dg-final { gdb-test 36 "*p" "26" } } */
   asm volatile (NOP);          /* { dg-final { gdb-test 36 "*q" "5" } } */
-  *q += 20;                    /* { dg-final { gdb-test 45 "a\[0\]" "4" } } */
+  *q += 20;                    /* { dg-final { gdb-test 45 "a\[0\]" "4" { xfail { *-*-* } } } } */
                                /* { dg-final { gdb-test 45 "a\[1\]" "25" } } */
                                /* { dg-final { gdb-test 45 "a\[2\]" "26" } } */
                                /* { dg-final { gdb-test 45 "*p" "26" } } */
                                /* { dg-final { gdb-test 45 "p\[-1\]" "25" } } */
-                               /* { dg-final { gdb-test 45 "p\[-2\]" "4" } } */
-                               /* { dg-final { gdb-test 45 "q\[-1\]" "4" } } */
+                               /* { dg-final { gdb-test 45 "p\[-2\]" "4" { xfail { *-*-* } } } } */
+                               /* { dg-final { gdb-test 45 "q\[-1\]" "4" { xfail { *-*-* } } } } */
                                /* { dg-final { gdb-test 45 "q\[1\]" "26" } } */
   asm volatile (NOP);          /* { dg-final { gdb-test 45 "*q" "25" } } */
   return 0;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83141.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83141.c
new file mode 100644 (file)
index 0000000..73ea45c
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-esra-details" } */
+
+volatile short vs;
+volatile long vl;
+
+struct A { short s; long i; long j; };
+struct A a, b;
+void foo ()
+{
+  struct A c;
+  __builtin_memcpy (&c, &b, sizeof (struct A));
+  __builtin_memcpy (&a, &c, sizeof (struct A));
+
+  vs = c.s;
+  vl = c.i;
+  vl = c.j;
+}
+
+
+int main()
+{
+  if ((sizeof (short) != 2)
+      || (__builtin_offsetof (struct A, i) < 4))
+    return 0;
+
+  __builtin_memset (&b, 0, sizeof (struct A));
+  b.s = 1;
+  __builtin_memcpy ((char *)&b+2, &b, 2);
+  foo ();
+  __builtin_memcpy (&a, (char *)&a+2, 2);
+  if (a.s != 1)
+    __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Will attempt to totally scalarize" "esra" } } */
index 866cff0edb045b606556f7ba8c800f48b1fd85ea..54f1c8d54d5b8700ec9948e3142e083a32dd78aa 100644 (file)
@@ -1141,6 +1141,33 @@ contains_view_convert_expr_p (const_tree ref)
   return false;
 }
 
+/* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs
+   type conversion or a COMPONENT_REF with a bit-field field declaration.  */
+
+static bool
+contains_vce_or_bfcref_p (const_tree ref)
+{
+  while (handled_component_p (ref))
+    {
+      if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
+         || (TREE_CODE (ref) == COMPONENT_REF
+             && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
+       return true;
+      ref = TREE_OPERAND (ref, 0);
+    }
+
+  if (TREE_CODE (ref) != MEM_REF
+      || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
+    return false;
+
+  tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
+  if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
+      != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
+    return true;
+
+  return false;
+}
+
 /* Search the given tree for a declaration by skipping handled components and
    exclude it from the candidates.  */
 
@@ -1339,7 +1366,14 @@ build_accesses_from_assign (gimple *stmt)
       racc->grp_assignment_read = 1;
       if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
          && !is_gimple_reg_type (racc->type))
-       bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+       {
+         if (contains_vce_or_bfcref_p (rhs))
+           bitmap_set_bit (cannot_scalarize_away_bitmap,
+                           DECL_UID (racc->base));
+         else
+           bitmap_set_bit (should_scalarize_away_bitmap,
+                           DECL_UID (racc->base));
+       }
       if (storage_order_barrier_p (lhs))
        racc->grp_unscalarizable_region = 1;
     }
@@ -3416,24 +3450,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 an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
-   bit-field field declaration somewhere in it.  */
-
-static inline bool
-contains_vce_or_bfcref_p (const_tree ref)
-{
-  while (handled_component_p (ref))
-    {
-      if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
-         || (TREE_CODE (ref) == COMPONENT_REF
-             && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
-       return true;
-      ref = TREE_OPERAND (ref, 0);
-    }
-
-  return false;
-}
-
 /* Examine both sides of the assignment statement pointed to by STMT, replace
    them with a scalare replacement if there is one and generate copying of
    replacements if scalarized aggregates have been used in the assignment.  GSI