This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR18896, addressing split complex args

This fixes an ICE on mainline powerpc64-linux caused by an unexpected
concat, and other problems related to addressing split complex function
parameters.  See the PR for all the gory details.

I've done things a little differently than Richard suggested, mostly
because I was working on this patch before he said anything..  Instead
of making both real and imag parts go into pseudos, I've allowed the
normal param assignment to take place for the real part, and just set
DECL_ARTIFICIAL on the imag part to force it into a pseudo (which we
ingore).  Later, assign_parms_unsplit_complex pokes the imag part into
mem from DECL_INCOMING_RTL.  This seems to work well with various
testcases I tried.

	PR target/18896
	* function.c (split_complex_args): DECL_ARTIFICIAL for the imaginary
	part if the real part is addressable.
	(assign_parms_unsplit_complex): If addressable, save imaginary part
	and set decl rtl to a mem that covers both real and imag parts.

powerpc64-linux bootstrap and regression test nearly completed.  OK
mainline assuming no regressions?

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 12:23:21 -0000
@@ -2061,6 +2061,11 @@ 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);
+	  /* If the real part must go in memory, make the imag part go
+	     in a pseudo.  We don't want the imag part to go in memory
+	     as per normal parms, because the usual place might not be
+	     immediately adjacent to the real part.  */
 	  layout_decl (decl, 0);
 	  /* Splice it in; skip the new decl.  */
@@ -2987,7 +2992,24 @@ assign_parms_unsplit_complex (tree orig_
 	      real = gen_lowpart_SUBREG (inner, real);
 	      imag = gen_lowpart_SUBREG (inner, imag);
-	  tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
+	  if (TREE_ADDRESSABLE (parm))
+	    {
+	      rtx in, imem;
+	      /* split_complex_arg put the imag part in a pseudo.  Move
+		 it to memory adjacent to the real part.  */
+	      gcc_assert (MEM_P (real));
+	      imem = adjust_address_nv (real, VOIDmode, GET_MODE_SIZE (inner));
+	      in = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
+	      if (inner != GET_MODE (in))
+		in = gen_lowpart_SUBREG (inner, in);
+	      if (!rtx_equal_p (imem, in))
+		emit_move_insn (imem, in);
+	      tmp = adjust_address_nv (real, DECL_MODE (parm), 0);
+	    }
+	  else
+	    tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
 	  SET_DECL_RTL (parm, tmp);
 	  real = DECL_INCOMING_RTL (fnargs);

Alan Modra
IBM OzLabs - Linux Technology Centre

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]