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