From aae678414b17b8ec35ee8479c4909a7cb43d4195 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Wed, 8 Dec 1993 05:46:16 -0500 Subject: [PATCH] (fold, case *_{DIV,MOD}_EXPR): When using distributive law, take care when C2 is negative. From-SVN: r6194 --- gcc/fold-const.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 27f6baba9219..6821c0635b97 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3922,7 +3922,7 @@ fold (expr) where C1 % C3 == 0 or C3 % C1 == 0. We can simplify these expressions, which often appear in the offsets or sizes of objects with a varying size. Only deal with positive divisors - and multiplicands. + and multiplicands. If C2 is negative, we must have C2 % C3 == 0. Look for NOPs and SAVE_EXPRs inside. */ @@ -3942,7 +3942,10 @@ fold (expr) && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0); else if (TREE_CODE (xarg0) == MINUS_EXPR - && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) + && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST + /* If we are doing this computation unsigned, the negate + is incorrect. */ + && ! TREE_UNSIGNED (type)) { c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1))); xarg0 = TREE_OPERAND (xarg0, 0); @@ -3959,7 +3962,10 @@ fold (expr) && (integer_zerop (const_binop (TRUNC_MOD_EXPR, TREE_OPERAND (xarg0, 1), arg1, 1)) || integer_zerop (const_binop (TRUNC_MOD_EXPR, arg1, - TREE_OPERAND (xarg0, 1), 1)))) + TREE_OPERAND (xarg0, 1), 1))) + && (tree_int_cst_lt (integer_zero_node, c2) + || integer_zerop (const_binop (TRUNC_MOD_EXPR, c2, + arg1, 1)))) { tree outer_div = integer_one_node; tree c1 = TREE_OPERAND (xarg0, 1); @@ -4020,7 +4026,8 @@ fold (expr) && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0); else if (TREE_CODE (xarg0) == MINUS_EXPR - && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) + && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST + && ! TREE_UNSIGNED (type)) { c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1))); xarg0 = TREE_OPERAND (xarg0, 0); @@ -4032,7 +4039,8 @@ fold (expr) && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST && integer_zerop (const_binop (TRUNC_MOD_EXPR, TREE_OPERAND (xarg0, 1), - arg1, 1))) + arg1, 1)) + && tree_int_cst_lt (integer_zero_node, c2)) /* The result is (C2%C3). */ return omit_one_operand (type, const_binop (code, c2, arg1, 1), TREE_OPERAND (xarg0, 0)); -- 2.43.5