This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR target/16430
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Jul 2004 16:30:30 +0200
- Subject: 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)