Bug 29198 - [4.0 Regression] Incorrect reference to __thread array with -fPIC -O2 on x86
Summary: [4.0 Regression] Incorrect reference to __thread array with -fPIC -O2 on x86
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.0
: P2 normal
Target Milestone: 4.0.4
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2006-09-24 05:21 UTC by Ian Lance Taylor
Modified: 2007-02-03 20:22 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0 4.1.2 4.2.0
Known to fail: 4.0.0 4.1.0 4.1.1
Last reconfirmed: 2006-09-29 11:29:51


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Lance Taylor 2006-09-24 05:21:48 UTC
I compiled this C code with current mainline with -fPIC -O2 on x86 GNU/Linux:

extern int f2 (int, int, int, int);
struct s { char b[4]; };
__thread struct s a[2];
void f1 (int a1, int a2)
{
  int i, j;
  for (i = 0; i < 4; i++)
    {
      int tot = 0;
      for (j = 0; j < 4; j++)
	tot += f2 (a1, a2, i, j);
      a[0].b[i] = tot;
    }
 }

The resulting assembler file had this in it:

	movl	a@GOT(%ebx), %ecx

But a is declared with __thread.  This should instead be something like:

	leal	a@TLSGD(,%ebx,1), %eax
	call	___tls_get_addr@PLT

In the real code there are other references to a, which leads to a linker error:

`a' accessed both as normal and thread local symbol

I believe the bug is in legitimize_address or in legitimize_pic_address in config/i386/i386.c.  legitimize_address gets called with

(plus:SI (reg/v:SI 64 [ i ])
    (symbol_ref:SI ("a") [flags 0x8] <var_decl 0xb7c630b0 a>))

When it sees a symbol as the right-hand operand of a PLUS, it calls legitimize_pic_address.  That returns an UNSPEC_GOT.  Somewhere along the way, it needs to call legitimize_tls_address.
Comment 1 Andrew Pinski 2006-09-24 05:29:30 UTC
Confirmed, this testcase worked in 3.4.0 but that might just mean this is a latent bug.
Comment 2 Andrew Pinski 2006-09-24 05:31:32 UTC
I should note that -fno-ivopts causes to produce the correct result for this testcase.  I am going to try to find a testcase that fails even with 3.4.0.
Comment 3 Andrew Pinski 2006-09-24 05:34:04 UTC
Here is a testcase which shows this is a latent bug:
extern int f2 (int, int, int, int);
struct s { char b[4]; };
__thread struct s a[2];
void f1 (int a1, int a2)
{
  int i, j;
  for (i = 0; i < 4; i++)
    {
      int tot = 0;
      for (j = 0; j < 4; j++)
        tot += f2 (a1, a2, i, j);
      *(&a[0].b[0] + i) = tot;
    }
 }


------
But since the orginal testcase worked in 3.4.0, this should be still marked as a regression, IV-OPTs is causing the latent bug to show up.
Comment 4 Mark Mitchell 2006-10-01 22:59:02 UTC
I'm marking this P2, rather than P1, because the use of TLS structures seems a bit of a corner-case.  Feel free to lobby to make this a P1.
Comment 5 Jakub Jelinek 2006-10-06 07:25:12 UTC
Subject: Bug 29198

Author: jakub
Date: Fri Oct  6 07:25:02 2006
New Revision: 117483

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117483
Log:
	PR target/29198
	* config/i386/i386.c (legitimize_pic_address): Reject TLS symbols.
	* config/i386/predicates.md (local_symbolic_operand): Likewise.

	* gcc.dg/tls/opt-12.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/tls/opt-12.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/config/i386/predicates.md
    trunk/gcc/testsuite/ChangeLog

Comment 6 Jakub Jelinek 2006-10-06 07:35:54 UTC
Subject: Bug 29198

Author: jakub
Date: Fri Oct  6 07:35:45 2006
New Revision: 117486

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117486
Log:
	PR target/29198
	* config/i386/i386.c (legitimize_pic_address): Reject TLS symbols.
	* config/i386/predicates.md (local_symbolic_operand): Likewise.

	* gcc.dg/tls/opt-12.c: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/tls/opt-12.c
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/config/i386/i386.c
    branches/gcc-4_1-branch/gcc/config/i386/predicates.md
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 7 Jakub Jelinek 2006-10-06 07:41:22 UTC
Fixed on the trunk and on 4.1 branch.
Comment 8 Gabriel Dos Reis 2007-02-03 20:22:08 UTC
Fixed in GCC-4.1.2.