From 4853940ccb7949141793454476b7436c1a431598 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Thu, 9 Feb 2006 14:13:57 +0000 Subject: [PATCH] re PR middle-end/26134 (fold *(float*)(&complex_float_var) into REALPART_EXPR) 2006-02-09 Andrew Pinski PR middle-end/26134 * fold-const.c (fold_indirect_ref_1): Fold "*(foo *)&complexfoo" to "__real__ complexfoo" and "((foo*)&complexfoo)[1]" to "__imag__ complexfoo". 2006-02-09 Andrew Pinski PR middle-end/26134 * gcc.dg/tree-ssa/complex-3.c: New test. From-SVN: r110800 --- gcc/ChangeLog | 7 ++++++ gcc/fold-const.c | 24 ++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/complex-3.c | 27 +++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/complex-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 478de234289..57e720cb9ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-02-09 Andrew Pinski + + PR middle-end/26134 + * fold-const.c (fold_indirect_ref_1): Fold + "*(foo *)&complexfoo" to "__real__ complexfoo" + and "((foo*)&complexfoo)[1]" to "__imag__ complexfoo". + 2006-02-09 Andrew Pinski * tree-flow-inline.h (var_can_have_subvars): diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 01734a62400..833cc4352df 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11721,8 +11721,32 @@ fold_indirect_ref_1 (tree type, tree op0) min_val = TYPE_MIN_VALUE (type_domain); return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE); } + /* *(foo *)&complexfoo => __real__ complexfoo */ + else if (TREE_CODE (optype) == COMPLEX_TYPE + && type == TREE_TYPE (optype)) + return fold_build1 (REALPART_EXPR, type, op); } + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ + if (TREE_CODE (sub) == PLUS_EXPR + && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) + { + tree op00 = TREE_OPERAND (sub, 0); + tree op01 = TREE_OPERAND (sub, 1); + tree op00type; + + STRIP_NOPS (op00); + op00type = TREE_TYPE (op00); + if (TREE_CODE (op00) == ADDR_EXPR + && TREE_CODE (TREE_TYPE (op00type)) == COMPLEX_TYPE + && type == TREE_TYPE (TREE_TYPE (op00type))) + { + tree size = TYPE_SIZE_UNIT (type); + if (tree_int_cst_equal (size, op01)) + return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (op00, 0)); + } + } + /* *(foo *)fooarrptr => (*fooarrptr)[0] */ if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE && type == TREE_TYPE (TREE_TYPE (subtype))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a73cf09490e..dd78250d0ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-02-09 Andrew Pinski + + PR middle-end/26134 + * gcc.dg/tree-ssa/complex-3.c: New test. + 2006-02-09 Andrew Pinski * gcc.c-torture/compile/volatile-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/complex-3.c b/gcc/testsuite/gcc.dg/tree-ssa/complex-3.c new file mode 100644 index 00000000000..5f4b110c6f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/complex-3.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +typedef _Complex float COMPLEX_FLOAT; +float real_part(COMPLEX_FLOAT a) +{ + return *(float*)(&a); +} + +float real_part_2(COMPLEX_FLOAT a) +{ + return ((float*)(&a))[0]; +} + + +float imag_part(COMPLEX_FLOAT a) +{ + return ((float*)(&a))[1]; +} + +/* Test that the above gets optimized to REALPART_EXPR and IMAGPART_EXPR + respectively. */ + +/* { dg-final { scan-tree-dump-times "REALPART_EXPR" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "IMAGPART_EXPR" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + -- 2.30.2