]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/61682 (wrong code at -O3 on x86_64-linux-gnu)
authorJakub Jelinek <jakub@redhat.com>
Thu, 3 Jul 2014 22:11:21 +0000 (00:11 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 3 Jul 2014 22:11:21 +0000 (00:11 +0200)
PR tree-optimization/61682
* wide-int.cc (wi::mul_internal): Handle high correctly
for umul_ppmm using cases and when one of the operands is
equal to 1.

* gcc.c-torture/execute/pr61682.c: New test.

From-SVN: r212273

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr61682.c [new file with mode: 0644]
gcc/wide-int.cc

index de5484e59bef5e16ce81eb31581e1673dc327d88..c1a2afb0d29bfdb0e3543d99cc9ba356128f35c7 100644 (file)
@@ -1,3 +1,10 @@
+2014-07-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/61682
+       * wide-int.cc (wi::mul_internal): Handle high correctly
+       for umul_ppmm using cases and when one of the operands is
+       equal to 1.
+
 2014-07-03  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/rs6000.md (rotl<mode>3, ashl<mode>3, lshr<mode>3,
index 50831ebcdbd7298a0e26e01577abc196693ca172..e9cfe2befc83642a36db1ef2367e10e99b457658 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/61682
+       * gcc.c-torture/execute/pr61682.c: New test.
+
 2014-07-03  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * gcc.target/powerpc/shift-dot.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61682.c b/gcc/testsuite/gcc.c-torture/execute/pr61682.c
new file mode 100644 (file)
index 0000000..a5ab29d
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR tree-optimization/61682 */
+
+int a, b;
+static int *c = &b;
+
+int
+main ()
+{
+  int *d = &a;
+  for (a = 0; a < 12; a++)
+    *c |= *d / 9;
+
+  if (b != 1)
+    __builtin_abort ();
+
+  return 0;
+}
index ed7f01bd19e9521e47f7f44c17018dfaff9cc3c7..c33d10ea20d7b7d4e3f36d3b5ce2c528d3ad80aa 100644 (file)
@@ -1,5 +1,5 @@
 /* Operations with very long integers.
-   Copyright (C) 2012-2013 Free Software Foundation, Inc.
+   Copyright (C) 2012-2014 Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
 
 This file is part of GCC.
@@ -1282,6 +1282,12 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val,
          && wi::fits_uhwi_p (op1)
          && wi::fits_uhwi_p (op2))
        {
+         /* This case never overflows.  */
+         if (high)
+           {
+             val[0] = 0;
+             return 1;
+           }
          umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ());
          return 1 + (val[1] != 0 || val[0] < 0);
        }
@@ -1294,6 +1300,8 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val,
          umul_ppmm (upper, val[0], op1.ulow (), op2.ulow ());
          if (needs_overflow)
            *overflow = (upper != 0);
+         if (high)
+           val[0] = upper;
          return 1;
        }
     }
@@ -1302,12 +1310,22 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val,
   /* Handle multiplications by 1.  */
   if (op1 == 1)
     {
+      if (high)
+       {
+         val[0] = wi::neg_p (op2, sgn) ? -1 : 0;
+         return 1;
+       }
       for (i = 0; i < op2len; i++)
        val[i] = op2val[i];
       return op2len;
     }
   if (op2 == 1)
     {
+      if (high)
+       {
+         val[0] = wi::neg_p (op1, sgn) ? -1 : 0;
+         return 1;
+       }
       for (i = 0; i < op1len; i++)
        val[i] = op1val[i];
       return op1len;