Hi!

For integral types, we really should honor TYPE_UNSIGNED (scalar_type)
when we call type_for_mode for overaligned types, otherwise we can break
type checking (original something = something + 1; where something
is overaligned int type can become unsigned int vector for lhs and rhs1
and int vector for rhs2).

Fixed thusly, bootstrapped/regtested on x86_64-linux, ok for trunk?

2013-02-26  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/56443
        * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): For
        overaligned types, pass TYPE_UNSIGNED (scalar_type) as second argument
        to type_for_mode langhook.

        * gcc.dg/torture/pr56443.c: New test.

--- gcc/tree-vect-stmts.c.jj    2013-02-05 16:45:40.000000000 +0100
+++ gcc/tree-vect-stmts.c       2013-02-25 13:56:46.978440945 +0100
@@ -6071,7 +6071,8 @@ get_vectype_for_scalar_type_and_size (tr
   /* We can't build a vector type of elements with alignment bigger than
      their size.  */
   else if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
-    scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+    scalar_type = lang_hooks.types.type_for_mode (inner_mode, 
+                                                 TYPE_UNSIGNED (scalar_type));
 
   /* If we felt back to using the mode fail if there was
      no scalar type for it.  */
--- gcc/testsuite/gcc.dg/torture/pr56443.c.jj   2013-02-25 14:01:11.347972815 
+0100
+++ gcc/testsuite/gcc.dg/torture/pr56443.c      2013-02-25 14:02:25.662541800 
+0100
@@ -0,0 +1,29 @@
+/* PR tree-optimization/56443 */
+/* { dg-do run } */
+/* { dg-options "-ftree-vectorize" } */
+
+extern void abort (void);
+typedef int myint __attribute__ ((__aligned__ (16)));
+
+int a1[1024] __attribute__ ((__aligned__ (16)));
+int a2[1024] __attribute__ ((__aligned__ (16)));
+
+__attribute__((noinline, noclone)) void
+test (int n, myint * __restrict__ p1, myint * __restrict__ p2)
+{
+  while (n--)
+    *p1++ = *p2++ + 1;
+}
+
+int
+main ()
+{
+  int n;
+  for (n = 0; n < 1024; n++)
+    a2[n] = n;
+  test (1024, a1, a2);
+  for (n = 0; n < 1024; n++)
+    if (a1[n] != a2[n] + 1)
+      abort ();
+  return 0;
+}

        Jakub

Reply via email to