2007-11-12 Richard Guenther PR middle-end/34070 * fold-const.c (fold_binary): If testing for non-negative operands with tree_expr_nonnegative_warnv_p make sure to use op0 which has all (sign) conversions retained. * gcc.c-torture/execute/pr34070-1.c: New testcase. * gcc.c-torture/execute/pr34070-2.c: Likewise. --- gcc/fold-const.c (revision 130097) +++ gcc/fold-const.c (revision 130098) @@ -8509,7 +8509,7 @@ fold_binary (enum tree_code code, tree t /* Simplify A / (B << N) where A and B are positive and B is a power of 2, to A >> (N + log2(B)). */ if (TREE_CODE (arg1) == LSHIFT_EXPR - && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (arg0))) + && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (op0))) { tree sval = TREE_OPERAND (arg1, 0); if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0) @@ -8584,7 +8584,7 @@ fold_binary (enum tree_code code, tree t /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR, i.e. "X % C" into "X & (C - 1)", if X and C are positive. */ if ((code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR) - && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (arg0))) + && (TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (op0))) { tree c = arg1; /* Also optimize A % (C << N) where C is a power of 2, --- gcc/testsuite/gcc.c-torture/execute/pr34070-1.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr34070-1.c (revision 130098) @@ -0,0 +1,13 @@ +extern void abort (void); + +int f(unsigned int x) +{ + return ((int)x) % 4; +} + +int main() +{ + if (f(-1) != -1) + abort (); + return 0; +} --- gcc/testsuite/gcc.c-torture/execute/pr34070-2.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr34070-2.c (revision 130098) @@ -0,0 +1,13 @@ +extern void abort (void); + +int f(unsigned int x, int n) +{ + return ((int)x) / (1 << n); +} + +int main() +{ + if (f(-1, 1) != 0) + abort (); + return 0; +}