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 (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))) || (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; +}