]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/51315 (unaligned memory accesses generated with -ftree-sra)
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 5 Jan 2012 22:24:45 +0000 (22:24 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 5 Jan 2012 22:24:45 +0000 (22:24 +0000)
PR tree-optimization/51315
* tree-sra.c (tree_non_aligned_mem_for_access_p): New predicate.
(build_accesses_from_assign): Use it instead of tree_non_aligned_mem_p.

From-SVN: r182933

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20120105-1.c [new file with mode: 0644]
gcc/tree-sra.c

index c9a2654764b1a1dd747f08569014abe5583c87f2..c020ffd20e0967b7b4c1732b5fc7bd7693654e44 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR tree-optimization/51315
+       * tree-sra.c (tree_non_aligned_mem_for_access_p): New predicate.
+       (build_accesses_from_assign): Use it instead of tree_non_aligned_mem_p.
+
 2012-01-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR tree-optimization/51624
index e9ffe531c49372231e68854646d7c93e9dab3721..6b8a0c4e3a317dac372a20e87ccf13572aa84c61 100644 (file)
@@ -1,3 +1,7 @@
+2012-01-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.c-torture/execute/20120104-1.c: New test.
+
 2012-01-04  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/49651
diff --git a/gcc/testsuite/gcc.c-torture/execute/20120105-1.c b/gcc/testsuite/gcc.c-torture/execute/20120105-1.c
new file mode 100644 (file)
index 0000000..115ba15
--- /dev/null
@@ -0,0 +1,24 @@
+struct __attribute__((packed)) S
+{
+  int a, b, c;
+};
+
+static int __attribute__ ((noinline,noclone))
+extract(const char *p)
+{
+  struct S s;
+  __builtin_memcpy (&s, p, sizeof(struct S));
+  return s.a;
+}
+
+volatile int i;
+
+int main (void)
+{
+  char p[sizeof(struct S) + 1];
+
+  __builtin_memset (p, 0, sizeof(struct S) + 1);
+  i = extract (p + 1);
+
+  return 0;
+}
index 016c0387d7773fc64eec29d36488b089671b295a..63eec95e12680aa879b8c37a56ab2f26ba12986c 100644 (file)
@@ -1047,6 +1047,25 @@ tree_non_aligned_mem_p (tree exp, unsigned int align)
   return false;
 }
 
+/* Return true if EXP is a memory reference less aligned than what the access
+   ACC would require.  This is invoked only on strict-alignment targets.  */
+
+static bool
+tree_non_aligned_mem_for_access_p (tree exp, struct access *acc)
+{
+  unsigned int acc_align;
+
+  /* The alignment of the access is that of its expression.  However, it may
+     have been artificially increased, e.g. by a local alignment promotion,
+     so we cap it to the alignment of the type of the base, on the grounds
+     that valid sub-accesses cannot be more aligned than that.  */
+  acc_align = get_object_alignment (acc->expr, BIGGEST_ALIGNMENT);
+  if (acc->base && acc_align > TYPE_ALIGN (TREE_TYPE (acc->base)))
+    acc_align = TYPE_ALIGN (TREE_TYPE (acc->base));
+
+  return tree_non_aligned_mem_p (exp, acc_align);
+}
+
 /* Scan expressions occuring in STMT, create access structures for all accesses
    to candidates for scalarization and remove those candidates which occur in
    statements or expressions that prevent them from being split apart.  Return
@@ -1073,10 +1092,7 @@ build_accesses_from_assign (gimple stmt)
   if (lacc)
     {
       lacc->grp_assignment_write = 1;
-      if (STRICT_ALIGNMENT
-         && tree_non_aligned_mem_p (rhs,
-                                    get_object_alignment (lhs,
-                                                          BIGGEST_ALIGNMENT)))
+      if (STRICT_ALIGNMENT && tree_non_aligned_mem_for_access_p (rhs, lacc))
         lacc->grp_unscalarizable_region = 1;
     }
 
@@ -1086,10 +1102,7 @@ build_accesses_from_assign (gimple stmt)
       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 (STRICT_ALIGNMENT
-         && tree_non_aligned_mem_p (lhs,
-                                    get_object_alignment (rhs,
-                                                          BIGGEST_ALIGNMENT)))
+      if (STRICT_ALIGNMENT && tree_non_aligned_mem_for_access_p (lhs, racc))
         racc->grp_unscalarizable_region = 1;
     }