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 <rguent...@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 <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)