Commit 99b25753 by Roger Sayle Committed by Roger Sayle

re PR tree-optimization/23452 (Optimizing CONJG_EXPR (a) * a)


	PR tree-optimization/23452
	* fold-const.c (fold_mult_zconjz): New subroutine of fold_binary,
	to optimize z * conj(z) as realpart(z)^2 + imagpart(z)^2.
	(fold_binary) <MULT_EXPR>: Call fold_mult_zconjz for integral
	complex values and with -ffast-math for FP complex values.

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

From-SVN: r114246
parent 606791f6
2006-05-30 Roger Sayle <roger@eyesopen.com>
PR tree-optimization/23452
* fold-const.c (fold_mult_zconjz): New subroutine of fold_binary,
to optimize z * conj(z) as realpart(z)^2 + imagpart(z)^2.
(fold_binary) <MULT_EXPR>: Call fold_mult_zconjz for integral
complex values and with -ffast-math for FP complex values.
2006-05-30 Kazu Hirata <kazu@codesourcery.com> 2006-05-30 Kazu Hirata <kazu@codesourcery.com>
* c-common.h: Remove the prototype for yyparse. * c-common.h: Remove the prototype for yyparse.
......
...@@ -8105,6 +8105,44 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8105,6 +8105,44 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
return NULL_TREE; return NULL_TREE;
} }
/* Subroutine of fold_binary. Optimize complex multiplications of the
form z * conj(z), as pow(realpart(z),2) + pow(imagpart(z),2). The
argument EXPR represents the expression "z" of type TYPE. */
static tree
fold_mult_zconjz (tree type, tree expr)
{
tree itype = TREE_TYPE (type);
tree rpart, ipart, tem;
if (TREE_CODE (expr) == COMPLEX_EXPR)
{
rpart = TREE_OPERAND (expr, 0);
ipart = TREE_OPERAND (expr, 1);
}
else if (TREE_CODE (expr) == COMPLEX_CST)
{
rpart = TREE_REALPART (expr);
ipart = TREE_IMAGPART (expr);
}
else
{
expr = save_expr (expr);
rpart = fold_build1 (REALPART_EXPR, itype, expr);
ipart = fold_build1 (IMAGPART_EXPR, itype, expr);
}
rpart = save_expr (rpart);
ipart = save_expr (ipart);
tem = fold_build2 (PLUS_EXPR, itype,
fold_build2 (MULT_EXPR, itype, rpart, rpart),
fold_build2 (MULT_EXPR, itype, ipart, ipart));
return fold_build2 (COMPLEX_EXPR, type, tem,
fold_convert (itype, integer_zero_node));
}
/* Fold a binary expression of code CODE and type TYPE with operands /* Fold a binary expression of code CODE and type TYPE with operands
OP0 and OP1. Return the folded expression if folding is OP0 and OP1. Return the folded expression if folding is
successful. Otherwise, return NULL_TREE. */ successful. Otherwise, return NULL_TREE. */
...@@ -8768,6 +8806,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8768,6 +8806,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
code, NULL_TREE))) code, NULL_TREE)))
return fold_convert (type, tem); return fold_convert (type, tem);
/* Optimize z * conj(z) for integer complex numbers. */
if (TREE_CODE (arg0) == CONJ_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
return fold_mult_zconjz (type, arg1);
if (TREE_CODE (arg1) == CONJ_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
return fold_mult_zconjz (type, arg0);
} }
else else
{ {
...@@ -8813,6 +8858,18 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8813,6 +8858,18 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
} }
} }
/* Optimize z * conj(z) for floating point complex numbers.
Guarded by flag_unsafe_math_optimizations as non-finite
imaginary components don't produce scalar results. */
if (flag_unsafe_math_optimizations
&& TREE_CODE (arg0) == CONJ_EXPR
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
return fold_mult_zconjz (type, arg1);
if (flag_unsafe_math_optimizations
&& TREE_CODE (arg1) == CONJ_EXPR
&& operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
return fold_mult_zconjz (type, arg0);
if (flag_unsafe_math_optimizations) if (flag_unsafe_math_optimizations)
{ {
enum built_in_function fcode0 = builtin_mathfn_code (arg0); enum built_in_function fcode0 = builtin_mathfn_code (arg0);
......
2006-05-30 Roger Sayle <roger@eyesopen.com>
PR tree-optimization/23452
* gcc.dg/fold-mulconj-1.c: New test case.
2006-05-30 Mark Mitchell <mark@codesourcery.com> 2006-05-30 Mark Mitchell <mark@codesourcery.com>
PR c++/27803 PR c++/27803
/* PR tree-optimization/23452 */
/* { dg-do compile } */
/* { dg-options "-O2 -ffast-math -fdump-tree-gimple" } */
_Complex double foo(_Complex double z)
{
return z * ~z;
}
_Complex int bar(_Complex int z)
{
return z * ~z;
}
/* { dg-final { scan-tree-dump-times "CONJ_EXPR" 0 "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
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