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: r155663
This commit is contained in:
parent
8a54e826ed
commit
17598865fe
|
@ -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 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/42614
|
||||
|
|
|
@ -70,8 +70,6 @@ extern bool legitimate_constant_p (rtx);
|
|||
extern bool constant_address_p (rtx);
|
||||
extern bool legitimate_pic_operand_p (rtx);
|
||||
extern int legitimate_address_p (enum machine_mode, rtx, int);
|
||||
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
||||
extern rtx legitimize_tls_address (rtx);
|
||||
extern rtx legitimize_address (rtx, rtx, enum machine_mode);
|
||||
extern void sparc_emit_call_insn (rtx, rtx);
|
||||
extern void sparc_defer_case_vector (rtx, rtx, int);
|
||||
|
@ -103,7 +101,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);
|
||||
|
|
|
@ -412,6 +412,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 bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, const_tree, bool);
|
||||
static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,
|
||||
|
@ -986,34 +989,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
|
||||
|
@ -1041,10 +1027,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;
|
||||
}
|
||||
}
|
||||
|
@ -2865,23 +2849,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;
|
||||
|
||||
|
@ -2948,10 +2920,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;
|
||||
}
|
||||
|
@ -2989,7 +2958,7 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int 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)
|
||||
|
@ -3029,7 +2998,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int 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;
|
||||
}
|
||||
}
|
||||
|
@ -3038,7 +3008,8 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int 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
|
||||
|
@ -3114,29 +3085,28 @@ sparc_tls_got (void)
|
|||
return temp;
|
||||
}
|
||||
|
||||
/* Return 1 if *X is a thread-local symbol. */
|
||||
/* Return true if X contains 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. */
|
||||
|
||||
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;
|
||||
|
@ -3260,21 +3230,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. */
|
||||
|
@ -3341,9 +3324,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)
|
||||
{
|
||||
|
@ -3395,10 +3378,10 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
|
|||
if (x != orig_x && 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)));
|
||||
|
@ -3407,8 +3390,9 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -8758,7 +8742,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);
|
||||
|
|
|
@ -2297,9 +2297,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) == '&')
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2010-01-05 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc.dg/tls/opt-15.c: New test.
|
||||
|
||||
2010-01-05 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/42614
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in New Issue