diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2010-01-05 22:29:18 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2010-01-05 22:29:18 +0000 |
commit | 208384fdd27fc1d15c7bc0be8c1f4d8cf8ca6637 (patch) | |
tree | 74ae2545069058553587b414ac1964dc1e6fce54 | |
parent | 4396e06315f0fdd09acf6eedfa4ea913b7106e96 (diff) | |
download | gcc-208384fdd27fc1d15c7bc0be8c1f4d8cf8ca6637.zip gcc-208384fdd27fc1d15c7bc0be8c1f4d8cf8ca6637.tar.gz gcc-208384fdd27fc1d15c7bc0be8c1f4d8cf8ca6637.tar.bz2 |
re PR target/42564 (unrecognizable insn with -O -fPIC)
PR target/42564
* config/sparc/sparc.h (SPARC_SYMBOL_REF_TLS_P): Delete.
* config/sparc/sparc-protos.h (legitimize_pic_address): Likewise.
(legitimize_tls_address): Likewise.
(sparc_tls_referenced_p): Likewise.
* config/sparc/sparc.c (sparc_expand_move): Use legitimize_tls_address
and adjust calls to legitimize_pic_address.
(legitimate_constant_p) Use sparc_tls_referenced_p.
(legitimate_pic_operand_p): Likewise.
(sparc_legitimate_address_p): Do not use SPARC_SYMBOL_REF_TLS_P.
(sparc_tls_symbol_ref_1): Delete.
(sparc_tls_referenced_p): Make static, recognize specific patterns.
(legitimize_tls_address): Make static, handle CONST patterns.
(legitimize_pic_address): Make static, remove unused parameter and
adjust recursive calls.
(sparc_legitimize_address): Make static, use sparc_tls_referenced_p
and adjust call to legitimize_pic_address.
(sparc_output_mi_thunk): Likewise.
From-SVN: r155662
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 122 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tls/opt-15.c | 24 |
6 files changed, 102 insertions, 75 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc334da..40a277b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2010-01-05 Eric Botcazou <ebotcazou@adacore.com> + + PR target/42564 + * config/sparc/sparc.h (SPARC_SYMBOL_REF_TLS_P): Delete. + * config/sparc/sparc-protos.h (legitimize_pic_address): Likewise. + (legitimize_tls_address): Likewise. + (sparc_tls_referenced_p): Likewise. + * config/sparc/sparc.c (sparc_expand_move): Use legitimize_tls_address + and adjust calls to legitimize_pic_address. + (legitimate_constant_p) Use sparc_tls_referenced_p. + (legitimate_pic_operand_p): Likewise. + (sparc_legitimate_address_p): Do not use SPARC_SYMBOL_REF_TLS_P. + (sparc_tls_symbol_ref_1): Delete. + (sparc_tls_referenced_p): Make static, recognize specific patterns. + (legitimize_tls_address): Make static, handle CONST patterns. + (legitimize_pic_address): Make static, remove unused parameter and + adjust recursive calls. + (sparc_legitimize_address): Make static, use sparc_tls_referenced_p + and adjust call to legitimize_pic_address. + (sparc_output_mi_thunk): Likewise. + 2010-01-05 Paolo Bonzini <bonzinI@gnu.rg> H.J. Lu <hongjiu.lu@intel.com> diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 097b709..b76e45b 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -64,8 +64,6 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *); extern bool legitimate_constant_p (rtx); extern bool constant_address_p (rtx); extern bool legitimate_pic_operand_p (rtx); -extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); -extern rtx legitimize_tls_address (rtx); extern void sparc_emit_call_insn (rtx, rtx); extern void sparc_defer_case_vector (rtx, rtx, int); extern bool sparc_expand_move (enum machine_mode, rtx *); @@ -97,7 +95,6 @@ extern int emit_move_sequence (rtx, enum machine_mode); extern int fp_sethi_p (rtx); extern int fp_mov_p (rtx); extern int fp_high_losum_p (rtx); -extern bool sparc_tls_referenced_p (rtx); extern int mem_min_alignment (rtx, int); extern int pic_address_needs_scratch (rtx); extern int reg_unused_after (rtx, rtx); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 82bc7d5..4b904b4 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -411,6 +411,9 @@ static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *); static void sparc_va_start (tree, rtx); static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); static bool sparc_vector_mode_supported_p (enum machine_mode); +static bool sparc_tls_referenced_p (rtx); +static rtx legitimize_tls_address (rtx); +static rtx legitimize_pic_address (rtx, rtx); static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode); static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); @@ -992,34 +995,17 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) /* Fixup TLS cases. */ if (TARGET_HAVE_TLS && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != HIGH && sparc_tls_referenced_p (operands [1])) { - rtx sym = operands[1]; - rtx addend = NULL; - - if (GET_CODE (sym) == CONST && GET_CODE (XEXP (sym, 0)) == PLUS) - { - addend = XEXP (XEXP (sym, 0), 1); - sym = XEXP (XEXP (sym, 0), 0); - } - - gcc_assert (SPARC_SYMBOL_REF_TLS_P (sym)); - - sym = legitimize_tls_address (sym); - if (addend) - { - sym = gen_rtx_PLUS (mode, sym, addend); - sym = force_operand (sym, operands[0]); - } - operands[1] = sym; + operands[1] = legitimize_tls_address (operands[1]); + return false; } /* Fixup PIC cases. */ if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) - operands[1] = legitimize_pic_address (operands[1], mode, 0); + operands[1] = legitimize_pic_address (operands[1], NULL_RTX); /* VxWorks does not impose a fixed gap between segments; the run-time gap can be different from the object-file gap. We therefore can't @@ -1047,10 +1033,8 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) if (symbolic_operand (operands[1], mode)) { operands[1] = legitimize_pic_address (operands[1], - mode, - (reload_in_progress ? - operands[0] : - NULL_RTX)); + reload_in_progress + ? operands[0] : NULL_RTX); return false; } } @@ -2979,23 +2963,11 @@ pic_address_needs_scratch (rtx x) bool legitimate_constant_p (rtx x) { - rtx inner; - switch (GET_CODE (x)) { - case SYMBOL_REF: - /* TLS symbols are not constant. */ - if (SYMBOL_REF_TLS_MODEL (x)) - return false; - break; - case CONST: - inner = XEXP (x, 0); - - /* Offsets of TLS symbols are never valid. - Discourage CSE from creating them. */ - if (GET_CODE (inner) == PLUS - && SPARC_SYMBOL_REF_TLS_P (XEXP (inner, 0))) + case SYMBOL_REF: + if (sparc_tls_referenced_p (x)) return false; break; @@ -3062,10 +3034,7 @@ legitimate_pic_operand_p (rtx x) { if (pic_address_needs_scratch (x)) return false; - if (SPARC_SYMBOL_REF_TLS_P (x) - || (GET_CODE (x) == CONST - && GET_CODE (XEXP (x, 0)) == PLUS - && SPARC_SYMBOL_REF_TLS_P (XEXP (XEXP (x, 0), 0)))) + if (sparc_tls_referenced_p (x)) return false; return true; } @@ -3103,7 +3072,7 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict) && GET_CODE (rs2) != SUBREG && GET_CODE (rs2) != LO_SUM && GET_CODE (rs2) != MEM - && ! SPARC_SYMBOL_REF_TLS_P (rs2) + && !(GET_CODE (rs2) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs2)) && (! symbolic_operand (rs2, VOIDmode) || mode == Pmode) && (GET_CODE (rs2) != CONST_INT || SMALL_INT (rs2))) || ((REG_P (rs1) @@ -3143,7 +3112,8 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict) rs2 = NULL; imm1 = XEXP (rs1, 1); rs1 = XEXP (rs1, 0); - if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1)) + if (!CONSTANT_P (imm1) + || (GET_CODE (rs1) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs1))) return 0; } } @@ -3152,7 +3122,8 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict) rs1 = XEXP (addr, 0); imm1 = XEXP (addr, 1); - if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1)) + if (!CONSTANT_P (imm1) + || (GET_CODE (rs1) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs1))) return 0; /* We can't allow TFmode in 32-bit mode, because an offset greater @@ -3228,29 +3199,28 @@ sparc_tls_got (void) return temp; } -/* Return 1 if *X is a thread-local symbol. */ - -static int -sparc_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) -{ - return SPARC_SYMBOL_REF_TLS_P (*x); -} - -/* Return 1 if X contains a thread-local symbol. */ +/* Return true if X contains a thread-local symbol. */ -bool +static bool sparc_tls_referenced_p (rtx x) { if (!TARGET_HAVE_TLS) return false; - return for_each_rtx (&x, &sparc_tls_symbol_ref_1, 0); + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) + x = XEXP (XEXP (x, 0), 0); + + if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) + return true; + + /* That's all we handle in legitimize_tls_address for now. */ + return false; } /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute this (thread-local) address. */ -rtx +static rtx legitimize_tls_address (rtx addr) { rtx temp1, temp2, temp3, ret, o0, got, insn; @@ -3374,21 +3344,34 @@ legitimize_tls_address (rtx addr) gcc_unreachable (); } + else if (GET_CODE (addr) == CONST) + { + rtx base, offset; + + gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS); + + base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0)); + offset = XEXP (XEXP (addr, 0), 1); + + base = force_operand (base, NULL_RTX); + if (!(GET_CODE (offset) == CONST_INT && SMALL_INT (offset))) + offset = force_reg (Pmode, offset); + ret = gen_rtx_PLUS (Pmode, base, offset); + } + else gcc_unreachable (); /* for now ... */ return ret; } - /* Legitimize PIC addresses. If the address is already position-independent, we return ORIG. Newly generated position-independent addresses go into a reg. This is REG if nonzero, otherwise we allocate register(s) as necessary. */ -rtx -legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, - rtx reg) +static rtx +legitimize_pic_address (rtx orig, rtx reg) { if (GET_CODE (orig) == SYMBOL_REF /* See the comment in sparc_expand_move. */ @@ -3455,9 +3438,9 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, } gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, - base == reg ? 0 : reg); + base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); + offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), + base == reg ? NULL_RTX : reg); if (GET_CODE (offset) == CONST_INT) { @@ -3490,7 +3473,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */ -rtx +static rtx sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode) { @@ -3512,10 +3495,10 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, if (x != orig_x && sparc_legitimate_address_p (mode, x, FALSE)) return x; - if (SPARC_SYMBOL_REF_TLS_P (x)) + if (sparc_tls_referenced_p (x)) x = legitimize_tls_address (x); else if (flag_pic) - x = legitimize_pic_address (x, mode, 0); + x = legitimize_pic_address (x, NULL_RTX); else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1))) x = gen_rtx_PLUS (Pmode, XEXP (x, 0), copy_to_mode_reg (Pmode, XEXP (x, 1))); @@ -3524,8 +3507,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, copy_to_mode_reg (Pmode, XEXP (x, 0))); else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST - || GET_CODE (x) == LABEL_REF) + || GET_CODE (x) == LABEL_REF) x = copy_to_suggested_reg (x, NULL_RTX, Pmode); + return x; } @@ -8899,7 +8883,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, /* Delay emitting the PIC helper function because it needs to change the section and we are emitting assembly code. */ load_pic_register (true); /* clobbers %o7 */ - scratch = legitimize_pic_address (funexp, Pmode, scratch); + scratch = legitimize_pic_address (funexp, scratch); seq = get_insns (); end_sequence (); emit_and_preserve (seq, spill_reg, spill_reg2); diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 58c584e..344441e 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2213,9 +2213,6 @@ extern int sparc_indent_opcode; } \ } while (0) -#define SPARC_SYMBOL_REF_TLS_P(RTX) \ - (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0) - #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '(' \ || (CHAR) == ')' || (CHAR) == '_' || (CHAR) == '&') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 992f310..4f6aa65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-01-05 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/tls/opt-15.c: New test. + 2010-01-05 H.J. Lu <hongjiu.lu@intel.com> * gcc.target/i386/pr42542-1.c (res): Make it 8 elements. diff --git a/gcc/testsuite/gcc.dg/tls/opt-15.c b/gcc/testsuite/gcc.dg/tls/opt-15.c new file mode 100644 index 0000000..bebee8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/opt-15.c @@ -0,0 +1,24 @@ +/* PR target/42564 */ +/* This used to ICE on the SPARC because of an unrecognized TLS pattern. */ + +/* { dg-do compile } */ +/* { dg-options "-O -fPIC" } */ +/* { dg-require-effective-target tls_native } */ +/* { dg-require-effective-target fpic } */ + +extern void *memset(void *s, int c, __SIZE_TYPE__ n); + +struct S1 { int i; }; + +struct S2 +{ + int ver; + struct S1 s; +}; + +static __thread struct S2 m; + +void init(void) +{ + memset(&m.s, 0, sizeof(m.s)); +} |