Commit 8ab49fef by Roger Sayle Committed by Roger Sayle

fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy to negate if…

fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy to negate if either operand is easy to negate...


	* fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy
	to negate if either operand is easy to negate, if we don't care
	about sign-dependent rounding.
	(negate_expr): Make the logic to negate a REAL_CST explicit.
	Attempt to negate a MULT_EXPR or RDIV_EXPR by negating an operand
	that's easy to negate, if we don't honor sign-dependent rounding.
	(fold <MULT_EXPR>): Optimize -A * B as A * -B if B is easy to
	negate, and the symmetric A * -B as -A * B if A is easy to negate.
	(fold <RDIV_EXPR>): Likewise, optimize -A/B and C/-D as A/-B and
	-C/D if B and C are cheap to negate.  Add an explicit rule to
	optimize X/-1.0 as -X when we don't care about signaling NaNs.

From-SVN: r70455
parent 74bed51b
2003-08-14 Roger Sayle <roger@eyesopen.com>
* fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy
to negate if either operand is easy to negate, if we don't care
about sign-dependent rounding.
(negate_expr): Make the logic to negate a REAL_CST explicit.
Attempt to negate a MULT_EXPR or RDIV_EXPR by negating an operand
that's easy to negate, if we don't honor sign-dependent rounding.
(fold <MULT_EXPR>): Optimize -A * B as A * -B if B is easy to
negate, and the symmetric A * -B as -A * B if A is easy to negate.
(fold <RDIV_EXPR>): Likewise, optimize -A/B and C/-D as A/-B and
-C/D if B and C are cheap to negate. Add an explicit rule to
optimize X/-1.0 as -X when we don't care about signaling NaNs.
2003-08-14 Zack Weinberg <zack@codesourcery.com> 2003-08-14 Zack Weinberg <zack@codesourcery.com>
* Makefile.in (tm_file): Rename tm_include_list. * Makefile.in (tm_file): Rename tm_include_list.
......
...@@ -847,6 +847,18 @@ negate_expr_p (tree t) ...@@ -847,6 +847,18 @@ negate_expr_p (tree t)
/* We can't turn -(A-B) into B-A when we honor signed zeros. */ /* We can't turn -(A-B) into B-A when we honor signed zeros. */
return ! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations; return ! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations;
case MULT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (t)))
break;
/* Fall through. */
case RDIV_EXPR:
if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
return negate_expr_p (TREE_OPERAND (t, 1))
|| negate_expr_p (TREE_OPERAND (t, 0));
break;
default: default:
break; break;
} }
...@@ -871,13 +883,19 @@ negate_expr (tree t) ...@@ -871,13 +883,19 @@ negate_expr (tree t)
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case INTEGER_CST: case INTEGER_CST:
case REAL_CST:
if (! TREE_UNSIGNED (type) if (! TREE_UNSIGNED (type)
&& 0 != (tem = fold (build1 (NEGATE_EXPR, type, t))) && 0 != (tem = fold (build1 (NEGATE_EXPR, type, t)))
&& ! TREE_OVERFLOW (tem)) && ! TREE_OVERFLOW (tem))
return tem; return tem;
break; break;
case REAL_CST:
tem = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (t)));
/* Two's complement FP formats, such as c4x, may overflow. */
if (! TREE_OVERFLOW (tem))
return convert (type, tem);
break;
case NEGATE_EXPR: case NEGATE_EXPR:
return convert (type, TREE_OPERAND (t, 0)); return convert (type, TREE_OPERAND (t, 0));
...@@ -890,6 +908,30 @@ negate_expr (tree t) ...@@ -890,6 +908,30 @@ negate_expr (tree t)
TREE_OPERAND (t, 0)))); TREE_OPERAND (t, 0))));
break; break;
case MULT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (t)))
break;
/* Fall through. */
case RDIV_EXPR:
if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
{
tem = TREE_OPERAND (t, 1);
if (negate_expr_p (tem))
return convert (type,
fold (build (TREE_CODE (t), TREE_TYPE (t),
TREE_OPERAND (t, 0),
negate_expr (tem))));
tem = TREE_OPERAND (t, 0);
if (negate_expr_p (tem))
return convert (type,
fold (build (TREE_CODE (t), TREE_TYPE (t),
negate_expr (tem),
TREE_OPERAND (t, 1))));
}
break;
default: default:
break; break;
} }
...@@ -5965,8 +6007,13 @@ fold (tree expr) ...@@ -5965,8 +6007,13 @@ fold (tree expr)
case MULT_EXPR: case MULT_EXPR:
/* (-A) * (-B) -> A * B */ /* (-A) * (-B) -> A * B */
if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR) if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
return fold (build (MULT_EXPR, type, TREE_OPERAND (arg0, 0), return fold (build (MULT_EXPR, type,
TREE_OPERAND (arg0, 0),
negate_expr (arg1)));
if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
return fold (build (MULT_EXPR, type,
negate_expr (arg0),
TREE_OPERAND (arg1, 0))); TREE_OPERAND (arg1, 0)));
if (! FLOAT_TYPE_P (type)) if (! FLOAT_TYPE_P (type))
...@@ -6315,8 +6362,13 @@ fold (tree expr) ...@@ -6315,8 +6362,13 @@ fold (tree expr)
return t; return t;
/* (-A) / (-B) -> A / B */ /* (-A) / (-B) -> A / B */
if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR) if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0), return fold (build (RDIV_EXPR, type,
TREE_OPERAND (arg0, 0),
negate_expr (arg1)));
if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
return fold (build (RDIV_EXPR, type,
negate_expr (arg0),
TREE_OPERAND (arg1, 0))); TREE_OPERAND (arg1, 0)));
/* In IEEE floating point, x/1 is not equivalent to x for snans. */ /* In IEEE floating point, x/1 is not equivalent to x for snans. */
...@@ -6324,6 +6376,11 @@ fold (tree expr) ...@@ -6324,6 +6376,11 @@ fold (tree expr)
&& real_onep (arg1)) && real_onep (arg1))
return non_lvalue (convert (type, arg0)); return non_lvalue (convert (type, arg0));
/* In IEEE floating point, x/-1 is not equivalent to -x for snans. */
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
&& real_minus_onep (arg1))
return non_lvalue (convert (type, negate_expr (arg0)));
/* If ARG1 is a constant, we can convert this to a multiply by the /* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal. This does not have the same rounding properties, reciprocal. This does not have the same rounding properties,
so only do this if -funsafe-math-optimizations. We can actually so only do this if -funsafe-math-optimizations. We can actually
......
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