Bug#800321: gcc-5: [mips64el] miscompilation caused by -fexpensive-optimizations
Package: gcc-5
Version: 5.2.1-17
Severity: important
Control: affects -1 ffmpeg
X-Debbugs-Cc: debian-mips@lists.debian.org
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
#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;
}
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
#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;
}
Reply to: