From 3122945e76681be8036d7a818310f2c21775d96c Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Fri, 25 Mar 1994 16:12:56 -0500 Subject: [PATCH] (fold, case *_DIV_EXPR): Correct result when product of constants overflows. From-SVN: r6900 --- gcc/fold-const.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 59da9acd258..e2f5fc498c5 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4008,30 +4008,44 @@ fold (expr) tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 1), arg1, 0); /* If it overflows, the result is +/- 1 or zero, depending on - the signs of the two constants and the division operation. */ + the signs of the constants and remaining operand and on which + division operation is being performed. */ + if (TREE_OVERFLOW (tem)) { + /* 1 if C1 * C2 is negative (i.e., C1 and C2 have + different signs). */ + int c_neg = ((tree_int_cst_sgn (arg1) < 0) + == (tree_int_cst_sgn (TREE_OPERAND (arg0, 1)) < 0)); + switch (code) { case EXACT_DIV_EXPR: + /* If this overflowed, it couldn't have been exact. */ + abort (); + case TRUNC_DIV_EXPR: - tem = integer_zero_node; - break; + return omit_one_operand (type, integer_zero_node, + TREE_OPERAND (arg0, 0)); + case FLOOR_DIV_EXPR: - /* -1 if signs disagree, else 0. */ - tem = (((tree_int_cst_sgn (TREE_OPERAND (arg0, 1)) < 0) - != (tree_int_cst_sgn (arg1) < 0)) - ? build_int_2 (-1, -1) : integer_zero_node); - break; + /* -1 or zero, depending on signs of remaining + operand and constants. */ + tem = build (c_neg ? GE_EXPR : LE_EXPR, integer_type_node, + TREE_OPERAND (arg0, 0), + convert (type, integer_zero_node)); + return fold (build (NEGATE_EXPR, type, + convert (type, fold (tem)))); + case CEIL_DIV_EXPR: - /* 1 if signs agree, else 0. */ - tem = (((tree_int_cst_sgn (TREE_OPERAND (arg0, 1)) < 0) - == (tree_int_cst_sgn (arg1) < 0)) - ? integer_one_node : integer_zero_node); - break; + /* Zero or 1, depending on signs of remaining + operand and constants. */ + tem = build (c_neg ? LE_EXPR : GE_EXPR, integer_type_node, + TREE_OPERAND (arg0, 0), + convert (type, integer_zero_node)); + + return convert (type, fold (tem)); } - - return omit_one_operand (type, tem, TREE_OPERAND (arg0, 0)); } else /* If no overflow, divide by C1*C2. */ -- 2.30.2