Article View: gnu.gcc.bug
Article #1171GCC for i386: builtin strcmp not ANSI compliant
From: Bruno Haible
Date: Wed, 07 Oct 1992 23:48
Date: Wed, 07 Oct 1992 23:48
121 lines
3156 bytes
3156 bytes
The __builtin_strcmp function that GCC uses for strcmp on i386 when compiling
with -O is not ANSI compliant.
I'm using GCC version 2.2.2d, configured as i386-linux by H.J.Lu.
To be ANSI compliant, strcmp() must compare the characters of the two strings
as if they were unsigned characters. This implies that "abc" is to be
considered `less' than any string beginning with "abc".
The following program tests this.
==================== strcmp.c ================================
#include <string.h>
#include <stdio.h>
main ()
{ printf("%d %d %d %d\n",strcmp("abc","abcx"),
strcmp("abc","abc\376"),
strcmp("abcx","abc"),
strcmp("abc\376","abc")
);
}
===============================================================
When compiled with gcc -O strcmp.c and run, it produces the output
-120 2 120 -2
This reveals incorrect handling of characters with values in the range
128..255.
The assembly code produced by gcc -O -S strcmp.s is the following:
====================== strcmp.s ================================
.file "strcmp.c"
gcc2_compiled.:
.text
LC0:
.ascii "abc\0"
LC1:
.ascii "abc\376\0"
LC2:
.ascii "abcx\0"
LC3:
.ascii "%d %d %d %d\12\0"
.align 2
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
call ___main
movl $LC1,%esi
movl $LC0,%edi
movl $4,%ecx
xorb %al,%al
repe
cmpsb
je L2
movb -1(%esi),%al
subb -1(%edi),%al
L2:
movsbl %al,%eax
pushl %eax
movl $LC2,%esi
movl $LC0,%edi
movl $4,%ecx
xorb %al,%al
repe
cmpsb
je L3
movb -1(%esi),%al
subb -1(%edi),%al
L3:
movsbl %al,%eax
pushl %eax
movl $LC0,%esi
movl $LC1,%edi
movl $4,%ecx
xorb %al,%al
repe
cmpsb
je L4
movb -1(%esi),%al
subb -1(%edi),%al
L4:
movsbl %al,%eax
pushl %eax
movl $LC0,%esi
movl $LC2,%edi
movl $4,%ecx
xorb %al,%al
repe
cmpsb
je L5
movb -1(%esi),%al
subb -1(%edi),%al
L5:
movsbl %al,%eax
pushl %eax
pushl $LC3
call _printf
leal -8(%ebp),%esp
popl %esi
popl %edi
leave
ret
================================================================
Simply subtracting the two last characters is not enough:
movb -1(%esi),%al
subb -1(%edi),%al
They should be zero-extended to some wider format before being subtracted.
These instructions are emitted by the section "memcmp recognizers"
in i386.md.
In any case, compiling strcmp() inline is a VERY advanced optimization.
Congratulations for that work!
Regards,
Bruno Haible
haible@ma2s2.mathematik.uni-karlsruhe.de
Technical Details
Message-ID:
<9210072148.AA18486@ma2s2.mathematik.uni-karlsruhe.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ma2s2.mathematik.uni-karlsruhe.de!haibleShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ma2s2.mathematik.uni-karlsruhe.de!haible From: haible@ma2s2.mathematik.uni-karlsruhe.de (Bruno Haible) Subject: GCC for i386: builtin strcmp not ANSI compliant Message-ID: <9210072148.AA18486@ma2s2.mathematik.uni-karlsruhe.de> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Wed, 7 Oct 1992 23:48:56 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 122