]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/52402 (IPA-SRA creates aligned loads from unaligned memory)
authorRichard Guenther <rguenther@suse.de>
Tue, 28 Feb 2012 09:15:49 +0000 (09:15 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 28 Feb 2012 09:15:49 +0000 (09:15 +0000)
2012-02-28  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/52402
* ipa-prop.c (ipa_modify_call_arguments): Properly use
mis-aligned types when creating the accesses at the call site.

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

From-SVN: r184619

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

index a89a8ff6943d4ad1117fa0a8f5ae1dbf3ce4ed5b..24df23ab7debf964c1858dca35e325e4ec3242de 100644 (file)
@@ -1,3 +1,9 @@
+2012-02-28  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52402
+       * ipa-prop.c (ipa_modify_call_arguments): Properly use
+       mis-aligned types when creating the accesses at the call site.
+
 2012-02-28  Georg-Johann Lay  <avr@gjlay.de>
 
        * config/avr/builtins.def: New file.
index 6d76adbbfb6618b0b3b1b013ea1b097baebc5946..3856793b0546c0a3178c46210e251edf0f068929 100644 (file)
@@ -2508,9 +2508,27 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
                }
            }
 
-         expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
-         if (adj->by_ref)
-           expr = build_fold_addr_expr (expr);
+         if (!adj->by_ref)
+           {
+             tree type = adj->type;
+             unsigned int align;
+             unsigned HOST_WIDE_INT misalign;
+             align = get_pointer_alignment_1 (base, &misalign);
+             misalign += (double_int_sext (tree_to_double_int (off),
+                                           TYPE_PRECISION (TREE_TYPE (off))).low
+                          * BITS_PER_UNIT);
+             misalign = misalign & (align - 1);
+             if (misalign != 0)
+               align = (misalign & -misalign);
+             if (align < TYPE_ALIGN (type))
+               type = build_aligned_type (type, align);
+             expr = fold_build2_loc (loc, MEM_REF, type, base, off);
+           }
+         else
+           {
+             expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
+             expr = build_fold_addr_expr (expr);
+           }
 
          expr = force_gimple_operand_gsi (&gsi, expr,
                                           adj->by_ref
index ee4e5f34adea96b0005cf597a0a273a738ac0050..7a3af5818dac4e26969592aba3426a5c0397322f 100644 (file)
@@ -1,3 +1,8 @@
+2012-02-28  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52402
+       * gcc.dg/torture/pr52402.c: New testcase.
+
 2012-02-28  Richard Guenther  <rguenther@suse.de>
 
        PR lto/52400
diff --git a/gcc/testsuite/gcc.dg/torture/pr52402.c b/gcc/testsuite/gcc.dg/torture/pr52402.c
new file mode 100644 (file)
index 0000000..5bd51fb
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+typedef int v4si __attribute__((vector_size(16)));
+struct T { v4si i[2]; int j; } __attribute__((packed));
+
+static v4si __attribute__((noinline))
+foo (struct T t)
+{
+  return t.i[0];
+}
+
+static struct T *__attribute__((noinline))
+init ()
+{
+  char *p = __builtin_malloc (sizeof (struct T) + 1);
+  p++;
+  __builtin_memset (p, 1, sizeof (struct T));
+  return (struct T *)p;
+}
+
+int main()
+{
+  struct T *p;
+  p = init ();
+  if (foo (*p)[0] != 0x01010101)
+    __builtin_abort ();
+  return 0;
+}