Bug#800321: gcc-5: [mips64el] miscompilation caused by -fexpensive-optimizations

Andreas Cadhalpun <[email protected]>
Newsgroups gmane.linux.debian.ports.mips
Message-ID <56083D37.3010502__43528.2179540538$1443380810$gmane$org@googlemail.com>
Package: gcc-5
Version: 5.2.1-17
Severity: important
Control: affects -1 ffmpeg
X-Debbugs-Cc: [email protected]


Dear Maintainer,

ffmpeg 7:2.8-1 failed to build on mips64el due to a test failure.

I investigated the problem and it turns out to be caused by a compiler bug
that can be avoided by using '-fno-expensive-optimizations'.

Attached is a reduced test case:
$ ls
Makefile  main.c  test.c
$ make
cc -fPIC -O2 -fno-expensive-optimizations -c -o working.o test.c
cc -shared -o libworking.so working.o
cc -o working main.c -L. -lworking
cc -fPIC -O2 -c -o broken.o test.c
cc -shared -o libbroken.so broken.o
cc -o broken main.c -L. -lbroken
LD_LIBRARY_PATH=. ./working || true
A f00000100 101
B f00000100 101
working
LD_LIBRARY_PATH=. ./broken || true
A f00000100 101
broken

In the broken version the '& 0xFFFFFFFF' in following line gets ignored:
    if (*last == ((state | buf) & 0xFFFFFFFF)) 

This also fails with gcc-4.9 and gcc-4.8, so it is a longstanding problem.

Best regards,
Andreas


-- System Information:
Debian Release: stretch/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: mips64el (mips64)

Kernel: Linux 4.2.0-trunk-amd64 (SMP w/4 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)
Shell: /bin/sh linked to /bin/dash
Init: unable to detect

Versions of packages gcc-5 depends on:
ii  binutils      2.25.1-3
ii  cpp-5         5.2.1-17
ii  gcc-5-base    5.2.1-17
ii  libc6         2.19-22
ii  libcc1-0      5.2.1-17
ii  libgcc-5-dev  5.2.1-17
ii  libgcc1       1:5.2.1-17
ii  libgmp10      2:6.0.0+dfsg-7+b1
ii  libisl13      0.14-2+b1
ii  libmpc3       1.0.3-1+b1
ii  libmpfr4      3.1.3-1+b1
ii  libstdc++6    5.2.1-17
ii  zlib1g        1:1.2.8.dfsg-2+b1

Versions of packages gcc-5 recommends:
ii  libc6-dev  2.19-22

Versions of packages gcc-5 suggests:
pn  gcc-5-doc        <none>
pn  gcc-5-locales    <none>
pn  gcc-5-multilib   <none>
pn  libasan2-dbg     <none>
pn  libatomic1-dbg   <none>
pn  libcilkrts5-dbg  <none>
pn  libgcc1-dbg      <none>
pn  libgomp1-dbg     <none>
pn  libitm1-dbg      <none>
pn  liblsan0-dbg     <none>
pn  libmpx0-dbg      <none>
pn  libquadmath-dbg  <none>
pn  libtsan0-dbg     <none>
pn  libubsan0-dbg    <none>

-- no debconf information
main.c (text/x-csrc, 351 B)
#include <inttypes.h>
#include <stdio.h>

int compare(uint64_t state, uint32_t *last, uint8_t buf);

int main(int argc, char **argv)
{
    uint64_t state = 0xF00000100U;
    uint32_t last  = 0x101U;
    int ret        = compare(state, &last, 0x01);
    if (ret == 0)
        printf("working\n");
    else
        printf("broken\n");
    return ret;
}
Makefile (text/plain, 600 B)
CFLAGS += -fPIC -O2
LDFLAGS += -shared

all: working broken
	LD_LIBRARY_PATH=. ./working || true
	LD_LIBRARY_PATH=. ./broken || true

working.o:
	$(CC) $(CFLAGS) -fno-expensive-optimizations -c -o working.o test.c

broken.o:
	$(CC) $(CFLAGS) -c -o broken.o test.c

libworking.so: working.o
	$(CC) $(LDFLAGS) -o libworking.so working.o

libbroken.so: broken.o
	$(CC) $(LDFLAGS) -o libbroken.so broken.o

working: libworking.so
	$(CC) -o working main.c -L. -lworking

broken: libbroken.so
	$(CC) -o broken main.c -L. -lbroken

clean:
	rm -f working.o libworking.so working broken.o libbroken.so broken
test.c (text/x-csrc, 300 B)
#include <inttypes.h>
#include <stdio.h>

int compare(uint64_t state, uint32_t *last, uint8_t buf)
{
    printf("A %"PRIx64" %"PRIx32"\n", state, *last);
    if (*last == ((state | buf) & 0xFFFFFFFF)) {
        printf("B %"PRIx64" %"PRIx32"\n", state, *last);
        return 0;
    }
    return 1;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.