Bug#813858: gcc-5: [mips] regression: miscompilation caused by -fexpensive-optimizations
Andreas Cadhalpun <[email protected]>
| Newsgroups | gmane.linux.debian.ports.mips |
|---|---|
| Message-ID | <56B54E8B.2020407__29461.6926381879$1454722958$gmane$org@googlemail.com> |
Package: gcc-5 Version: 5.3.1-7 Severity: serious Justification: causes ffmpeg to FTBFS Control: affects -1 ffmpeg X-Debbugs-Cc: [email protected] Dear Maintainer, ffmpeg 7:2.8.6-1 failed to build on mips due to test failures. I investigated the problem and it turns out to be caused by a compiler bug that can be avoided by using '-fno-expensive-optimizations'. (Somehow this feels like Déjà vu... #800318) Attached is a reduced test case: $ ls Makefile main.c test.c $ make cc -fPIC -g -O2 -fno-expensive-optimizations -c -o working.o test.c cc -shared -o libworking.so working.o cc -fPIC -g -o working main.c -L. -lworking cc -fPIC -g -O2 -c -o broken.o test.c cc -shared -o libbroken.so broken.o cc -fPIC -g -o broken main.c -L. -lbroken LD_LIBRARY_PATH=. ./working || true chunk_size: 11760 working LD_LIBRARY_PATH=. ./broken || true chunk_size: 0 broken This works correctly with gcc-5 5.3.1-6, so it is a regression in 5.3.1-7. The difference between broken.o compiled by 5.3.1-6 and 5.3.1-7 is shown by diffoscope as: ├── objdump --line-numbers --disassemble --section=.text {} │ @@ -17,23 +17,23 @@ │ 18: 24420001 addiu v0,v0,1 │ 1c: 24630001 addiu v1,v1,1 │ 20: aca2000c sw v0,12(a1) │ ./test.c:28 (discriminator 3) │ 24: 1446fffb bne v0,a2,14 <roq_read_packet+0x14> │ 28: a064ffff sb a0,-1(v1) │ ./test.c:32 │ - 2c: 8ba4000a lwl a0,10(sp) │ - 30: 97a2000c lhu v0,12(sp) │ - 34: 9ba4000d lwr a0,13(sp) │ - 38: 7c0210a0 wsbh v0,v0 │ + 2c: 8ba3000a lwl v1,10(sp) │ + 30: 97a4000c lhu a0,12(sp) │ + 34: 9ba3000d lwr v1,13(sp) │ + 38: 7c0420a0 wsbh a0,a0 │ ./test.c:33 │ 3c: 27bd0010 addiu sp,sp,16 │ ./test.c:32 │ - 40: 00021c00 sll v1,v0,0x10 │ - 44: 00041202 srl v0,a0,0x8 │ - 48: 00042602 srl a0,a0,0x18 │ - 4c: 3042ff00 andi v0,v0,0xff00 │ - 50: 00621025 or v0,v1,v0 │ + 40: 3084ffff andi a0,a0,0xffff │ + 44: 00031200 sll v0,v1,0x8 │ + 48: 7c633a00 ext v1,v1,0x8,0x8 │ + 4c: 00431825 or v1,v0,v1 │ + 50: 00031400 sll v0,v1,0x10 │ ./test.c:33 │ 54: 03e00008 jr ra │ 58: 00441025 or v0,v0,a0 │ 5c: 00000000 nop ├── readelf --wide --decompress --string-dump=.comment {} │ @@ -1,4 +1,4 @@ │ │ String dump of section '.comment': │ - [ 1] GCC: (Debian 5.3.1-6) 5.3.1 20160114 │ + [ 1] GCC: (Debian 5.3.1-7) 5.3.1 20160121 │ ╵ I hope that helps to fix this bug soon. Best regards, Andreas -- System Information: Debian Release: stretch/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: mips Kernel: Linux 4.3.0-1-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.26-3 ii cpp-5 5.3.1-7 ii gcc-5-base 5.3.1-7 ii libc6 2.21-7 ii libcc1-0 5.3.1-7 ii libgcc-5-dev 5.3.1-7 ii libgcc1 1:5.3.1-7 ii libgmp10 2:6.1.0+dfsg-2 ii libisl15 0.16.1-1 ii libmpc3 1.0.3-1 ii libmpfr4 3.1.3-2 ii libstdc++6 5.3.1-7 ii zlib1g 1:1.2.8.dfsg-2+b1 Versions of packages gcc-5 recommends: ii libc6-dev 2.21-7 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 libquadmath0-dbg <none> pn libtsan0-dbg <none> pn libubsan0-dbg <none> -- no debconf information
main.c
(text/x-csrc, 1005 B)
#include <inttypes.h>
#include <stdio.h>
typedef struct AVIOContext {
uint8_t a[4];
uint8_t *buffer;
int32_t buffer_size;
uint8_t *buf_ptr;
} AVIOContext;
typedef struct AVFormatContext {
uint8_t a[15];
AVIOContext* pb;
} AVFormatContext;
typedef struct AVPacket {
void *a;
} AVPacket;
int roq_read_packet(AVFormatContext *s, AVPacket *pkt);
int main()
{
AVPacket pkt = { 0 };
AVFormatContext s = { 0 };
AVIOContext pb = { 0 };
uint8_t buffer[32768] = { 0x84, 0x10, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00,
0x21, 0x10, 0xf0, 0x2d, 0x00, 0x00, 0x00, 0x00,
0 };
pb.buffer = buffer;
pb.buffer_size = 32768;
pb.buf_ptr = &buffer[8];
s.pb = &pb;
int chunk_size = roq_read_packet(&s, &pkt);
printf("chunk_size: %u\n", chunk_size);
if (chunk_size == 0x2df0) {
printf("working\n");
return 0;
}
else {
printf("broken\n");
return 1;
}
}
Makefile
(text/plain, 627 B)
CFLAGS += -fPIC -g LDFLAGS += -shared all: working broken LD_LIBRARY_PATH=. ./working || true LD_LIBRARY_PATH=. ./broken || true working.o: $(CC) $(CFLAGS) -O2 -fno-expensive-optimizations -c -o working.o test.c broken.o: $(CC) $(CFLAGS) -O2 -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) $(CFLAGS) -o working main.c -L. -lworking broken: libbroken.so $(CC) $(CFLAGS) -o broken main.c -L. -lbroken clean: rm -f working.o libworking.so working broken.o libbroken.so broken
test.c
(text/x-csrc, 734 B)
#include <inttypes.h>
typedef struct AVIOContext {
uint8_t a[4];
uint8_t *buffer;
int32_t buffer_size;
uint8_t *buf_ptr;
} AVIOContext;
typedef struct AVFormatContext {
uint8_t a[15];
AVIOContext* pb;
} AVFormatContext;
typedef struct AVPacket {
void *a;
} AVPacket;
static uint32_t av_bswap32(uint32_t x)
{
return ((((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) << 16 | ((((x) >> 16) << 8 & 0xff00) | (((x) >> 16) >> 8 & 0x00ff)));
}
int roq_read_packet(AVFormatContext *s, AVPacket *pkt)
{
unsigned char preamble[8];
int i;
for (i = 0; i < 8; i += 1) {
preamble[i] = s->pb->buf_ptr[0];
s->pb->buf_ptr += 1;
}
return av_bswap32(*((uint32_t *) (&preamble[2])));
}