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: r149511
This commit is contained in:
Jakub Jelinek 2009-07-11 11:23:32 +02:00 committed by Jakub Jelinek
parent e9edda2372
commit dd67163fa4
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-11 Paolo Bonzini <bonzini@gnu.org>
* expmed.c (emit_store_flag_1): Fix choice of zero vs. sign extension.

View File

@ -2976,9 +2976,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-11 Paolo Bonzini <bonzini@gnu.org>
* gcc.c-torture/execute/20090711-1.c: New test.

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;
}