mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
606791f698
commit
99b25753bb
|
|
@ -1,3 +1,11 @@
|
|||
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>
|
||||
|
||||
* c-common.h: Remove the prototype for yyparse.
|
||||
|
|
|
|||
|
|
@ -8105,6 +8105,44 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
|||
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
|
||||
OP0 and OP1. Return the folded expression if folding is
|
||||
successful. Otherwise, return NULL_TREE. */
|
||||
|
|
@ -8768,6 +8806,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
|||
code, NULL_TREE)))
|
||||
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
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
enum built_in_function fcode0 = builtin_mathfn_code (arg0);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
PR c++/27803
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
/* 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" } } */
|
||||
Loading…
Reference in New Issue