This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR78305


On Wed, 16 Nov 2016, Marc Glisse wrote:

> On Wed, 16 Nov 2016, Richard Biener wrote:
> 
> > I am testing the following to avoid undefined behavior when negating
> > a multiplication (basically extending a previous fix to properly handle
> > negative power of two).
> > 
> > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
> > 
> > Richard.
> > 
> > 2016-11-16  Richard Biener  <rguenther@suse.de>
> > 
> > 	PR middle-end/78305
> > 	* fold-const.c (negate_expr_p): Fix multiplication case.
> > 
> > 	* gcc.dg/torture/pr78305.c: New testcase.
> > 
> > Index: gcc/fold-const.c
> > ===================================================================
> > --- gcc/fold-const.c	(revision 242471)
> > +++ gcc/fold-const.c	(working copy)
> > @@ -450,13 +450,15 @@ negate_expr_p (tree t)
> >       if (TYPE_UNSIGNED (type))
> > 	break;
> >       /* INT_MIN/n * n doesn't overflow while negating one operand it does
> > -         if n is a power of two.  */
> > +         if n is a power of (minus) two.  */
> 
> if n is (minus) a power of two.
> if n is a divisor of INT_MIN.

n is a divisor of INT_MIN is correct.

> >       if (INTEGRAL_TYPE_P (TREE_TYPE (t))
> > 	  && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
> > 	  && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
> > -		 && ! integer_pow2p (TREE_OPERAND (t, 0)))
> > +		 && (wi::popcount (TREE_OPERAND (t, 0))
> > +		     != 1 + wi::neg_p (TREE_OPERAND (t, 0), SIGNED)))
> 
> Is that supposed to test for (possibly negated) powers of 2? I don't see it.
> For -2, aka 0b11...110, popcount is 31 != 1 + 1.

It's supposed to test for a power of two with the sign-bit ORed in.
I believe those are which, when multiplied with some number can
yield INT_MIN.  That is, we look for a test that ensures that there
exists no number when multiplied with X yields INT_MIN.

Richard.

> > 		|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
> > -		    && ! integer_pow2p (TREE_OPERAND (t, 1)))))
> > +		    && (wi::popcount (TREE_OPERAND (t, 1))
> > +			!= 1 + wi::neg_p (TREE_OPERAND (t, 1), SIGNED)))))
> > 	break;
> > 
> >       /* Fall through.  */
> > Index: gcc/testsuite/gcc.dg/torture/pr78305.c
> > ===================================================================
> > --- gcc/testsuite/gcc.dg/torture/pr78305.c	(revision 0)
> > +++ gcc/testsuite/gcc.dg/torture/pr78305.c	(working copy)
> > @@ -0,0 +1,14 @@
> > +/* { dg-require-effective-target int32plus } */
> > +/* { dg-do run } */
> > +
> > +int main ()
> > +{
> > +  int a = 2;
> > +  int b = 1;
> > +
> > +  int t = -1 * ( -0x40000000 * a / ( -0x20000000 + b ) )  / -1;
> > +
> > +  if (t != 4) __builtin_abort();
> > +
> > +  return 0;
> > +}
> > 
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]