This fixes the easiest case in PR48149 by extending fold to handle COMPLEX_EXPR <REALPART_EXPR <x>, IMAGPART_EXPR <x>>. We have to be careful when the types do not match as fold-convert happily re-constructs a COMPLEX_EXPR of this kind when folding a complex-expr to a slightly different type.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-03-16 Richard Guenther <rguent...@suse.de> PR tree-optimization/48149 * fold-const.c (fold_binary_loc): Fold COMPLEX_EXPR <REALPART_EXPR <x>, IMAGPART_EXPR <x>>. * gcc.dg/fold-complex-1.c: New testcase. Index: gcc/fold-const.c =================================================================== *** gcc/fold-const.c (revision 171047) --- gcc/fold-const.c (working copy) *************** fold_binary_loc (location_t loc, *** 13176,13181 **** --- 13176,13189 ---- || (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)) return build_complex (type, arg0, arg1); + if (TREE_CODE (arg0) == REALPART_EXPR + && TREE_CODE (arg1) == IMAGPART_EXPR + && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg0, 0))) + == TYPE_MAIN_VARIANT (type)) + && operand_equal_p (TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg1, 0), 0)) + return omit_one_operand_loc (loc, type, TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg1, 0)); return NULL_TREE; case ASSERT_EXPR: Index: gcc/testsuite/gcc.dg/fold-complex-1.c =================================================================== *** gcc/testsuite/gcc.dg/fold-complex-1.c (revision 0) --- gcc/testsuite/gcc.dg/fold-complex-1.c (revision 0) *************** *** 0 **** --- 1,11 ---- + /* { dg-do compile } */ + /* { dg-options "-O -ffast-math -fdump-tree-original" } */ + + _Complex float + foo (_Complex float x) + { + return __real x + 1.0iF * __imag x; + } + + /* { dg-final { scan-tree-dump-times "COMPLEX_EXPR" 0 "original" } } */ + /* { dg-final { cleanup-tree-dump "original" } } */