This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/20204] New: [4.0 regression] miscompilation of asm-declared registers
- From: "hp at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 25 Feb 2005 00:59:04 -0000
- Subject: [Bug tree-optimization/20204] New: [4.0 regression] miscompilation of asm-declared registers
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Between LAST_UPDATED: "Thu Feb 24 08:05:18 UTC 2005"
and "Thu Feb 24 14:59:24 UTC 2005" I see lots of testsuite regressions.
For GCC, they are (as per Mike Stump's script):
Tests that now fail, but worked before:
21_strings/basic_string/insert/char/2.cc execution test
21_strings/basic_string/replace/char/3.cc execution test
22_locale/money_get/get/char/14.cc execution test
22_locale/money_get/get/char/6.cc execution test
23_containers/vector/check_construct_destroy.cc execution test
23_containers/vector/invalidation/3.cc execution test
25_algorithms/sort.cc execution test
Tests that now fail, but worked before:
gcc.c-torture/execute/20010124-1.c execution, -O0
gcc.c-torture/execute/20010124-1.c execution, -O1
gcc.c-torture/execute/20010124-1.c execution, -O2
gcc.c-torture/execute/20010124-1.c execution, -Os
(also failures in newlib sanity tests).
It seems that the cause is that memmove is miscompiled.
Here's a slightly minimized test-case. Note the use of asm-declared registers:
void *x (void *pdst, const void *psrc, unsigned int pn)
{
register void *return_dst __asm__ ("r10") = pdst;
register unsigned char *dst __asm__ ("r13") = pdst;
register unsigned const char *src __asm__ ("r11") = psrc;
register int n __asm__ ("r12") = pn;
if (src < dst && dst < src + n)
{
src += n;
dst += n;
while (n--)
*--dst = *--src;
return return_dst;
}
while (n >= 16) n--;
return return_dst;
}
extern void abort ();
extern void exit (int);
char xx[30] = "abc";
int main (void)
{
char yy[30] = "aab";
if (x (xx + 1, xx, 2) != xx + 1 || memcmp (xx, yy, sizeof (yy)) != 0)
abort ();
exit (0);
}
The moving while-loop results in this code (pruned;
assembly syntax should be understandable enough knowing that
destinations are to the right):
_x:
cmp.d $r11,$r10
bls .L2
nop
add.d $r12,$r11
cmp.d $r11,$r10
blo .L14
move.d $r10,$r9
.L2:
cmpq 15,$r12
ble .L17
clear.d $r9
subq 15,$r12
addq 1,$r9
.L16:
cmp.d $r9,$r12
bne .L16
addq 1,$r9
.L17:
ret
nop
.L14:
test.d $r12
beq .L17
add.d $r12,$r9
.L10:
subq 1,$r9
subq 1,$r11
move.b [$r11],$r13
cmpq 1,$r12
beq .L17
move.b $r13,[$r9]
subq 1,$r9
subq 1,$r11
move.b [$r11],$r13
cmpq 1,$r12
bne .L10
move.b $r13,[$r9]
ba .L17
nop
.size _x, .-_x
Note the absence of update of R12.
--
Summary: [4.0 regression] miscompilation of asm-declared
registers
Product: gcc
Version: 4.0.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: critical
Priority: P2
Component: tree-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: hp at gcc dot gnu dot org
CC: dnovillo at gcc dot gnu dot org,gcc-bugs at gcc dot gnu
dot org
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: cris-axis-elf
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20204