xfs
[Top] [All Lists]

TAKE - Workaround for gcc 2.96 bug

Subject: TAKE - Workaround for gcc 2.96 bug
From: Keith Owens <kaos@xxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 10 Jan 2002 19:28:17 +1100
Sender: owner-linux-xfs@xxxxxxxxxxx
gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)

breaks on complex expressions involving long long.  Swapping two lines
in xfs_bmap.c works around the broken gcc.

For the record, this test gcc_bug.c file demonstrates the bug.  Note
that it uses the standard do_div from /usr/include/asm/div64.h and not
the xfs version, although both versions of do_div fail with gcc 2.96.
I doubt that it is worth opening a bug with gcc, AFAICT they don't want
to know about 2.96, even the latest "fixed" RedHat version.

#define do_div(n,base) ({ \
        unsigned long __upper, __low, __high, __mod; \
        asm("":"=a" (__low), "=d" (__high):"A" (n)); \
        __upper = __high; \
        if (__high) { \
                __upper = __high % (base); \
                __high = __high / (base); \
        } \
        asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (base), "0" (__low), "1" 
(__upper)); \
        asm("":"=A" (n):"a" (__low),"d" (__high)); \
        __mod; \
})

void gcc_bug(unsigned long long *len_p)
{
        unsigned long long bno;
        unsigned long long len;

        bno = 2000;
        do_div(bno, 12);
        len = *len_p;
        do_div(len, 24);
        printf("%lld %lld\n", bno, len);
}

gcc -O2 gcc_bug.c

gcc_bug.c: In function `gcc_bug':
gcc_bug.c:26: Unrecognizable insn:
(insn 49 149 143 (parallel[ 
            (set (reg:SI 0 eax)
                (asm_operands ("") ("=a") 0[ 
                        (reg:DI 1 edx)
                    ] 
                    [ 
                        (asm_input:DI ("A"))
                    ]  ("gcc_bug.c") 24))
            (set (reg:SI 1 edx)
                (asm_operands ("") ("=d") 1[ 
                        (reg:DI 1 edx)
                    ] 
                    [ 
                        (asm_input:DI ("A"))
                    ]  ("gcc_bug.c") 24))
            (clobber (reg:QI 19 dirflag))
            (clobber (reg:QI 18 fpsr))
            (clobber (reg:QI 17 flags))
        ] ) -1 (insn_list 45 (nil))
    (nil))
gcc_bug.c:26: confused by earlier errors, bailing out


Setting both bno and len before do_div works, i.e.

        bno = 2000;
        len = *len_p;
        do_div(bno, 12);
        do_div(len, 24);


Date:  Thu Jan 10 00:03:03 PST 2002
Workarea:  sherman.melbourne.sgi.com:/build/kaos/2.4.x-xfs

The following file(s) were checked into:
  bonnie.engr.sgi.com:/isms/slinx/2.4.x-xfs


Modid:  2.4.x-xfs:slinx:109353a
linux/fs/xfs/xfs_bmap.c - 1.279


<Prev in Thread] Current Thread [Next in Thread>