🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #1171

GCC for i386: builtin strcmp not ANSI compliant

#1171
From: Bruno Haible
Date: Wed, 07 Oct 1992 23:48
121 lines
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!haible

Show 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