This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix x86_64 TLS bug
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 Jul 2003 01:36:00 +0200
- Subject: [PATCH] Fix x86_64 TLS bug
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This following testcase generates bogus:
movq baz@GOTTPOFF(%rip), %rax
movq $0, %fs:(%rax)
movq $0, 8+baz(%rip)
The problem is that although legitimate_pic_address_disp_p refused
tls_symbolic_operand, it did not refuse
(const (plus tls_symbolic_operand (const_int small_integer)))
Ok to commit if testing succeeds?
2003-07-31 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (legitimate_pic_address_disp_p): Disallow TLS
SYMBOL_REFs not inside UNSPEC even in PLUS rtx.
* gcc.dg/tls/opt-7.c: New test.
--- gcc/testsuite/gcc.dg/tls/opt-7.c.jj 2003-07-30 19:17:34.000000000 -0400
+++ gcc/testsuite/gcc.dg/tls/opt-7.c 2003-07-30 19:17:30.000000000 -0400
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC" } */
+
+static __thread void *baz [4] __attribute__((tls_model ("initial-exec")));
+void foo (void)
+{
+ void **u = (void **) baz;
+
+ u[0] = 0;
+ u[1] = 0;
+}
+
+/* { dg-final { scan-assembler-not "\[48\]\\+baz" { target i?86-*-* x86_64-*-* } } } */
--- gcc/config/i386/i386.c.jj 2003-07-30 17:08:13.000000000 -0400
+++ gcc/config/i386/i386.c 2003-07-30 19:00:24.000000000 -0400
@@ -5661,15 +5661,23 @@ legitimate_pic_address_disp_p (register
if (GET_CODE (disp) == LABEL_REF)
return 1;
if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == PLUS
- && ((GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
- && ix86_cmodel == CM_SMALL_PIC
- && SYMBOL_REF_LOCAL_P (XEXP (XEXP (disp, 0), 0)))
- || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
- && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (disp, 0), 1)) < 16*1024*1024
- && INTVAL (XEXP (XEXP (disp, 0), 1)) >= -16*1024*1024)
- return 1;
+ && GET_CODE (XEXP (disp, 0)) == PLUS)
+ {
+ rtx op0 = XEXP (XEXP (disp, 0), 0);
+ rtx op1 = XEXP (XEXP (disp, 0), 1);
+
+ /* TLS references should always be enclosed in UNSPEC. */
+ if (tls_symbolic_operand (op0, GET_MODE (op0)))
+ return 0;
+ if (((GET_CODE (op0) == SYMBOL_REF
+ && ix86_cmodel == CM_SMALL_PIC
+ && SYMBOL_REF_LOCAL_P (op0))
+ || GET_CODE (op0) == LABEL_REF)
+ && GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) < 16*1024*1024
+ && INTVAL (op1) >= -16*1024*1024)
+ return 1;
+ }
}
if (GET_CODE (disp) != CONST)
return 0;
Jakub