This is the mail archive of the gcc-patches@gcc.gnu.org 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 PR target/16430


This is an ICE on SPARC 64-bit related to functions returning non-C 
aggregates larger than 16 bytes (i.e. neither structures nor unions), a 
regression from 3.2.x present on the 3.4 branch.  An Ada testcase is:

procedure P is

  type my_array is array (1..6) of Integer;
  A : my_array;

  function Q return my_array is
  begin
    return A;
  end;

begin
  A := Q;
end P;


These aggregates (up to 32 bytes) have always been returned in integer 
registers right-justified.  When I fixed the ABI for unions (which also were 
returned right-justified, whereas the SCD wants them to be returned 
left-justified), I chose not to change the ABI for them (unlike MIPS).  Now 
OImode has vanished since 3.3 so the back-end doesn't find any suitable mode 
for them anymore and ends up generating (reg:BLK).

I'm under the impression resurrecting OImode is out of question, at least on 
the 3.4 branch, so I think the safest fix is to piggyback on the machinery 
used for unions when no mode is found (i.e when 16<size<=32).

Bootstrapped/regtested (3.4 branch) on sparc64-sun-solaris2.9 and 
sparc-sun-solaris2.8.  It also fixes a bunch of C failures on mainline (see 
the thread "aggregate_value_p in the gimplifier" on gcc@).

Applied to mainline and 3.4 branch.


2004-07-08  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR target/16430
	* config/sparc/sparc.c (function_value): In 64-bit mode,
	return the aggregates larger than 16 bytes like unions.


-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.271.4.15
diff -u -p -r1.271.4.15 sparc.c
--- config/sparc/sparc.c	7 Jun 2004 21:03:00 -0000	1.271.4.15
+++ config/sparc/sparc.c	8 Jul 2004 05:38:20 -0000
@@ -5740,6 +5808,18 @@ function_value (tree type, enum machine_
 	    abort ();
 
 	  mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
+
+	  /* ??? We probably should have made the same ABI change in
+	     3.4.0 as the one we made for unions.   The latter was
+	     required by the SCD though, while the former is not
+	     specified, so we favored compatibility and efficiency.
+
+	     Now we're stuck for aggregates larger than 16 bytes,
+	     because OImode vanished in the meantime.  Let's not
+	     try to be unduly clever, and simply follow the ABI
+	     for unions in that case.  */
+	  if (mode == BLKmode)
+	    return function_arg_union_value (bytes, mode, regbase);
 	}
       else if (GET_MODE_CLASS (mode) == MODE_INT
 	       && GET_MODE_SIZE (mode) < UNITS_PER_WORD)

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