Commit 23b9463b by Roger Sayle

fold-const.c (fold_comparison): Remove compile-time evaluation of complex…

fold-const.c (fold_comparison): Remove compile-time evaluation of complex constant equality/inequality...


	* fold-const.c (fold_comparison): Remove compile-time evaluation of
	complex constant equality/inequality comparisons for here.
	(fold_binary) <EQ_EXPR>: Simplify complex comparisons that are
	known at compile-time or can be simplified to a scalar comparison.
	(fold_relational_const): Move compile-time evaluation of complex
	constant equality/inequality comparisons to here.

	* gcc.dg/fold-eqcmplx-1.c: New test case.

From-SVN: r122767
parent 99b12b20
2007-03-09 Roger Sayle <roger@eyesopen.com>
* fold-const.c (fold_comparison): Remove compile-time evaluation of
complex constant equality/inequality comparisons for here.
(fold_binary) <EQ_EXPR>: Simplify complex comparisons that are
known at compile-time or can be simplified to a scalar comparison.
(fold_relational_const): Move compile-time evaluation of complex
constant equality/inequality comparisons to here.
2007-03-09 Alexandre Oliva <aoliva@redhat.com> 2007-03-09 Alexandre Oliva <aoliva@redhat.com>
PR rtl-optimization/30643 PR rtl-optimization/30643
...@@ -7,7 +16,8 @@ ...@@ -7,7 +16,8 @@
2007-03-09 DJ Delorie <dj@redhat.com> 2007-03-09 DJ Delorie <dj@redhat.com>
* config/m32c/t-m32c (m32c-pragma.o): Add TM_H dependency to m32c-pragma.o * config/m32c/t-m32c (m32c-pragma.o): Add TM_H dependency to
m32c-pragma.o.
2007-03-09 Aldy Hernandez <aldyh@redhat.com> 2007-03-09 Aldy Hernandez <aldyh@redhat.com>
......
...@@ -8859,29 +8859,6 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8859,29 +8859,6 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
} }
} }
/* If this is a comparison of complex values and both sides
are COMPLEX_CST, do the comparison by parts to fold the
comparison. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
&& TREE_CODE (arg0) == COMPLEX_CST
&& TREE_CODE (arg1) == COMPLEX_CST)
{
tree real0, imag0, real1, imag1;
enum tree_code outercode;
real0 = TREE_REALPART (arg0);
imag0 = TREE_IMAGPART (arg0);
real1 = TREE_REALPART (arg1);
imag1 = TREE_IMAGPART (arg1);
outercode = code == EQ_EXPR ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
return fold_build2 (outercode, type,
fold_build2 (code, type, real0, real1),
fold_build2 (code, type, imag0, imag1));
}
/* Fold a comparison of the address of COMPONENT_REFs with the same /* Fold a comparison of the address of COMPONENT_REFs with the same
type and component to a comparison of the address of the base type and component to a comparison of the address of the base
object. In short, &x->a OP &y->a to x OP y and object. In short, &x->a OP &y->a to x OP y and
...@@ -11621,6 +11598,79 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -11621,6 +11598,79 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
arg01, arg11)), arg01, arg11)),
arg10); arg10);
} }
/* Attempt to simplify equality/inequality comparisons of complex
values. Only lower the comparison if the result is known or
can be simplified to a single scalar comparison. */
if ((TREE_CODE (arg0) == COMPLEX_EXPR
|| TREE_CODE (arg0) == COMPLEX_CST)
&& (TREE_CODE (arg1) == COMPLEX_EXPR
|| TREE_CODE (arg1) == COMPLEX_CST))
{
tree real0, imag0, real1, imag1;
tree rcond, icond;
if (TREE_CODE (arg0) == COMPLEX_EXPR)
{
real0 = TREE_OPERAND (arg0, 0);
imag0 = TREE_OPERAND (arg0, 1);
}
else
{
real0 = TREE_REALPART (arg0);
imag0 = TREE_IMAGPART (arg0);
}
if (TREE_CODE (arg1) == COMPLEX_EXPR)
{
real1 = TREE_OPERAND (arg1, 0);
imag1 = TREE_OPERAND (arg1, 1);
}
else
{
real1 = TREE_REALPART (arg1);
imag1 = TREE_IMAGPART (arg1);
}
rcond = fold_binary (code, type, real0, real1);
if (rcond && TREE_CODE (rcond) == INTEGER_CST)
{
if (integer_zerop (rcond))
{
if (code == EQ_EXPR)
return omit_two_operands (type, boolean_false_node,
imag0, imag1);
return fold_build2 (NE_EXPR, type, imag0, imag1);
}
else
{
if (code == NE_EXPR)
return omit_two_operands (type, boolean_true_node,
imag0, imag1);
return fold_build2 (EQ_EXPR, type, imag0, imag1);
}
}
icond = fold_binary (code, type, imag0, imag1);
if (icond && TREE_CODE (icond) == INTEGER_CST)
{
if (integer_zerop (icond))
{
if (code == EQ_EXPR)
return omit_two_operands (type, boolean_false_node,
real0, real1);
return fold_build2 (NE_EXPR, type, real0, real1);
}
else
{
if (code == NE_EXPR)
return omit_two_operands (type, boolean_true_node,
real0, real1);
return fold_build2 (EQ_EXPR, type, real0, real1);
}
}
}
return NULL_TREE; return NULL_TREE;
case LT_EXPR: case LT_EXPR:
...@@ -13931,6 +13981,23 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) ...@@ -13931,6 +13981,23 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
return constant_boolean_node (real_compare (code, c0, c1), type); return constant_boolean_node (real_compare (code, c0, c1), type);
} }
/* Handle equality/inequality of complex constants. */
if (TREE_CODE (op0) == COMPLEX_CST && TREE_CODE (op1) == COMPLEX_CST)
{
tree rcond = fold_relational_const (code, type,
TREE_REALPART (op0),
TREE_REALPART (op1));
tree icond = fold_relational_const (code, type,
TREE_IMAGPART (op0),
TREE_IMAGPART (op1));
if (code == EQ_EXPR)
return fold_build2 (TRUTH_ANDIF_EXPR, type, rcond, icond);
else if (code == NE_EXPR)
return fold_build2 (TRUTH_ORIF_EXPR, type, rcond, icond);
else
return NULL_TREE;
}
/* From here on we only handle LT, LE, GT, GE, EQ and NE. /* From here on we only handle LT, LE, GT, GE, EQ and NE.
To compute GT, swap the arguments and do LT. To compute GT, swap the arguments and do LT.
......
2007-03-09 Roger Sayle <roger@eyesopen.com>
* gcc.dg/fold-eqcmplx-1.c: New test case.
2007-03-09 Alexandre Oliva <aoliva@redhat.com> 2007-03-09 Alexandre Oliva <aoliva@redhat.com>
PR rtl-optimization/30643 PR rtl-optimization/30643
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-original" } */
int foo(float x, float y)
{
return (_Complex float)x == (_Complex float)y;
}
/* { dg-final { scan-tree-dump-times "x == y" 1 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */
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