re PR target/15783 (ICE with union assignment in 64-bit mode)

PR target/15783
	* config/sparc/sparc.c (function_arg_union_value): Add 'mode'
	parameter.  Enumerate the registers inside the PARALLEL.
	(function_arg): Adjust call to function_arg_union_value.
	(function_value): Likewise.

From-SVN: r82722
This commit is contained in:
Eric Botcazou 2004-06-07 22:58:33 +02:00 committed by Eric Botcazou
parent 67057c537b
commit 85bbb21f8f
4 changed files with 59 additions and 23 deletions

View File

@ -1,3 +1,13 @@
2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/15783
* config/sparc/sparc.c (function_arg_union_value): Add 'mode'
parameter. Enumerate the registers inside the PARALLEL.
(function_arg): Adjust call to function_arg_union_value.
(function_value): Likewise.
* config/sparc/sparc.c (sparc_function_epilogue): Properly format.
2004-06-07 Roger Sayle <roger@eyesopen.com>
* real.c (real_copysign): New function to implement libm's copysign.

View File

@ -4514,12 +4514,12 @@ sparc_function_epilogue (FILE *file,
This insn is used in the 32-bit ABI when calling a function that returns
a non zero-sized structure. The 64-bit ABI doesn't have it. Be careful
to have this test be the same as that used on the call. */
sparc_skip_caller_unimp =
! TARGET_ARCH64
&& current_function_returns_struct
&& (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
== INTEGER_CST)
&& ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
sparc_skip_caller_unimp
= ! TARGET_ARCH64
&& current_function_returns_struct
&& (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
== INTEGER_CST)
&& ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
if (current_function_epilogue_delay_list == 0)
{
@ -5129,7 +5129,7 @@ static void function_arg_record_value_2
static void function_arg_record_value_1
(tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
static rtx function_arg_record_value (tree, enum machine_mode, int, int, int);
static rtx function_arg_union_value (int, int);
static rtx function_arg_union_value (int, enum machine_mode, int);
/* A subroutine of function_arg_record_value. Traverse the structure
recursively and determine how many registers will be required. */
@ -5471,26 +5471,25 @@ function_arg_record_value (tree type, enum machine_mode mode,
FUNCTION_ARG and FUNCTION_VALUE.
SIZE is the size in bytes of the union.
MODE is the argument's machine mode.
REGNO is the hard register the union will be passed in. */
static rtx
function_arg_union_value (int size, int regno)
function_arg_union_value (int size, enum machine_mode mode, int regno)
{
enum machine_mode mode;
rtx reg;
if (size <= UNITS_PER_WORD)
mode = word_mode;
else
mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
reg = gen_rtx_REG (mode, regno);
int nwords = ROUND_ADVANCE (size), i;
rtx regs;
/* Unions are passed left-justified. */
return gen_rtx_PARALLEL (mode,
gen_rtvec (1, gen_rtx_EXPR_LIST (VOIDmode,
reg,
const0_rtx)));
regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
for (i = 0; i < nwords; i++)
XVECEXP (regs, 0, i)
= gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (word_mode, regno + i),
GEN_INT (UNITS_PER_WORD * i));
return regs;
}
/* Handle the FUNCTION_ARG macro.
@ -5547,7 +5546,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
if (size > 16)
abort (); /* shouldn't get here */
return function_arg_union_value (size, regno);
return function_arg_union_value (size, mode, regno);
}
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them.
@ -5872,7 +5871,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
if (size > 32)
abort (); /* shouldn't get here */
return function_arg_union_value (size, regbase);
return function_arg_union_value (size, mode, regbase);
}
else if (AGGREGATE_TYPE_P (type))
{

View File

@ -1,3 +1,7 @@
2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/union-1.c: New test.
2004-06-07 Roger Sayle <roger@eyesopen.com>
* gcc.dg/builtins-41.c: New test case.
@ -22718,3 +22722,4 @@ rlsruhe.de>
correspond to c-torture 1.11.
* New file.

View File

@ -0,0 +1,22 @@
/* PR target/15783 */
/* Origin: Paul Pluzhnikov <ppluzhnikov@charter.net> */
/* This used to ICE on SPARC 64-bit because the back-end was
returning an invalid construct for the return value of fu2. */
/* { dg-do compile } */
union u2 {
struct
{
int u2s_a, u2s_b, u2s_c, u2s_d, u2s_e;
} u2_s;
double u2_d;
} u2a;
union u2 fu2();
void unions()
{
u2a = fu2();
}