This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/3095: gcc miscompiles __udivdi3 (libgcc2.c) for linux-m68k
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/3095: gcc miscompiles __udivdi3 (libgcc2.c) for linux-m68k
- From: Roman Zippel <zippel at linux-m68k dot org>
- Date: Sat, 09 Jun 2001 01:36:40 +0200
>Number: 3095
>Category: c
>Synopsis: gcc miscompiles __udivdi3 (libgcc2.c) for linux-m68k
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Fri Jun 08 16:46:02 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Roman Zippel
>Release: 3.0 20010606 (prerelease)
>Organization:
>Environment:
System: Linux sodom 2.2.10 #4 Sun Aug 1 14:25:38 CEST 1999 m68k unknown
Architecture: m68k
host: m68k-unknown-linux-gnu
build: m68k-unknown-linux-gnu
target: m68k-unknown-linux-gnu
configured with: ../gcc-3.0/configure --verbose --cache-file=../config.cache --prefix=/usr/local/egcs --enable-languages=c,c++
>Description:
The inline assembly in libgcc2.c is miscompiled, e.g.:
(insn/i 29 149 30 (parallel[
(set (reg/v:SI 42)
(asm_operands:SI ("divu%.l %4,%1:%0") ("=d") 0[
(reg/v:SI 39)
(reg/v:SI 40)
(reg/v:SI 37)
]
[
(asm_input:SI ("0"))
(asm_input:SI ("1"))
(asm_input:SI ("dmi"))
] ("../../gcc-3.0/gcc/libgcc2.c") 532))
(set (reg/v:SI 39)
(asm_operands:SI ("divu%.l %4,%1:%0") ("=d") 1[
(reg/v:SI 39)
(reg/v:SI 40)
(reg/v:SI 37)
]
[
(asm_input:SI ("0"))
(asm_input:SI ("1"))
(asm_input:SI ("dmi"))
] ("../../gcc-3.0/gcc/libgcc2.c") 532))
] ) -1 (nil)
(expr_list:REG_DEAD (reg/v:SI 37)
(expr_list:REG_DEAD (reg/v:SI 40)
(expr_list:REG_UNUSED (reg/v:SI 39)
(nil)))))
becomes after regmove:
(insn/i 29 187 30 (parallel[
(set (reg/v:SI 42)
(asm_operands:SI ("divu%.l %4,%1:%0") ("=d") 0[
(reg/v:SI 42)
(reg/v:SI 40)
(reg/v:SI 37)
]
[
(asm_input:SI ("0"))
(asm_input:SI ("1"))
(asm_input:SI ("dmi"))
] ("../../gcc-3.0/gcc/libgcc2.c") 532))
(set (reg/v:SI 42)
(asm_operands:SI ("divu%.l %4,%1:%0") ("=d") 1[
(reg/v:SI 42)
(reg/v:SI 40)
(reg/v:SI 37)
]
[
(asm_input:SI ("0"))
(asm_input:SI ("1"))
(asm_input:SI ("dmi"))
] ("../../gcc-3.0/gcc/libgcc2.c") 532))
] ) -1 (nil)
(expr_list:REG_DEAD (reg/v:SI 37)
(expr_list:REG_DEAD (reg/v:SI 40)
(nil))))
Register 39 is replaced, although it's still used as input parameter.
In the end the result is put into the wrong register.
>How-To-Repeat:
Configure for linux-m68k and (cross) compile.
Note that the fixes from bootstrap/3090 and c/3092 are needed to get
at least a cross compiler.
>Fix:
Index: gcc/regmove.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/regmove.c,v
retrieving revision 1.96.2.6
diff -u -r1.96.2.6 regmove.c
--- regmove.c 2001/05/14 16:31:46 1.96.2.6
+++ regmove.c 2001/06/08 19:57:56
@@ -1355,7 +1355,8 @@
continue;
}
- if (! (src_note = find_reg_note (insn, REG_DEAD, src)))
+ if (! (src_note = find_reg_note (insn, REG_DEAD, src)) &&
+ ! (src_note = find_reg_note (insn, REG_UNUSED, src)))
{
if (!copy_src)
{
>Release-Note:
>Audit-Trail:
>Unformatted: