This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix x86 sibcall optimization bug.


All,

This testcase fails on X86 mainline because the memcpy call is incorrectly
optimized into a sibcall which results in the wrong value being returned
from foo.

---------------------------------------------------------------------------
extern void exit(int);
extern void abort (void);

extern void * memcpy (void *, const void *, unsigned int);
int foo (void *, void *, unsigned int c);

int src[10];
int dst[10];

int main()
{
   if (foo (dst, src, 10) != 0)
     abort();
   exit(0);
}

int foo (void *a, void *b, unsigned int c)
{
  if (c == 0)
    return 1;

  memcpy (a, b, c);
  return 0;
}
-----------------------------------------------------------------------------

The problem is call_ends_block_p thinks that the CALL_PLACEHOLDER used for the
memcpy call is at the end of its BB which is not true.

(call_insn 57 35 62 (call_placeholder 49 36 0 0 (call_insn 54 53 56 (set (reg:SI 0 eax)
            (call (mem:QI (symbol_ref:SI ("memcpy")) 0)
                (const_int 12 [0xc]))) -1 (nil)
        (expr_list:REG_EH_REGION (const_int 0 [0x0])
            (nil))
        (nil))) -1 (nil)
    (nil)
    (nil))

(insn 62 57 63 (set (reg:SI 58)
        (const_int 0 [0x0])) -1 (nil)
    (nil))

This is because skip_copy_to_return_value thinks that insn 62 is setting the return value
for FOO from the MEMCPY result.

This patch fixes the testcase and the original code miscompiled objdump on x86.

This testcase might also fail on the 3.0.x branch but I don't have enough resources to to find out.

Bootstrapped no regressions x86-linux.

ChangeLog

	*sibcall.c (skip_copy_to_return_value): Tighten return value
	copy check.

-------------------------------------------------------------------
Index: sibcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sibcall.c,v
retrieving revision 1.24
diff -c -p -r1.24 sibcall.c
*** sibcall.c   2001/08/22 14:35:42     1.24
--- sibcall.c   2001/09/09 15:52:37
*************** skip_copy_to_return_value (orig_insn)
*** 159,166 ****

    if (return_value_pseudo)
      {
!       if (SET_DEST (set) == return_value_pseudo)
!         return insn;
        return orig_insn;
      }

--- 159,167 ----

    if (return_value_pseudo)
      {
!       if (SET_DEST (set) == return_value_pseudo
!         && SET_SRC (set) == softret)
!       return insn;
        return orig_insn;
      }

---------------------------------------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]