TLS relocations do not support offsets, so add a new constraint Usb and
predicate aarch64_tls_symref to ensure only plain symbol_ref is allowed.
In the future UNSPEC could be removed in some cases and some patterns could
be shared in a single insn.

Passes regress, OK for commit?

gcc:
        * config/aarch64/aarch64.md (tlsgd_small_<mode>): Update constraints.
        (tlsie_small_<mode>): Likewise.
        (tlsie_small_sidi): Likewise.
        (tlsie_tiny_<mode>): Likewise.
        (tlsie_tiny_sidi): Likewise.
        (tlsle12_<mode>): Likewise.
        (tlsle24_<mode>): Likewise.
        (tlsle32_<mode>): Likewise.
        (tlsle48_<mode>): Likewise.
        (tlsdesc_small_<mode>): Likewise.
        (tlsdesc_small_advsimd_<mode>): Likewise.
        (tlsdesc_small_advsimd_<mode>): Likewise.
        * config/aarch64/aarch64.cc (aarch64_expand_mov_immediate): Ensure
        all TLS symbols have any offsets split off.     
        * config/aarch64/constraints.md (Usb): New constraint for symbol_ref.
        * config/aarch64/predicates.md (aarch64_tls_symref): New predicate for 
TLS.
        (aarch64_tls_ie_symref): Remove.
        (aarch64_tls_le_symref): Remove.

---

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 
cd5ed154c7ac93f0585c031d6f42f176fa276edf..de448249ebd98004410757943fc80af671866e2a
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -6763,13 +6763,17 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
 
          return;
 
-        case SYMBOL_SMALL_TLSGD:
-        case SYMBOL_SMALL_TLSDESC:
+       case SYMBOL_SMALL_TLSGD:
+       case SYMBOL_SMALL_TLSDESC:
        case SYMBOL_SMALL_TLSIE:
        case SYMBOL_SMALL_GOT_28K:
        case SYMBOL_SMALL_GOT_4G:
        case SYMBOL_TINY_GOT:
        case SYMBOL_TINY_TLSIE:
