[Bug c/28362] New: Invalid code e.g. for ALSA kernel driver

enrico dot scholz at informatik dot tu-chemnitz dot de gcc-bugzilla@gcc.gnu.org
Wed Jul 12 16:54:00 GMT 2006


gcc creates invalid code for

------
struct snd_mask {
    unsigned int bits[6];       // ****** (1) *******
};

static int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v)
{
  struct snd_mask old;

  old = *mask;
  if (mask->bits[0]==0 && mask->bits[1]==0)
    *(char *)0 = 0;

  return mask->bits[0] == old.bits[0] ? 0 : 1;
}

static int test(struct snd_mask *a, struct snd_mask *b)
{
  return snd_mask_refine(a, b);
}

int main(int argc, char *argv[])
{
  int volatile    v    = 0;
  struct snd_mask mask;
  struct snd_mask m;


  mask.bits[0] = 23;
  mask.bits[1] = 42;
  mask.bits[2] = 0;
  mask.bits[3] = 0;
  mask.bits[4] = 0;             // ****** (2) ********
  mask.bits[5] = 0;

  m.bits[0] = 0xffffffff;
  m.bits[1] = 0xffffffff;
  m.bits[2] = 0xffffffff;
  m.bits[3] = 0xffffffff;
  m.bits[4] = 0xffffffff;
  m.bits[5] = 0xffffffff;

  return !v ? test(&mask, &m) : test(&m, &mask);
}
------

| $ arm-xscale-linux-gnu-gcc -Os ./test.c
| $ ./a.out
| Segmentation fault



When changing parameters things are fine; e.g.

| $ arm-xscale-linux-gnu-gcc -O0 ./test.c
| $ ./a.out
| $


Affecting parameters are:

* assigning '1' instead of '0' at (2)
* the array size at (1); e.g. 5 instead of 6 makes it work as expected
* optimization flags; e.g. '-O0' or '-O3' makes it work
* platform; can not reproduce it on non-arm compilers,


The code gnerated by '-Os' is

| 000080a0 <test>:
|     80a0:       e52de004        str     lr, [sp, #-4]!
|     80a4:       e24dd018        sub     sp, sp, #24     ; 0x18
|     80a8:       e1a0c00d        mov     ip, sp
|     80ac:       e1a0e000        mov     lr, r0
|     80b0:       e8be000f        ldmia   lr!, {r0, r1, r2, r3}
|     80b4:       e8ac000f        stmia   ip!, {r0, r1, r2, r3}
|     80b8:       e89e0003        ldmia   lr, {r0, r1}
|     80bc:       e2503000        subs    r3, r0, #0      ; 0x0
|     80c0:       e88c0003        stmia   ip, {r0, r1}
|     80c4:       e59d2000        ldr     r2, [sp]
|     80c8:       1a000001        bne     80d4 <test+0x34>
|     80cc:       e3510000        cmp     r1, #0  ; 0x0
|     80d0:       05c33000        streqb  r3, [r3]
|     80d4:       e0530002        subs    r0, r3, r2
|     80d8:       13a00001        movne   r0, #1  ; 0x1
|     80dc:       e28dd018        add     sp, sp, #24     ; 0x18
|     80e0:       e8bd8000        ldmia   sp!, {pc}


afais:

* 0x80b0 + 0x80b4 copies 'mask[0..3]' to 'old[0..3]'.
* 0x80b8 loads mask[4..5] into {r0,r1}
* now, it uses r0 which contains mask[4] but not mask[0] for comparision
  which is wrong



Bug can be reproduced with


$ $C-gcc-3.4.5 -v
Reading specs from /usr/lib/gcc/arm-xscale-linux-gnu/3.4.5/specs
Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu
--host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu
--with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit
--enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info
--mandir=/usr/share/man --enable-version-specific-runtime-libs
--enable-languages=c,c++ --enable-shared --enable-threads --disable-multilib
--with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer
Thread model: posix
gcc version 3.4.5

$ $C-gcc-4.0.3 -v
Using built-in specs.
Target: arm-xscale-linux-gnu
Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu
--host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu
--with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit
--enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info
--mandir=/usr/share/man --enable-version-specific-runtime-libs
--enable-languages=c --enable-shared --enable-threads --disable-multilib
--with-cpu=xscale --enable-cxx-flags=-mcpu=xscale -fomit-frame-pointer
Thread model: posix
gcc version 4.0.3

$ $C-gcc-4.1.1 -v
Using built-in specs.
Target: arm-xscale-linux-gnu
Configured with: ../configure --prefix=/usr --build=i686-redhat-linux-gnu
--host=i686-redhat-linux-gnu --target=arm-xscale-linux-gnu
--with-sysroot=/usr/arm-xscale-linux-gnu/sys-root --disable-__cxa_atexit
--enable-target-optspace --with-gnu-ld --disable-nls --infodir=/usr/share/info
--mandir=/usr/share/man --enable-version-specific-runtime-libs
--disable-multilib --enable-languages=c,c++,java,objc --enable-shared
--enable-threads --with-cpu=xscale --enable-cxx-flags=-mcpu=xscale
-fomit-frame-pointer
Thread model: posix
gcc version 4.1.1


The assembler code above was created with 4.1.1.

I think this is a major bug.


-- 
           Summary: Invalid code e.g. for ALSA kernel driver
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: enrico dot scholz at informatik dot tu-chemnitz dot de
 GCC build triplet: i386-redhat-linux
  GCC host triplet: i386-redhat-linux
GCC target triplet: arm-xscale-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28362



More information about the Gcc-bugs mailing list