This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
I really had a hard time tracking this down from a large program: gcc 4.0.2 on i386-linux sometimes passes wrong arguments. Please try the attached source file on i386 with "gcc-4.0.2 -march=i386 -O3 -fomit-frame-pointer". When looking at the disassembly of f2() it seems that %edi is incorrectly used twice: 5e: 89 f8 mov %edi,%eax !!!!! 60: ff 74 24 24 pushl 0x24(%esp) 64: 55 push %ebp 65: 89 f9 mov %edi,%ecx !!!!! 67: 89 da mov %ebx,%edx 69: e8 92 ff ff ff call 0 <f1> This wrong-code bug is probably a 3.2, 3.3 and 3.4 regression. ~Markus
Created an attachment (id=10373) [edit] wrong_args.c Please try "gcc-4.0.2 -march=i386 -O3 -fomit-frame-pointer wrong_args.c"
This works at least on the mainline (but I don't know if this is a latent bug or not).
Serious wrong code problem: P1.
// short testcase, compile with "-m32 -march=i386 -O3 -fomit-frame-pointer" extern void abort (void); static int j; static void __attribute__((noinline)) f1 (int a, int b, int c, int d, int e) { j = a; } int __attribute__((noinline)) f2 (int a, int b, int c, int d, int e) { if ((b & 0x1111) != 1) f1 (a, b, c, d, e); return 0; } int main (void) { f2 (123, 0, 0, 0, 0); if (j != 123) abort (); return 0; } --- Note that this bug disappears with -fno-gcse-after-reload, here is difference in generated assembly between -fno-gcse-after-reload (---) and -fgcse-after-reload (+++): $ diff -U 5 1.s 2.s --- 1.s 2005-12-20 12:10:44.000000000 +0300 +++ 2.s 2005-12-20 12:10:41.000000000 +0300 @@ -14,13 +14,13 @@ movl 12(%esp), %ecx movl %edx, %eax andl $4369, %eax decl %eax je .L4 + movl %ecx, %eax pushl 20(%esp) pushl 20(%esp) - movl 12(%esp), %eax call f1 popl %eax popl %edx .L4: xorl %eax, %eax $ So this bug looks very much like bug 23453.
Re. comment #4: but this new PR has a much simpler test case :-)
*** Bug 23453 has been marked as a duplicate of this bug. ***
Does not fail with trunk or the head of the gcc 4.1 branch. But it does fail with gcc 4.0.2. I'm going to try it with the head of the gcc 4.0 branch now.
Gross. According to a comment in postreload.c:move2add_note_store(), we can have pushes without REG_INC notes: /* Some targets do argument pushes without adding REG_INC notes. */ So we need to go look for those {pre,post}{decrements,increments} ourselves. With this patch, we just do what postreload.c does. Index: postreload-gcse.c =================================================================== --- postreload-gcse.c (revision 108853) +++ postreload-gcse.c (working copy) @@ -676,6 +676,17 @@ record_last_set_info (rtx dest, rtx sett /* Ignore pushes, they clobber nothing. */ && ! push_operand (dest, GET_MODE (dest))) record_last_mem_set_info (last_set_insn); + + /* ??? Some targets do argument pushes without adding REG_INC notes. + See e.g. PR25196, where a pushsi2 on i386 doesn't have REG_INC + notes. */ + if (MEM_P (dest)) + { + dest = XEXP (dest, 0); + if (GET_CODE (dest) == PRE_INC || GET_CODE (dest) == POST_INC + || GET_CODE (dest) == PRE_DEC || GET_CODE (dest) == POST_DEC) + record_last_reg_set_info (last_set_insn, REGNO (XEXP (dest, 0))); + } }
Fixed on the trunk and on the GCC 4.1 branch. See http://gcc.gnu.org/ml/gcc-cvs/2005-12/msg01177.html and http://gcc.gnu.org/ml/gcc-cvs/2005-12/msg01178.html (I used the wrong bug number in the commit >:-/) Will ask for permission for the 4.0 branch in a few days.
What is the status of this bug for gcc 4.0.3 ? According to the thread at http://gcc.gnu.org/ml/gcc-patches/2006-01/msg00542.html it seems it has been approved a while ago.
Steven, would you please apply this patch ASAP? Thanks, -- Mark
Subject: Bug 25196 Author: steven Date: Mon Feb 27 21:12:54 2006 New Revision: 111490 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111490 Log: Backport from mainline and the GCC 4.1 branch: PR rtl-optimization/25196 * postreload-gcse.c (record_last_set_info): Notice stack pointer changes in push insns without REG_INC notes. Added: branches/gcc-4_0-branch/gcc/testsuite/gcc.dg/pr25196.c Modified: branches/gcc-4_0-branch/gcc/ChangeLog branches/gcc-4_0-branch/gcc/postreload-gcse.c
'tis done.