Date: Tue, 4 Jun 2002 09:13:37 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: current@freebsd.org Cc: obrien@freebsd.org Subject: memset() broken in gcc-3.1 on i386's Message-ID: <20020604084202.Q939-100000@gamplex.bde.org>
index | next in thread | raw e-mail
gcc now generates inline code for memset in some cases. Broken code.
E.g., compiling the following with -O:
%%%
#include <string.h>
int foo[100];
int x;
main()
{
memset(&foo[0], 0, x);
}
%%%
gives (at least if you have fixed function alignment):
%%%
.file "z.c"
.text
.p2align 2,,3
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %eax
movl x, %ecx
xorl %eax, %eax
shrl $2, %ecx
movl $foo, %edi
cld
rep
stosl
andl $-16, %esp
<-- the lower bits of `len' should be loaded
near here
testl $2, %edi <-- this seems to be meant to test the 2^1
bit in `len' (not alignment of the pointer
like it actually does). %edi is the wrong
register for holding the bits, since it is
still needed for the pointer.
je .L2
stosw
.L2:
testl $1, %edi <-- similarly for the 2^0 bit.
je .L3
stosb
.L3:
movl -4(%ebp), %edi
leave
ret
.Lfe1:
.size main,.Lfe1-main
.comm foo,400,32
.comm x,4,4
.ident "GCC: (GNU) 3.1 [FreeBSD] 20020509 (prerelease)"
%%%
This broke newfs (newfs left some garbage in a bitmap).
This seems to only result in (len % 3) bytes not being cleared, since gcc
doesn't seem to use the builtin memset unless it knows that the pointer is
aligned. If %edi could be misaligned, then too many bytes would be set.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020604084202.Q939-100000>
