The attached change fixes a problem found in the libcap-ng package. TLS call arguments were not being pre expanded. As a result, the register arguments were being clobbered.

After fixing pa_legitimate_constant_p() to return false for all TLS references, I found that the code in pa_emit_move_sequence to simplify TLS references in the form CONST (PLUS SYMBOL_REF CONST_INT) was not being executed. I fixed that and adjusted CONSTANT_ADDRESS_P
to reject this form.

Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and hppa64-hp- hpux11.11.

Committed to trunk and 4.8.

Dave
--
John David Anglin       dave.ang...@bell.net


2014-02-04  John David Anglin  <dang...@gcc.gnu.org>

        PR target/59777
        * config/pa/pa.c (legitimize_tls_address): Return original address
        if not passed a SYMBOL_REF rtx.
        (hppa_legitimize_address): Call legitimize_tls_address for all TLS
        addresses.
        (pa_emit_move_sequence): Simplify TLS source operands.
        (pa_legitimate_constant_p): Reject all TLS constants.
        * config/pa/pa.h (PA_SYMBOL_REF_TLS_P): Correct comment.
        (CONSTANT_ADDRESS_P): Reject TLS CONST addresses.

Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c      (revision 207393)
+++ config/pa/pa.c      (working copy)
@@ -916,9 +910,12 @@
 legitimize_tls_address (rtx addr)
 {
   rtx ret, insn, tmp, t1, t2, tp;
-  enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
 
-  switch (model) 
+  /* Currently, we can't handle anything but a SYMBOL_REF.  */
+  if (GET_CODE (addr) != SYMBOL_REF)
+    return addr;
+
+  switch (SYMBOL_REF_TLS_MODEL (addr)) 
     {
       case TLS_MODEL_GLOBAL_DYNAMIC:
        tmp = gen_reg_rtx (Pmode);
@@ -1039,7 +1036,7 @@
       && !REG_POINTER (XEXP (x, 1)))
     return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));
 
-  if (PA_SYMBOL_REF_TLS_P (x))
+  if (pa_tls_referenced_p (x))
     return legitimize_tls_address (x);
   else if (flag_pic)
     return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
@@ -1920,9 +1917,10 @@
      not consider them legitimate constants.  Loop optimizations can
      call the emit_move_xxx with one as a source.  */
   if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
+      || (GET_CODE (operand1) == HIGH
+         && symbolic_operand (XEXP (operand1, 0), mode))
       || function_label_operand (operand1, VOIDmode)
-      || (GET_CODE (operand1) == HIGH
-         && symbolic_operand (XEXP (operand1, 0), mode)))
+      || pa_tls_referenced_p (operand1))
     {
       int ishighonly = 0;
 
@@ -10300,7 +10298,7 @@
   /* TLS_MODEL_GLOBAL_DYNAMIC and TLS_MODEL_LOCAL_DYNAMIC are not
      legitimate constants.  The other variants can't be handled by
      the move patterns after reload starts.  */
-  if (PA_SYMBOL_REF_TLS_P (x))
+  if (pa_tls_referenced_p (x))
     return false;
 
   if (TARGET_64BIT && GET_CODE (x) == CONST_DOUBLE)
Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h      (revision 207393)
+++ config/pa/pa.h      (working copy)
@@ -784,9 +784,9 @@
 
 #define MAX_REGS_PER_ADDRESS 2
 
-/* Non-TLS symbolic references.  */
-#define PA_SYMBOL_REF_TLS_P(RTX) \
-  (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
+/* TLS symbolic reference.  */
+#define PA_SYMBOL_REF_TLS_P(X) \
+  (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (X) != 0)
 
 /* Recognize any constant value that is a valid address except
    for symbolic addresses.  We get better CSE by rejecting them
@@ -796,7 +796,8 @@
 #define CONSTANT_ADDRESS_P(X) \
   ((GET_CODE (X) == LABEL_REF                                          \
    || (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (X))                
\
-   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST               \
+   || GET_CODE (X) == CONST_INT                                                
\
+   || (GET_CODE (X) == CONST && !pa_tls_referenced_p (X))              \
    || GET_CODE (X) == HIGH)                                            \
    && (reload_in_progress || reload_completed                          \
        || ! pa_symbolic_expression_p (X)))

Reply via email to