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:
Eric Botcazou 2010-01-05 22:32:25 +00:00 committed by Eric Botcazou
parent 8a54e826ed
commit 17598865fe
6 changed files with 102 additions and 75 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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) == '&')

View File

@ -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

View File

@ -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));
}