+       case SYMBOL_TLSLE12:
+       case SYMBOL_TLSLE24:
+       case SYMBOL_TLSLE32:
+       case SYMBOL_TLSLE48:
          if (const_offset != 0)
            {
              gcc_assert(can_create_pseudo_p ());
@@ -6782,10 +6786,6 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
 
        case SYMBOL_SMALL_ABSOLUTE:
        case SYMBOL_TINY_ABSOLUTE:
-       case SYMBOL_TLSLE12:
-       case SYMBOL_TLSLE24:
-       case SYMBOL_TLSLE32:
-       case SYMBOL_TLSLE48:
          aarch64_load_symref_appropriately (dest, imm, sty);
          return;
 
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 
0ef01e889a6d8b47d4c348c2fd623460804d882e..bab39061c41e122006041ba0e789f5d6fe6e6bbf
 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -8007,7 +8007,7 @@ (define_expand "tlsgd_small_<mode>"
  [(parallel [(set (match_operand:PTR 0 "register_operand")
                   (call (mem:DI (match_dup 2)) (const_int 1)))
             (unspec:DI [(const_int 0)] UNSPEC_CALLEE_ABI)
-            (unspec:DI [(match_operand 1 "aarch64_valid_symref")] 
UNSPEC_GOTSMALLTLS)
+            (unspec:DI [(match_operand 1 "aarch64_tls_symref")] 
UNSPEC_GOTSMALLTLS)
             (clobber (reg:DI LR_REGNUM))])]
  ""
 {
@@ -8018,7 +8018,7 @@ (define_insn "*tlsgd_small_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "")
        (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
    (unspec:DI [(const_int 0)] UNSPEC_CALLEE_ABI)
-   (unspec:DI [(match_operand 1 "aarch64_valid_symref" "S")] 
UNSPEC_GOTSMALLTLS)
+   (unspec:DI [(match_operand 1 "aarch64_tls_symref" "Usb")] 
UNSPEC_GOTSMALLTLS)
    (clobber (reg:DI LR_REGNUM))
   ]
   ""
@@ -8028,7 +8028,7 @@ (define_insn "*tlsgd_small_<mode>"
 
 (define_insn "tlsie_small_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "=r")
-        (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
+        (unspec:PTR [(match_operand 1 "aarch64_tls_symref" "Usb")]
                   UNSPEC_GOTSMALLTLS))]
   ""
   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
@@ -8039,7 +8039,7 @@ (define_insn "tlsie_small_<mode>"
 (define_insn "tlsie_small_sidi"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-          (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
+          (unspec:SI [(match_operand 1 "aarch64_tls_symref" "Usb")]
                      UNSPEC_GOTSMALLTLS)))]
   ""
   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
@@ -8049,7 +8049,7 @@ (define_insn "tlsie_small_sidi"
 
 (define_insn "tlsie_tiny_<mode>"
   [(set (match_operand:PTR 0 "register_operand" "=&r")
-       (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
+       (unspec:PTR [(match_operand 1 "aarch64_tls_symref" "Usb")
                     (match_operand:PTR 2 "register_operand" "r")]
                   UNSPEC_GOTTINYTLS))]
   ""
@@ -8061,7 +8061,7 @@ (define_insn "tlsie_tiny_<mode>"
 (define_insn "tlsie_tiny_sidi"
   [(set (match_operand:DI 0 "register_operand" "=&r")
        (zero_extend:DI
-         (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
+         (unspec:SI [(match_operand 1 "aarch64_tls_symref" "Usb")
                      (match_operand:DI 2 "register_operand" "r")
                      ]
                      UNSPEC_GOTTINYTLS)))]
@@ -8074,7 +8074,7 @@ (define_insn "tlsie_tiny_sidi"
 (define_insn "tlsle12_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand:P 1 "register_operand" "r")
-                  (match_operand 2 "aarch64_tls_le_symref" "S")]
+                  (match_operand 2 "aarch64_tls_symref" "Usb")]
                   UNSPEC_TLSLE12))]
   ""
   "add\\t%<w>0, %<w>1, #%L2";
@@ -8085,7 +8085,7 @@ (define_insn "tlsle12_<mode>"
 (define_insn "tlsle24_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
        (unspec:P [(match_operand:P 1 "register_operand" "r")
-                  (match_operand 2 "aarch64_tls_le_symref" "S")]
+                  (match_operand 2 "aarch64_tls_symref" "Usb")]
                   UNSPEC_TLSLE24))]
   ""
   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
@@ -8095,7 +8095,7 @@ (define_insn "tlsle24_<mode>"
 
 (define_insn "tlsle32_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
-       (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+       (unspec:P [(match_operand 1 "aarch64_tls_symref" "Usb")]
                   UNSPEC_TLSLE32))]
   ""
   "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
@@ -8105,7 +8105,7 @@ (define_insn "tlsle32_<mode>"
 
 (define_insn "tlsle48_<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
-       (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+       (unspec:P [(match_operand 1 "aarch64_tls_symref" "Usb")]
                   UNSPEC_TLSLE48))]
   ""
   "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, 
#:tprel_g0_nc:%1"
@@ -8114,7 +8114,7 @@ (define_insn "tlsle48_<mode>"
 )
 
 (define_expand "tlsdesc_small_<mode>"
-  [(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
+  [(unspec:PTR [(match_operand 0 "aarch64_tls_symref")] UNSPEC_TLSDESC)]
   "TARGET_TLS_DESC"
   {
     if (TARGET_SVE)
@@ -8136,7 +8136,7 @@ (define_expand "tlsdesc_small_<mode>"
 ;; R0 and LR.
 (define_insn "tlsdesc_small_advsimd_<mode>"
   [(set (reg:PTR R0_REGNUM)
-        (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
+        (unspec:PTR [(match_operand 0 "aarch64_tls_symref" "Usb")]
                    UNSPEC_TLSDESC))
    (clobber (reg:DI LR_REGNUM))
    (clobber (reg:CC CC_REGNUM))
@@ -8153,7 +8153,7 @@ (define_insn "tlsdesc_small_advsimd_<mode>"
 (define_insn "tlsdesc_small_sve_<mode>"
   [(set (reg:PTR R0_REGNUM)
        (call (mem:DI (unspec:PTR
-                       [(match_operand 0 "aarch64_valid_symref")]
+                       [(match_operand 0 "aarch64_tls_symref")]
                        UNSPEC_TLSDESC))
              (const_int 0)))
    (unspec:DI [(match_operand:DI 1 "const_int_operand")] UNSPEC_CALLEE_ABI)
diff --git a/gcc/config/aarch64/constraints.md 
b/gcc/config/aarch64/constraints.md
index 
8760220835b74e87497a696865a5ea7304b9d406..93025bd3e861cb1285bcabe6b1974191f7d79c7f
 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -195,6 +195,11 @@ (define_constraint "Usa"
        (match_test "aarch64_symbolic_address_p (op)")
        (match_test "aarch64_mov_operand_p (op, GET_MODE (op))")))
 
+(define_constraint "Usb"
+  "@internal
+   A constraint that matches a symbol_ref."
+  (match_code "symbol_ref"))
+
 (define_constraint "Usm"
  "A constant that can be used with the S[MIN/MAX] CSSC instructions."
  (and (match_code "const_int")
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 
40b0e8b9f02c7eb936edf5245ce6a89611fc52a1..76d42312607ff58834267df3c7415b7d0820e89f
 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -372,48 +372,10 @@ (define_predicate "aarch64_valid_symref"
          != SYMBOL_FORCE_TO_MEM);
 })
 
-(define_predicate "aarch64_tls_ie_symref"
-  (match_code "const, symbol_ref, label_ref")
-{
-  switch (GET_CODE (op))
-    {
-    case CONST:
-      op = XEXP (op, 0);
-      if (GET_CODE (op) != PLUS
-         || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
-         || GET_CODE (XEXP (op, 1)) != CONST_INT)
-       return false;
-      op = XEXP (op, 0);
-      /* FALLTHRU */
-
-    case SYMBOL_REF:
-      return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
-
-    default:
-      gcc_unreachable ();
-    }
-})
-
-(define_predicate "aarch64_tls_le_symref"
-  (match_code "const, symbol_ref, label_ref")
+(define_predicate "aarch64_tls_symref"
+  (match_code "symbol_ref")
 {
-  switch (GET_CODE (op))
-    {
-    case CONST:
-      op = XEXP (op, 0);
-      if (GET_CODE (op) != PLUS
-         || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
-         || GET_CODE (XEXP (op, 1)) != CONST_INT)
-       return false;
-      op = XEXP (op, 0);
-      /* FALLTHRU */
-
-    case SYMBOL_REF:
-      return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
-
-    default:
-      gcc_unreachable ();
-    }
+  return SYMBOL_REF_TLS_MODEL (op) != TLS_MODEL_NONE;
 })
 
 (define_predicate "aarch64_mov_operand"


Reply via email to