ice with gcc 3.1 when optimizing for k6
>Submitter-Id: net
>Originator: Peter Cordes
>Confidential: no
>Synopsis: ice with gcc 3.1 when optimizing for k6
>Severity: serious
>Priority: medium
>Category: target
>Class: ice-on-legal-code
>Release: 3.1.1 20020606 (Debian prerelease) (Debian testing/unstable)
>Environment:
AMD k6-2 CPU. Also reproducable on an Intel P200MMX (still only when
optimizing for k6).
Debian Release: 3.0
Architecture: i386
Kernel: Linux yeti 2.4.18 #1 Thu Apr 4 17:15:43 AST 2002 i586
Locale: LANG=C, LC_CTYPE=C
Debian GNU/Linux, using gcc-3.1 packages, version 3.1.1-0pre2.
Versions of packages gcc-3.1 depends on:
ii binutils 2.12.90.0.9-1 The GNU assembler, linker and bina
ii cpp-3.1 1:3.1.1-0pre2 The GNU C preprocessor.
ii gcc-3.1-base 1:3.1.1-0pre2 The GNU Compiler Collection (base
ii libc6 2.2.5-6 GNU C Library: Shared libraries an
ii libgcc1 1:3.1.1-0pre2 GCC support library.
configured with: /mnt/data/gcc-3.1/gcc-3.1-3.1.1ds1/src/configure -v --enable-languages=c,c++,java,f77,proto,objc,ada --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/g++-v3-3.1 --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --enable-clocale=gnu --enable-threads=posix --enable-java-gc=boehm --enable-objc-gc i386-linux
>Description:
In case it matters, this code is from alsa 0.9.0rc1-2,
pci/trident/trident_memory.c. The preprocessed source was 15000 lines, but
only 100 of them are needed to trigger the bug.
$ gcc-3.1 gcc_bug.c -c -O6 -march=k6
gcc_bug.c: In function snd_trident_synth_bzero':
gcc_bug.c:106: unrecognizable insn:
(insn 238 231 240 (set (reg:SI 99)
(ashift:SI (plus:SI (reg/v:SI 63)
(const_int -1 [0xffffffff]))
(const_int 12 [0xc]))) -1 (insn_list 28 (nil))
(nil))
gcc_bug.c:106: Internal compiler error in extract_insn, at recog.c:2132
>How-To-Repeat:
Compile this code with -O2 -mcpu=k6. -O1 doesn't do it. -mcpu=anything else
doesn't do it either. (-O3 or higher ices too.)
-------------------------------- gcc-bug.c
typedef unsigned int size_t;
static inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep\n\t"
"stosb"
: "=&c" (d0), "=&D" (d1)
:"a" (c),"1" (s),"0" (count)
:"memory");
return s;
}
static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
return s;
case 1:
*(unsigned char *)s = pattern;
return s;
case 2:
*(unsigned short *)s = pattern;
return s;
case 3:
*(unsigned short *)s = pattern;
*(2+(unsigned char *)s) = pattern;
return s;
case 4:
*(unsigned long *)s = pattern;
return s;
}
{
int d0, d1;
switch (count % 4) {
case 0: __asm__ __volatile__( "rep ; stosl" "" : "=&c" (d0), "=&D" (d1) : "a" (pattern),"0" (count/4),"1" ((long) s) : "memory"); return s;
case 1: __asm__ __volatile__( "rep ; stosl" "\n\tstosb" : "=&c" (d0), "=&D" (d1) : "a" (pattern),"0" (count/4),"1" ((long) s) : "memory"); return s;
case 2: __asm__ __volatile__( "rep ; stosl" "\n\tstosw" : "=&c" (d0), "=&D" (d1) : "a" (pattern),"0" (count/4),"1" ((long) s) : "memory"); return s;
default: __asm__ __volatile__( "rep ; stosl" "\n\tstosw\n\tstosb" : "=&c" (d0), "=&D" (d1) : "a" (pattern),"0" (count/4),"1" ((long) s) : "memory"); return s;
}
}
}
static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
"rep ; stosl\n\t"
"testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
"1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
: "=&c" (d0), "=&D" (d1)
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
:"memory");
return (s);
}
typedef struct snd_util_memblk snd_util_memblk_t;
struct snd_util_memblk {
int size;
int offset;
};
typedef struct {
unsigned long * shadow_entries;
} snd_trident_tlb_t;
typedef struct _snd_trident trident_t;
struct _snd_trident {
snd_trident_tlb_t tlb;
};
int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size);
inline static void *offset_ptr(trident_t *trident, int offset)
{
char *ptr;
ptr = (void*)((trident)->tlb.shadow_entries[((offset) >> 12)]);
ptr += offset % (1UL << 12);
return (void*)ptr;
}
int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size)
{
int page, nextofs, end_offset, temp, temp1;
offset += blk->offset;
end_offset = offset + size;
page = ((offset) >> 12) + 1;
do {
nextofs = ((page) << 12);
temp = nextofs - offset;
temp1 = end_offset - offset;
if (temp1 < temp)
temp = temp1;
(__builtin_constant_p(0) ? (__builtin_constant_p((temp)) ? __constant_c_and_count_memset(((offset_ptr(trident, offset))),((0x01010101UL*(unsigned char)(0))),((temp))) : __constant_c_memset(((offset_ptr(trident, offset))),((0x01010101UL*(unsigned char)(0))),((temp)))) : (__builtin_constant_p((temp)) ? __memset_generic((((offset_ptr(trident, offset)))),(((0))),(((temp)))) : __memset_generic(((offset_ptr(trident, offset))),((0)),((temp)))));
offset = nextofs;
page++;
} while (offset < end_offset);
return 0;
}
-----------------------------------------------
>Fix:
gcc-3.0 doesn't ice on this code. I don't know if it actually compiles
it correctly or not. (Other alsa modules compiled with gcc-3.1 seemed to
make my kernel unstable, but that's nothing to do with this.)
--
To UNSUBSCRIBE, email to debian-gcc-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Reply to: