middle-end/5840: inline asm: register output parameter overlaps with indirect output parameter

Valentin Nechayev netch@netch.kiev.ua
Tue Mar 5 09:26:00 GMT 2002

>Number:         5840
>Category:       middle-end
>Synopsis:       inline asm: register output parameter overlaps with indirect output parameter
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 05 09:26:01 PST 2002
>Originator:     Valentin Nechayev
>Release:        2.95.3,

The problem is of inline assembler on i386 architecture.

This was reproduced on variety of 2.95.3 and 2.7.2.x packages of gcc
from a bunch of platforms. Details on this gcc packages are listed below.
2.95.3 today from GCC main ftp also shows it.

I failed to reproduce it on: 3.0.2 from FreeBSD port (ports/lang/gcc30,
also on: 2.91.66 from RedHat 6.2;
also on: 2.96 20000731 from RedHat 7.1 (package gcc-2.96-85)


The problem is shown on the bench-test example.

For input file sbb6.c:

=== begin sbb6.c ===
void m_sbb( int* pnc, int* pd, int* pnf, int a, int b, int c )
      "mov %5,%%edi\n\t"
      "shr %%edi\n\t"
      "sbb %4,%0\n\t"
      "setc %b1\n\t"
      "movzbl %b1,%1\n\t"
      "popl %2"
      : "=r" ( *pd ), "=q" ( *pnc ), "=g" ( *pnf )
      : "0" ( a ), "g" ( b ), "g" ( c ) : "cc","edi" );
=== end sbb6.c ===

and for gcc 2.95.3, the command `gcc -fverbose-asm -g -S sbb6.c' produces
assembly file which contains:

=== cut sbb6.s ===
        mov 28(%ebp),%edi
        shr %edi
        sbb 24(%ebp),%edx
        setc %al
        movzbl %al,%eax
        popl (%eax)
=== end cut ===

One can see that %2 is `(%eax)', %1 is `%eax', and they overlaps.
With optimization level >=1, the effect disappears. Example of correct
code, with the same options as above, but with -O added:

=== cut sbb6.s.o1 ===
        mov 28(%ebp),%edi
        shr %edi
        sbb 24(%ebp),%eax
        setc %dl
        movzbl %dl,%edx
        popl (%ecx)
=== end cut ===

These results for 2.95.3 are identical for all tested versions of it.

On the other side, with and, the effect appears only
with non-zero optimization level with the following result:

=== cut sbb6.s ===
        mov %eax,%edi
        shr %edi
        sbb %edx,%ecx
        setc %bl
        movzbl %bl,%ebx
        popl (%ebx)
=== end cut ===

(command was: `gcc -fverbose-asm -g -S sbb6.c')

With -O0, no overlapping occurs.


See source file and commands shown above.

Details on gcc versions where this occurs:

gcc 2.95.3 from GCC main ftp, compiled on FreeBSD 4.4-RELEASE
with commands:

./configure --prefix=/usr/local/gcc/2.95.3
gmake install

and called as: /usr/local/gcc/2.95.3/bin/gcc -fverbose-asm -g -S sbb6.c

for FreeBSD4 versions:

$ gcc -v
Using builtin specs.
gcc version 2.95.3 20010315 (release) [FreeBSD]

this is canonical gcc from FreeBSD installation.

For 2.95.3 from mandrake:

$ gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/specs
gcc version 2.95.3 19991030 (prerelease)

$ rpm -qf /usr/bin/gcc-2.95.2

(Sorry, but no more details for this - I'm not root on this host.)

The same `2.95.3 19991030 (prerelease)' from OpenBSD 2.8-current
shows the same result.

For 2.95.3 from OpenBSD 2.9:

$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-unknown-openbsd2.9/2.95.3/specs
gcc version 2.95.3 20010125 (prerelease)
$ uname -mrs
OpenBSD 2.9 i386

For from FreeBSD 3.3:

$ gcc -v
gcc version

Also this is version from standard FreeBSD installation.

Also on from unidentified Slackware, with the same results
as with


More information about the Gcc-bugs mailing list