re PR target/40668 (64-bit sparc miscompiles memcpy of argument inside switch)

PR target/40668
	* function.c (assign_parm_setup_stack): Adjust
	MEM_OFFSET (data->stack_parm) if promoted_mode is different
	from nominal_mode on big endian.

	* gcc.c-torture/execute/pr40668.c: New test.

From-SVN: r149512
This commit is contained in:
Jakub Jelinek 2009-07-11 11:26:23 +02:00 committed by Jakub Jelinek
parent 116d3d018a
commit bb068ff507
4 changed files with 58 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2009-07-11 Jakub Jelinek <jakub@redhat.com>
PR target/40668
* function.c (assign_parm_setup_stack): Adjust
MEM_OFFSET (data->stack_parm) if promoted_mode is different
from nominal_mode on big endian.
2009-07-08 Richard Henderson <rth@redhat.com>
PR target/38900

View File

@ -2977,9 +2977,17 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
TYPE_UNSIGNED (TREE_TYPE (parm)));
if (data->stack_parm)
/* ??? This may need a big-endian conversion on sparc64. */
data->stack_parm
= adjust_address (data->stack_parm, data->nominal_mode, 0);
{
int offset = subreg_lowpart_offset (data->nominal_mode,
GET_MODE (data->stack_parm));
/* ??? This may need a big-endian conversion on sparc64. */
data->stack_parm
= adjust_address (data->stack_parm, data->nominal_mode, 0);
if (offset && MEM_OFFSET (data->stack_parm))
set_mem_offset (data->stack_parm,
plus_constant (MEM_OFFSET (data->stack_parm),
offset));
}
}
if (data->entry_parm != data->stack_parm)

View File

@ -1,3 +1,8 @@
2009-07-11 Jakub Jelinek <jakub@redhat.com>
PR target/40668
* gcc.c-torture/execute/pr40668.c: New test.
2009-07-10 Jakub Jelinek <jakub@redhat.com>
PR c++/40502

View File

@ -0,0 +1,35 @@
static void
foo (unsigned int x, void *p)
{
__builtin_memcpy (p, &x, sizeof x);
}
void
bar (int type, void *number)
{
switch (type)
{
case 1:
foo (0x12345678, number);
break;
case 7:
foo (0, number);
break;
case 8:
foo (0, number);
break;
case 9:
foo (0, number);
break;
}
}
int
main (void)
{
unsigned int x;
bar (1, &x);
if (x != 0x12345678)
__builtin_abort ();
return 0;
}