The following patch fixes PR70450 where I (again...) was not able to decipher wide-int workings in a first try. (the 'sign' op looks redundant for a tree wide_int::from so I was thinking it must apply to the destination to specify eventual zero/sign-extension if the 'precision' arg is not a multiple of HWI bits - appearantly a case that needs to be handled separately - I wonder about lurking bits in other similar users for this case).
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2016-03-30 Richard Biener <rguent...@suse.de> PR middle-end/70450 * fold-const.c (extract_muldiv_1): Fix thinko in wide_int::from usage. * gcc.dg/torture/pr70450.c: New testcase. Index: gcc/fold-const.c =================================================================== *** gcc/fold-const.c (revision 234546) --- gcc/fold-const.c (working copy) *************** extract_muldiv_1 (tree t, tree c, enum t *** 6375,6382 **** bool overflow_mul_p; signop sign = TYPE_SIGN (ctype); unsigned prec = TYPE_PRECISION (ctype); ! wide_int mul = wi::mul (wide_int::from (op1, prec, sign), ! wide_int::from (c, prec, sign), sign, &overflow_mul_p); overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1); if (overflow_mul_p --- 6375,6384 ---- bool overflow_mul_p; signop sign = TYPE_SIGN (ctype); unsigned prec = TYPE_PRECISION (ctype); ! wide_int mul = wi::mul (wide_int::from (op1, prec, ! TYPE_SIGN (TREE_TYPE (op1))), ! wide_int::from (c, prec, ! TYPE_SIGN (TREE_TYPE (c))), sign, &overflow_mul_p); overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1); if (overflow_mul_p Index: gcc/testsuite/gcc.dg/torture/pr70450.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr70450.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr70450.c (working copy) *************** *** 0 **** --- 1,19 ---- + /* { dg-do run } */ + /* { dg-require-effective-target lp64 } */ + + unsigned long int a = 2UL; + int b = 2; + unsigned long int c = 2UL; + + void foo () + { + c = 2 * ((2 * a) * (2 * (-b))); + } + + int main () + { + foo(); + if (c != 18446744073709551584UL) + __builtin_abort(); + return 0; + }