OSDN Git Service

PR rtl-optimization/41646
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Oct 2009 19:01:53 +0000 (19:01 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Oct 2009 19:01:53 +0000 (19:01 +0000)
* calls.c (expand_call): For BLKmode types returned in registers
avoid likely spilled hard regs in copy_blkmode_from_reg generated
insns.

* gcc.c-torture/compile/pr41646.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152597 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr41646.c [new file with mode: 0644]

index ac0fd78..0dfb2d0 100644 (file)
@@ -1,3 +1,10 @@
+2009-10-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/41646
+       * calls.c (expand_call): For BLKmode types returned in registers
+       avoid likely spilled hard regs in copy_blkmode_from_reg generated
+       insns.
+
 2009-10-09  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/41634
index 49e576e..13167a6 100644 (file)
@@ -3020,7 +3020,10 @@ expand_call (tree exp, rtx target, int ignore)
        }
       else if (TYPE_MODE (rettype) == BLKmode)
        {
-         target = copy_blkmode_from_reg (target, valreg, rettype);
+         rtx val = valreg;
+         if (GET_MODE (val) != BLKmode)
+           val = avoid_likely_spilled_reg (val);
+         target = copy_blkmode_from_reg (target, val, rettype);
 
          /* We can not support sibling calls for this case.  */
          sibcall_failure = 1;
index 64e65d7..a151705 100644 (file)
@@ -1,3 +1,8 @@
+2009-10-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/41646
+       * gcc.c-torture/compile/pr41646.c: New test.
+
 2009-10-09  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/41634
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41646.c b/gcc/testsuite/gcc.c-torture/compile/pr41646.c
new file mode 100644 (file)
index 0000000..f07b6ba
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR rtl-optimization/41646 */
+
+struct A { unsigned long a; };
+struct B { unsigned short b, c, d; };
+struct B bar (unsigned long);
+
+char *
+foo (char *a, struct A *x)
+{
+  struct B b = bar (x->a);
+  unsigned char c;
+  unsigned short d;
+  a[3] = ((unsigned char) (b.b % 10) + 48);
+  d = b.b / 10;
+  a[2] = ((unsigned char) (d % 10) + 48);
+  d = d / 10;
+  a[1] = ((unsigned char) (d % 10) + 48);
+  a[0] = ((unsigned char) ((d / 10) % 10) + 48);
+  a[4] = 46;
+  c = (unsigned char) b.c;
+  a[6] = (c % 10 + 48);
+  a[5] = ((c / 10) % 10 + 48);
+  a[7] = 46;
+  c = b.d;
+  a[9] = (c % 10 + 48);
+  a[8] = ((c / 10) % 10 + 48);
+  return a + 10;
+}