Skip site navigation (1)Skip section navigation (2)
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>