]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/56918 (incorrect auto-vectorization of array initialization)
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Apr 2013 08:18:59 +0000 (10:18 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Apr 2013 08:18:59 +0000 (10:18 +0200)
PR tree-optimization/56918
PR tree-optimization/56920
* fold-const.c (int_const_binop_1): Use op1.mul_with_sign (op2, ...)
instead of op1 - op2.  Pass 2 * TYPE_PRECISION (type) as second
argument to rshift method.  For 2 * HOST_BITS_PER_WIDE_INT precision
use wide_mul_with_sign method.

* gcc.dg/vect/pr56918.c: New test.
* gcc.dg/vect/pr56920.c: New test.

From-SVN: r197846

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr56918.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr56920.c [new file with mode: 0644]

index afcdb109efdd0fb74447514f97efa139ef10f3af..aa332721946e5438ef4a2c6641a805897dbb8e2f 100644 (file)
@@ -1,3 +1,12 @@
+2013-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/56918
+       PR tree-optimization/56920
+       * fold-const.c (int_const_binop_1): Use op1.mul_with_sign (op2, ...)
+       instead of op1 - op2.  Pass 2 * TYPE_PRECISION (type) as second
+       argument to rshift method.  For 2 * HOST_BITS_PER_WIDE_INT precision
+       use wide_mul_with_sign method.
+
 2013-04-12  Richard Biener  <rguenther@suse.de>
 
        * gimple.c (is_gimple_constant): Vector CONSTRUCTORs should
index e8187cbf477af49ad99f6a36a3052c1cf2515b29..59dbc034c4f3c53aa0411597e49fac67f9635437 100644 (file)
@@ -984,12 +984,22 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
       break;
 
     case MULT_HIGHPART_EXPR:
-      /* ??? Need quad precision, or an additional shift operand
-        to the multiply primitive, to handle very large highparts.  */
       if (TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT)
-       return NULL_TREE;
-      tmp = op1 - op2;
-      res = tmp.rshift (TYPE_PRECISION (type), TYPE_PRECISION (type), !uns);
+       {
+         bool dummy_overflow;
+         if (TYPE_PRECISION (type) != 2 * HOST_BITS_PER_WIDE_INT)
+           return NULL_TREE;
+         op1.wide_mul_with_sign (op2, uns, &res, &dummy_overflow);
+       }
+      else
+       {
+         bool dummy_overflow;
+         /* MULT_HIGHPART_EXPR can't ever oveflow, as the multiplication
+            is performed in twice the precision of arguments.  */
+         tmp = op1.mul_with_sign (op2, false, &dummy_overflow);
+         res = tmp.rshift (TYPE_PRECISION (type),
+                           2 * TYPE_PRECISION (type), !uns);
+       }
       break;
 
     case TRUNC_DIV_EXPR:
index bbf27e6bb232cd9c82b42244b5a9d6a12a9c637f..2c8c87872aa0af52b9a3d89e6610631bd0e943d9 100644 (file)
@@ -1,3 +1,10 @@
+2013-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/56918
+       PR tree-optimization/56920
+       * gcc.dg/vect/pr56918.c: New test.
+       * gcc.dg/vect/pr56920.c: New test.
+
 2013-04-12  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/56845
diff --git a/gcc/testsuite/gcc.dg/vect/pr56918.c b/gcc/testsuite/gcc.dg/vect/pr56918.c
new file mode 100644 (file)
index 0000000..581faa0
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR tree-optimization/56918 */
+/* { dg-additional-options "-O3" } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+double data[8];
+
+__attribute__((noinline, noclone)) void
+foo ()
+{
+  int i;
+  for (i = 0; i < 8; ++i)
+    data[i] = ((i + 2) % 3) + 1;
+}
+
+int
+main ()
+{
+  int i;
+  check_vect ();
+  foo ();
+  if (data[0] != 3 || data[7] != 1)
+    abort ();
+  for (i = 1; i < 4; ++i)
+    if (data[i] != i || data[i + 3] != i)
+      abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr56920.c b/gcc/testsuite/gcc.dg/vect/pr56920.c
new file mode 100644 (file)
index 0000000..c6c7cca
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR tree-optimization/56920 */
+/* { dg-additional-options "-O3" } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+
+int
+main ()
+{
+  unsigned int a[15], i;
+  check_vect ();
+  for (i = 0; i < 15; ++i)
+    a[i] = (i * 2) % 15;
+  for (i = 0; i < 15; ++i)
+    if (a[i] != (i * 2) % 15)
+      abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */