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 <ubiz...@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.
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;