OSDN Git Service

PR tree-optimization/56918
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Apr 2013 08:18:59 +0000 (08:18 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Apr 2013 08:18:59 +0000 (08:18 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197846 138bc75d-0d04-0410-961f-82ee72b054a4

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 afcdb10..aa33272 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 e8187cb..59dbc03 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 bbf27e6..2c8c878 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" } } */