Hi!

The following patch fixes ICE, when we try to split a double-word TLS load
or store.  The problem is that x86_64_immediate_operand disallows CONST_INT
offsets with -mcmodel=large.  I guess it is intentional for SYMBOL_REFs,
LABEL_REFs etc., but for the TLS LE UNSPECs it should be fine, there are no
64-bit relocations for these, we don't really support > 2GB thread local
segments.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-02-12  Jakub Jelinek  <ja...@redhat.com>

        PR target/89290
        * config/i386/predicates.md (x86_64_immediate_operand): Allow
        TLS UNSPECs offsetted by signed 32-bit CONST_INT even with
        -mcmodel=large.

        * gcc.target/i386/pr89290.c: New test.

--- gcc/config/i386/predicates.md.jj    2019-01-01 12:37:32.267727037 +0100
+++ gcc/config/i386/predicates.md       2019-02-12 17:07:15.937097266 +0100
@@ -182,7 +182,7 @@ (define_predicate "x86_64_immediate_oper
          rtx op1 = XEXP (XEXP (op, 0), 0);
          rtx op2 = XEXP (XEXP (op, 0), 1);
 
-         if (ix86_cmodel == CM_LARGE)
+         if (ix86_cmodel == CM_LARGE && GET_CODE (op1) != UNSPEC)
            return false;
          if (!CONST_INT_P (op2))
            return false;
--- gcc/testsuite/gcc.target/i386/pr89290.c.jj  2019-02-12 17:32:49.291750588 
+0100
+++ gcc/testsuite/gcc.target/i386/pr89290.c     2019-02-12 17:34:00.847568163 
+0100
@@ -0,0 +1,19 @@
+/* PR target/89290 */
+/* { dg-do compile { target { tls && lp64 } } } */
+/* { dg-options "-O0 -mcmodel=large" } */
+
+struct S { long int a, b; } e;
+__thread struct S s;
+__thread struct S t[2];
+
+void
+foo (void)
+{
+  s = e;
+}
+
+void
+bar (void)
+{
+  t[1] = e;
+}

        Jakub

Reply via email to