On powerpc64-linux, with this testcase

int f (_Complex double a)
{
  extern _Complex double cd;
  return memcmp (&a, &cd, sizeof (a));
}

I'm hitting this assert in expand_expr_addr_expr_1

          /* If the DECL isn't in memory, then the DECL wasn't properly
             marked TREE_ADDRESSABLE, which will be either a front-end
             or a tree optimizer bug.  */
          gcc_assert (GET_CODE (result) == MEM);

The decl rtl is:

(concat:DC (mem/i:DF (reg/f:DI 113 virtual-incoming-args) [0 a+0 S8 A64])
    (reg/v:DF 119 [ a+8 ]))

That's buggy.  We shouldn't have part of the concat in memory, and part
in a reg.  Fixed with:

        * function.c (split_complex_args): Copy TREE_ADDRESSABLE for
        synthetic decl.

With that, we get 

(concat:DC (mem/i:DF (reg/f:DI 113 virtual-incoming-args) [0 a+0 S8 A64])
    (mem/i:DF (plus:DI (reg/f:DI 113 virtual-incoming-args)
            (const_int 8 [0x8])) [0 D.1119+0 S8 A64]))

Now I'm not sure where this should be fixed.  I'm guessing that the hack
I have in my local tree in expand_expr_addr_expr_1 to look inside the
CONCAT isn't the right place to fix this.  Also there's a much worse
problem;  The two pieces of the concat might not be adjacent.  Consider

int g (_Complex float a)
{
  extern _Complex float cf;
  return memcmp (&a, &cf, sizeof (a));
}

For this, the decl rtl is now

(concat:SC (mem/i:SF (reg/f:DI 113 virtual-incoming-args) [0 a+0 S4 A64])
    (mem/i:SF (plus:DI (reg/f:DI 113 virtual-incoming-args)
            (const_int 8 [0x8])) [0 D.1128+0 S4 A64]))

Notice that the two mems are 8 bytes apart but a _Complex float in
memory should have the two 4 byte parts adjacent.


Index: gcc/function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.592
diff -u -p -r1.592 function.c
--- gcc/function.c      1 Dec 2004 18:13:30 -0000       1.592
+++ gcc/function.c      9 Dec 2004 00:48:12 -0000
@@ -2061,6 +2061,7 @@ split_complex_args (tree args)
          /* Build a second synthetic decl.  */
          decl = build_decl (PARM_DECL, NULL_TREE, subtype);
          DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
+         TREE_ADDRESSABLE (decl) = TREE_ADDRESSABLE (p);
          layout_decl (decl, 0);
 
          /* Splice it in; skip the new decl.  */

-- 
           Summary: addressing split complex parm
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: amodra at bigpond dot net dot au
                CC: gcc-bugs at gcc dot gnu dot org
GCC target triplet: powerpc64-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18896

Reply via email to