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

Reply via email to