diff mbox

[i386] : Fix PR 58792 by adding missing registers to ix86_function_value_regno_p

Message ID CAFULd4YBbsFjmDeRQfcb=FzWh4HxTfHzUE6u=zGwXTo92WENFQ@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Oct. 19, 2013, 12:55 p.m. UTC
Hello!

The list of possible return registers in ix86_function_value_regno_p
is incomplete.  32bit and 64bit targets use %[er]dx register for
DImode and TImode values respectively and %st(1) and %xmm1 for
imaginary part of complex values. Additionally, 64bit SYSV targets use
%rdi and %rsi registers to pass structures (as declared in
x86_64_int_return_registers array).

function_value_regno_p is mainly used in (obsolete) __builtin_apply
and __builtin_return builtins, but it is also used in mode-switching
pass to check if regno is OK as multiple register value return.

Attached patch fixes PR 58792 by adding missing registers to
function_value_regno_p.

2013-10-19  Uros Bizjak  <ubizjak@gmail.com>

    PR target/58792
    * config/i386/i386.c (ix86_function_value_regno): Add DX_REG,
    ST1_REG and XMM1_REG for 32bit and 64bit targets.  Also add DI_REG
    and SI_REG for 64bit SYSV ABI targets.

The patch was tested on x86_64-pc-linux-gnu {,-m32}, also with
'--with-arch=core-avx-i --with-cpu=core-avx-i --with-fpmath=avx'
configured compiler for  all default languages, plus obj-c++ and go.

I plan to commit the patch to all release branches after a week in mainline.

Patch was committed to mainline, so automatic SPEC testers will pick
it for additional testing.

Uros.

Comments

Uros Bizjak Oct. 19, 2013, 1:04 p.m. UTC | #1
On Sat, Oct 19, 2013 at 2:55 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>
> The list of possible return registers in ix86_function_value_regno_p
> is incomplete.  32bit and 64bit targets use %[er]dx register for
> DImode and TImode values respectively and %st(1) and %xmm1 for
> imaginary part of complex values. Additionally, 64bit SYSV targets use
> %rdi and %rsi registers to pass structures (as declared in
> x86_64_int_return_registers array).
>
> function_value_regno_p is mainly used in (obsolete) __builtin_apply
> and __builtin_return builtins, but it is also used in mode-switching
> pass to check if regno is OK as multiple register value return.
>
> Attached patch fixes PR 58792 by adding missing registers to
> function_value_regno_p.
>
> 2013-10-19  Uros Bizjak  <ubizjak@gmail.com>
>
>     PR target/58792
>     * config/i386/i386.c (ix86_function_value_regno): Add DX_REG,
>     ST1_REG and XMM1_REG for 32bit and 64bit targets.  Also add DI_REG
>     and SI_REG for 64bit SYSV ABI targets.
>
> The patch was tested on x86_64-pc-linux-gnu {,-m32}, also with
> '--with-arch=core-avx-i --with-cpu=core-avx-i --with-fpmath=avx'
> configured compiler for  all default languages, plus obj-c++ and go.
>
> I plan to commit the patch to all release branches after a week in mainline.
>
> Patch was committed to mainline, so automatic SPEC testers will pick
> it for additional testing.

Oh, I forgot to say that I tried to construct a C testcase to be put
in gcc.target/i386, but I was not able to trigger the assert. Since
the problem turned out to be quite obvious and with a  straightforward
fix, I gave up on the testcase.

Uros.
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 203845)
+++ config/i386/i386.c	(working copy)
@@ -7406,9 +7406,15 @@  ix86_function_value_regno_p (const unsigned int re
   switch (regno)
     {
     case AX_REG:
+    case DX_REG:
       return true;
+    case DI_REG:
+    case SI_REG:
+      return TARGET_64BIT && ix86_abi != MS_ABI;
 
-    case FIRST_FLOAT_REG:
+      /* Complex values are returned in %st(0)/%st(1) pair.  */
+    case ST0_REG:
+    case ST1_REG:
       /* TODO: The function should depend on current function ABI but
        builtins.c would need updating then. Therefore we use the
        default ABI.  */
@@ -7416,10 +7422,12 @@  ix86_function_value_regno_p (const unsigned int re
 	return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
-    case FIRST_SSE_REG:
+      /* Complex values are returned in %xmm0/%xmm1 pair.  */
+    case XMM0_REG:
+    case XMM1_REG:
       return TARGET_SSE;
 
-    case FIRST_MMX_REG:
+    case MM0_REG:
       if (TARGET_MACHO || TARGET_64BIT)
 	return false;
       return TARGET_MMX;