Following testcase (distilled from Fortran test in openmpbench_F_v2): extern __thread double thrtest[81];
int main (void) { int i; for (i = 0; i < 81; i++) thrtest[i] = 1.0; } is miscompiled at -O2 on x86_64: movq [EMAIL PROTECTED](%rip), %rax addq %fs:0, %rax .L2: movabsq $4607182418800017408, %rdx movq %rdx, (%rax) addq $8, %rax cmpq $thrtest+648, %rax jne .L2 rep ; ret Note $thrtest+648 which is wrong for __thread variables. The i386 backend (but it seems other backends as well) legitimize TLS addresses either when LEGITIMIZE_ADDRESS, or when expanding a move (ix86_expand_move). But in this case the middle-end created (const:DI (plus:DI (symbol_ref:DI ("thrtest") [flags 0x58]) (const_int 648))) and passed it to gen_movdi, which doesn't do any legitimization. Adding calls to a legitimization function for TLS addresses to (almost) every expander is certainly not going to work, so I wonder if either expand_expr_addr_expr shouldn't notice addresses of TLS variables and force_reg them, or if general_operand and other routines shouldn't check for this and reject it (which I guess would cause it to be forced to register and therefore ix86_expand_move etc. could do its job). -- Summary: [4.1 regression] TLS miscompilation on x86_64 Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: major Priority: P2 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org GCC target triplet: x86_64-*-linux* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24428