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