From 9a10956c4bbf9fd7ff35cc87cea14e6cb6b3812c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 22 Mar 2016 13:23:00 +0000 Subject: [PATCH] re PR target/70333 (Test miscompiled with -O0.) 2016-03-22 Richard Biener PR middle-end/70333 * fold-const.c (extract_muldiv_1): Properly perform multiplication in the wide type. * gcc.dg/torture/pr70333.c: New testcase. From-SVN: r234401 --- gcc/ChangeLog | 6 ++++++ gcc/fold-const.c | 13 ++++++------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr70333.c | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr70333.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 973fdff6807..01f38d02123 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-03-22 Richard Biener + + PR middle-end/70333 + * fold-const.c (extract_muldiv_1): Properly perform multiplication + in the wide type. + 2016-03-22 Kirill Yukhin * config/i386/i386.c (def_builtin): Remove duplicated functionality. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 696b4a6996f..9d861c6847b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6376,18 +6376,17 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, bool overflow_p = false; bool overflow_mul_p; signop sign = TYPE_SIGN (ctype); - wide_int mul = wi::mul (op1, c, sign, &overflow_mul_p); + 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 && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED)) overflow_p = true; if (!overflow_p) - { - mul = wide_int::from (mul, TYPE_PRECISION (ctype), - TYPE_SIGN (TREE_TYPE (op1))); - return fold_build2 (tcode, ctype, fold_convert (ctype, op0), - wide_int_to_tree (ctype, mul)); - } + return fold_build2 (tcode, ctype, fold_convert (ctype, op0), + wide_int_to_tree (ctype, mul)); } /* If these operations "cancel" each other, we have the main diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49f9e080c84..f568f1b784d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-03-22 Richard Biener + + PR middle-end/70333 + * gcc.dg/torture/pr70333.c: New testcase. + 2016-03-22 Ilya Enkovich * g++.dg/ext/pr70290.C: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr70333.c b/gcc/testsuite/gcc.dg/torture/pr70333.c new file mode 100644 index 00000000000..854e6d59e1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr70333.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-require-effective-target lp64 } */ + +unsigned long int +foo (signed char b, signed char e) +{ + return ((2ULL * b) * (e * 13)) * (32 << 24); +} + +int +main () +{ + if (__CHAR_BIT__ == 8 + && sizeof (int) == 4 + && sizeof (long long) == 8 + && foo (-60, 1) != 0xffffff3d00000000ULL) + __builtin_abort (); + return 0; +} -- 2.30.2