From patchwork Tue Feb 26 06:37:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix vectorizer ICE with overaligned types (PR tree-optimization/56443) Date: Mon, 25 Feb 2013 20:37:13 -0000 From: Jakub Jelinek X-Patchwork-Id: 223117 Message-Id: <20130226063713.GX1215@tucnak.zalov.cz> To: Richard Biener Cc: gcc-patches@gcc.gnu.org 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 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. Jakub --- 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; +}