diff mbox

Fix high handling in wi::mul_internal (PR tree-optimization/61682)

Message ID 20140703184222.GK31640@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 3, 2014, 6:42 p.m. UTC
Hi!

Several places in wi::mul_internal didn't handle high parameter
and would return the low bits instead of high bits.

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

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.

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


	Jakub

Comments

Richard Sandiford July 3, 2014, 9:53 p.m. UTC | #1
Jakub Jelinek <jakub@redhat.com> writes:
> @@ -1302,12 +1310,28 @@ wi::mul_internal (HOST_WIDE_INT *val, co
>    /* Handle multiplications by 1.  */
>    if (op1 == 1)
>      {
> +      if (high)
> +	{
> +	  if (sgn == SIGNED && wi::neg_p (op2))
> +	    val[0] = -1;
> +	  else
> +	    val[0] = 0;
> +	  return 1;
> +	}
>        for (i = 0; i < op2len; i++)
>  	val[i] = op2val[i];
>        return op2len;
>      }
>    if (op2 == 1)
>      {
> +      if (high)
> +	{
> +	  if (sgn == SIGNED && wi::neg_p (op1))
> +	    val[0] = -1;
> +	  else
> +	    val[0] = 0;
> +	  return 1;
> +	}
>        for (i = 0; i < op1len; i++)
>  	val[i] = op1val[i];
>        return op1len;

I think the preferred way of writing this is "wi::neg_p (op1, sgn)"
OK otherwise, thanks, and sorry for the multiple breakage.

Richard
Mike Stump July 3, 2014, 10:09 p.m. UTC | #2
On Jul 3, 2014, at 2:53 PM, Richard Sandiford <rdsandiford@googlemail.com> wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
>> 
>> +	  if (sgn == SIGNED && wi::neg_p (op1))
> 
> I think the preferred way of writing this is "wi::neg_p (op1, svn)"

Yes.
diff mbox

Patch

--- gcc/wide-int.cc.jj	2014-05-30 10:51:11.000000000 +0200
+++ gcc/wide-int.cc	2014-07-03 09:35:11.084228924 +0200
@@ -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, co
 	  && 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, co
 	  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,28 @@  wi::mul_internal (HOST_WIDE_INT *val, co
   /* Handle multiplications by 1.  */
   if (op1 == 1)
     {
+      if (high)
+	{
+	  if (sgn == SIGNED && wi::neg_p (op2))
+	    val[0] = -1;
+	  else
+	    val[0] = 0;
+	  return 1;
+	}
       for (i = 0; i < op2len; i++)
 	val[i] = op2val[i];
       return op2len;
     }
   if (op2 == 1)
     {
+      if (high)
+	{
+	  if (sgn == SIGNED && wi::neg_p (op1))
+	    val[0] = -1;
+	  else
+	    val[0] = 0;
+	  return 1;
+	}
       for (i = 0; i < op1len; i++)
 	val[i] = op1val[i];
       return op1len;
--- gcc/testsuite/gcc.c-torture/execute/pr61682.c.jj	2014-03-19 15:57:57.735114622 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr61682.c	2014-07-03 09:40:26.215520476 +0200
@@ -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;
+}