Bug#813858: gcc-5: [mips] regression: miscompilation caused by -fexpensive-optimizations
Package: gcc-5
Version: 5.3.1-7
Severity: serious
Justification: causes ffmpeg to FTBFS
Control: affects -1 ffmpeg
X-Debbugs-Cc: debian-mips@lists.debian.org
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
#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;
}
}
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
#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])));
}
Reply to: