re PR middle-end/26134 (fold *(float*)(&complex_float_var) into REALPART_EXPR<complex...
authorAndrew Pinski <pinskia@physics.uc.edu>
Thu, 9 Feb 2006 14:13:57 +0000 (14:13 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Thu, 9 Feb 2006 14:13:57 +0000 (06:13 -0800)
2006-02-09  Andrew Pinski  <pinskia@physics.uc.edu>

        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  <pinskia@physics.uc.edu>

        PR middle-end/26134
        * gcc.dg/tree-ssa/complex-3.c: New test.

From-SVN: r110800

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/complex-3.c [new file with mode: 0644]

index 478de23428904ff22994476d7baffd2fb4df28ca..57e720cb9ad6d6e6b8caa3c4de912205e5184024 100644 (file)
@@ -1,3 +1,10 @@
+2006-02-09  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       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  <pinskia@physics.uc.edu>
 
        * tree-flow-inline.h (var_can_have_subvars): 
index 01734a624007a0a17aff9991d0edd70b68d2ac04..833cc4352dff5c9f8edc3f49bc4b0630ad610198 100644 (file)
@@ -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)))
index a73cf09490e98828a0621e97c0d4ef36ec6d6521..dd78250d0edce65378d2ffa618a9ba906d40fa29 100644 (file)
@@ -1,3 +1,8 @@
+2006-02-09  Andrew Pinski  <pinskia@physics.uc.edu>
+
+       PR middle-end/26134
+       * gcc.dg/tree-ssa/complex-3.c: New test.
+
 2006-02-09  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * 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 (file)
index 0000000..5f4b110
--- /dev/null
@@ -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" } } */
+