Hi,

I found the following bug in gcc 3.3 and 3.4 with TLS on x86-32. It seems to be
OK with gcc 4.0-4.4. This problem affects the Userspace RCU library
(http://lttng.org/urcu). I am providing a small test case to show the problem.


comp...@compumobile:~/test$ gcc-3.4 -v -save-temps -c -o gccbug-tls.o 
gccbug-tls.c
Reading specs from /usr/lib/gcc/i486-linux-gnu/3.4.6/specs
Configured with: ../src/configure -v --enable-languages=c,f77 --prefix=/usr 
--libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 
--enable-shared --with-system-zlib --enable-nls --without-included-gettext 
--program-suffix=-3.4 --enable-__cxa_atexit --with-tune=i686 i486-linux-gnu
Thread model: posix
gcc version 3.4.6 (Debian 3.4.6-9)
 /usr/lib/gcc/i486-linux-gnu/3.4.6/cc1 -E -quiet -v gccbug-tls.c -mtune=i686 -o 
gccbug-tls.i
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu/3.4.6/include
 /usr/include
End of search list.
 /usr/lib/gcc/i486-linux-gnu/3.4.6/cc1 -fpreprocessed gccbug-tls.i -quiet 
-dumpbase gccbug-tls.c -mtune=i686 -auxbase-strip gccbug-tls.o -version -o 
gccbug-tls.s
GNU C version 3.4.6 (Debian 3.4.6-9) (i486-linux-gnu)
        compiled by GNU C version 3.4.6 (Debian 3.4.6-9).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
gccbug-tls.c: In function `main':
gccbug-tls.c:26: error: unrecognizable insn:
(insn 21 3 22 0 (set (reg/f:SI 70)
        (const:SI (plus:SI (symbol_ref:SI ("data") [flags 0x22] <var_decl 
0xb7390c3c data>)
                (const_int 4 [0x4])))) -1 (nil)
    (nil))
gccbug-tls.c:26: internal compiler error: in extract_insn, at recog.c:2083
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-3.4/README.Bugs>.


Here is the a sample program that generates this error.

<<<begin>>>

extern struct tls_data __thread data;

struct tls_data {
        int val;
        char count;
};

struct tls_data __thread data;

/*
 * Instruct the compiler to perform only a single access to a variable
 * (prohibits merging and refetching). The compiler is also forbidden to reorder
 * successive instances of ACCESS_ONCE(), but only when the compiler is aware of
 * particular ordering. Compiler ordering can be ensured, for example, by
 * putting two ACCESS_ONCE() in separate C statements.
 *
 * This macro does absolutely -nothing- to prevent the CPU from reordering,
 * merging, or refetching absolutely anything at any time.  Its main intended
 * use is to mediate communication between process-level code and irq/NMI
 * handlers, all running on the same CPU.
 */
#define ACCESS_ONCE(x)  (*(volatile typeof(x) *)&(x))

int main(int argc, char **argv)
{
        ACCESS_ONCE(data.count);
        return 0;
}

<<<end>>>

If we remove the "val" field from the structure (hence putting "count" at the
beginning of the structure with a 0 offset), it works fine.

Thanks,

Mathieu


-- 
Mathieu Desnoyers
Operating System Efficiency Consultant
EfficiOS Inc.
http://www.efficios.com

Reply via email to