Subject: port-mips/11292: gcc mips optimizer bug with ffs()
To: None <>
From: Chuck Silvers <>
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
>Originator:     Chuck Silvers
>Release:        1.4.2 and later

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


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


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);

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

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

% 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.

	see above example.