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