Commit aae67841 by Richard Kenner

(fold, case *_{DIV,MOD}_EXPR): When using distributive law, take care

when C2 is negative.

From-SVN: r6194
parent a03f67cb
...@@ -3922,7 +3922,7 @@ fold (expr) ...@@ -3922,7 +3922,7 @@ fold (expr)
where C1 % C3 == 0 or C3 % C1 == 0. We can simplify these where C1 % C3 == 0 or C3 % C1 == 0. We can simplify these
expressions, which often appear in the offsets or sizes of expressions, which often appear in the offsets or sizes of
objects with a varying size. Only deal with positive divisors 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. */ Look for NOPs and SAVE_EXPRs inside. */
...@@ -3942,7 +3942,10 @@ fold (expr) ...@@ -3942,7 +3942,10 @@ fold (expr)
&& TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0); c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0);
else if (TREE_CODE (xarg0) == MINUS_EXPR 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))); c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1)));
xarg0 = TREE_OPERAND (xarg0, 0); xarg0 = TREE_OPERAND (xarg0, 0);
...@@ -3959,7 +3962,10 @@ fold (expr) ...@@ -3959,7 +3962,10 @@ fold (expr)
&& (integer_zerop (const_binop (TRUNC_MOD_EXPR, && (integer_zerop (const_binop (TRUNC_MOD_EXPR,
TREE_OPERAND (xarg0, 1), arg1, 1)) TREE_OPERAND (xarg0, 1), arg1, 1))
|| integer_zerop (const_binop (TRUNC_MOD_EXPR, arg1, || 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 outer_div = integer_one_node;
tree c1 = TREE_OPERAND (xarg0, 1); tree c1 = TREE_OPERAND (xarg0, 1);
...@@ -4020,7 +4026,8 @@ fold (expr) ...@@ -4020,7 +4026,8 @@ fold (expr)
&& TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST) && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST)
c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0); c2 = TREE_OPERAND (xarg0, 1), xarg0 = TREE_OPERAND (xarg0, 0);
else if (TREE_CODE (xarg0) == MINUS_EXPR 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))); c2 = fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (xarg0, 1)));
xarg0 = TREE_OPERAND (xarg0, 0); xarg0 = TREE_OPERAND (xarg0, 0);
...@@ -4032,7 +4039,8 @@ fold (expr) ...@@ -4032,7 +4039,8 @@ fold (expr)
&& TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST && TREE_CODE (TREE_OPERAND (xarg0, 1)) == INTEGER_CST
&& integer_zerop (const_binop (TRUNC_MOD_EXPR, && integer_zerop (const_binop (TRUNC_MOD_EXPR,
TREE_OPERAND (xarg0, 1), TREE_OPERAND (xarg0, 1),
arg1, 1))) arg1, 1))
&& tree_int_cst_lt (integer_zero_node, c2))
/* The result is (C2%C3). */ /* The result is (C2%C3). */
return omit_one_operand (type, const_binop (code, c2, arg1, 1), return omit_one_operand (type, const_binop (code, c2, arg1, 1),
TREE_OPERAND (xarg0, 0)); TREE_OPERAND (xarg0, 0));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment