re PR target/40668 (64-bit sparc miscompiles memcpy of argument inside switch)
authorJakub Jelinek <jakub@redhat.com>
Sat, 11 Jul 2009 09:23:32 +0000 (11:23 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 11 Jul 2009 09:23:32 +0000 (11:23 +0200)
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

gcc/ChangeLog
gcc/function.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr40668.c [new file with mode: 0644]

index 3e626352ec126caac5e9cb8ac8f3ee1111198d8a..17bb0cd69628fe8ba982f172f31eabcc3043f718 100644 (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.
index 93244dba76b5e7609080c08ca3a137912d5cddfa..258f59419507b1c62b7dfab1539a9e8f3883af6e 100644 (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)
index 7a477b3b9b62cbf284877909065787560d4036b1..87d57084e95d1aff818571606ea2f84004dd0bcc 100644 (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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr40668.c b/gcc/testsuite/gcc.c-torture/execute/pr40668.c
new file mode 100644 (file)
index 0000000..70fe63f
--- /dev/null
@@ -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;
+}