Subject: port-mips/11292: gcc mips optimizer bug with ffs()
To: None <gnats-bugs@gnats.netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: netbsd-bugs
Date: 10/23/2000 00:51:19
>Number:         11292
>Category:       port-mips
>Synopsis:       gcc mips optimizer bug with ffs()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-mips-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 23 00:51:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Chuck Silvers
>Release:        1.4.2 and later
>Organization:
myself
>Environment:

gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)

and

gcc version egcs-2.91.66 19990314 (egcs-1.1.2 release)


>Description:

the versions of gcc listed above mis-optimize the ffs() function
in certain cases.

compile this test program with and without -O2 and note the different output:

% cat ffs-bug.c
#include <stdio.h>

int a, b, c;

void bug(int *ap, int *bp, int *cp);


void
bug(int *ap, int *bp, int *cp)
{
        *bp = *ap;
        *cp = ffs(*bp);
}

int
main(int argc, char **argv)
{
        a = 8;
        bug(&a, &b, &c);
        printf("%d %d %d\n", a, b, c);
        exit(0);
}

% cc -o ffs-bug ffs-bug.c 
% cc ./ffs-bug 
8 8 4
% cc -O2 -o ffs-bug ffs-bug.c
% ./ffs-bug
8 0 4
% 


dissembling the .o file, we see these instructions for bug():

00000000 <bug>:
...
   c:   8c830000        lw      $v1,0($a0)
  10:   00001021        move    $v0,$zero
  14:   10600004        beqz    $v1,28 <bug+0x28>
  18:   30670001        andi    $a3,$v1,0x1
  1c:   24420001        addiu   $v0,$v0,1
  20:   10e0fffd        beqz    $a3,18 <bug+0x18>
  24:   00031842        srl     $v1,$v1,0x1
  28:   aca30000        sw      $v1,0($a1)
  2c:   03e00008        jr      $ra
  30:   acc20000        sw      $v0,0($a2)


the optimizer has moved the store for "*bp = *ap" after
the inline-expansion of ffs(), which clobbers the register
containing the desired value, so *bp will always be set to zero.


>How-To-Repeat:
	see above example.

>Fix:
	dunno.
>Release-Note:
>Audit-Trail:
>Unformatted: