[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: