From: Richard Guenther Date: Fri, 22 Aug 2008 12:43:49 +0000 (+0000) Subject: re PR middle-end/36548 (remainder gives the wrong result for wrapping case with unsig... X-Git-Tag: releases/gcc-4.4.0~2953 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=beeab17c6ed0733203002932c08d1d3f3fe5d053;p=thirdparty%2Fgcc.git re PR middle-end/36548 (remainder gives the wrong result for wrapping case with unsigned types) 2008-08-22 Richard Guenther PR middle-end/36548 PR middle-end/37125 * fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only if the multiplication does not overflow. * gcc.c-torture/execute/pr37125.c: New testcase. From-SVN: r139450 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f788ef87987e..592b28cd5c8f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-08-22 Richard Guenther + + PR middle-end/36548 + PR middle-end/37125 + * fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only + if the multiplication does not overflow. + 2008-08-21 Nathan Sidwell * c-ppoutput.c (init_pp_output): Initialize src_line to 1. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index cba882675655..e6769a650a88 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5930,9 +5930,20 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, (C * 8) % 4 since we know that's zero. */ if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR) + /* If the multiplication can overflow we cannot optimize this. + ??? Until we can properly mark individual operations as + not overflowing we need to treat sizetype special here as + stor-layout relies on this opimization to make + DECL_FIELD_BIT_OFFSET always a constant. */ + && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)) + || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (TREE_TYPE (t)))) && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0))) - return omit_one_operand (type, integer_zero_node, op0); + { + *strict_overflow_p = true; + return omit_one_operand (type, integer_zero_node, op0); + } /* ... fall through ... */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae16c70a1f35..061c21962fc1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-08-22 Richard Guenther + + PR middle-end/36548 + PR middle-end/37125 + * gcc.c-torture/execute/pr37125.c: New testcase. + 2008-08-22 Daniel Kraft * gfortran.dg/used_before_typed_4.f90: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr37125.c b/gcc/testsuite/gcc.c-torture/execute/pr37125.c new file mode 100644 index 000000000000..f29209eb7aad --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr37125.c @@ -0,0 +1,23 @@ +extern void abort (void); + +static inline unsigned int +mod_rhs(int rhs) +{ + if (rhs == 0) return 1; + return rhs; +} + +void func_44 (unsigned int p_45); +void func_44 (unsigned int p_45) +{ + if (!((p_45 * -9) % mod_rhs (-9))) { + abort(); + } +} + +int main (void) +{ + func_44 (2); + return 0; +} +