re PR target/17224 (relocation truncated to fit: GPREL22)

PR target/17224
        * config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets
        outside the referenced object.

From-SVN: r91478
This commit is contained in:
Richard Henderson 2004-11-29 10:42:26 -08:00 committed by Richard Henderson
parent dda88f6f85
commit b0c2dee9fb
2 changed files with 43 additions and 3 deletions

View File

@ -1,3 +1,9 @@
2004-11-29 Richard Henderson <rth@redhat.com>
PR target/17224
* config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets
outside the referenced object.
2004-11-29 Kazu Hirata <kazu@cs.umass.edu>
* tree-if-conv.c (replace_phi_with_cond_modify_expr): Use

View File

@ -74,21 +74,55 @@
(define_predicate "sdata_symbolic_operand"
(match_code "symbol_ref,const")
{
HOST_WIDE_INT offset = 0, size = 0;
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, 0)) != SYMBOL_REF
|| GET_CODE (XEXP (op, 1)) != CONST_INT)
return false;
offset = INTVAL (XEXP (op, 1));
op = XEXP (op, 0);
/* FALLTHRU */
case SYMBOL_REF:
if (CONSTANT_POOL_ADDRESS_P (op))
return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
{
size = GET_MODE_SIZE (get_pool_mode (op));
if (size > ia64_section_threshold)
return false;
}
else
return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);
{
tree t;
if (!SYMBOL_REF_LOCAL_P (op) || !SYMBOL_REF_SMALL_P (op))
return false;
/* Note that in addition to DECLs, we can get various forms
of constants here. */
t = SYMBOL_REF_DECL (op);
if (DECL_P (t))
t = DECL_SIZE_UNIT (t);
else
t = TYPE_SIZE_UNIT (TREE_TYPE (t));
if (t && host_integerp (t, 0))
{
size = tree_low_cst (t, 0);
if (size < 0)
size = 0;
}
}
/* Deny the stupid user trick of addressing outside the object. Such
things quickly result in GPREL22 relocation overflows. Of course,
they're also highly undefined. From a pure pedant's point of view
they deserve a slap on the wrist (such as provided by a relocation
overflow), but that just leads to bugzilla noise. */
return (offset >= 0 && offset <= size);
default:
abort ();