On Sun, Jul 17, 2011 at 4:32 PM, Richard Sandiford <rdsandif...@googlemail.com> wrote: > This patch makes the mechanical MEM_OFFSET interface change, > along the same lines as the MEM_SIZE one.
Ok if there are no objections from target maintainers. Thanks, Richard. > Richard > > > gcc/ > * doc/rtl.texi (MEM_OFFSET_KNOWN_P): Document. > (MEM_OFFSET): Change from returning an rtx to returning a > HOST_WIDE_INT. > * rtl.h (MEM_OFFSET_KNOWN_P): New macro. > (MEM_OFFSET): Return a HOST_WIDE_INT rather than an rtx. > * emit-rtl.h (set_mem_offset): Take a HOST_WIDE_INT rather than an rtx. > (clear_mem_offset): Declare. > * alias.c (ao_ref_from_mem): Adjust uses of MEM_OFFSET, using > MEM_OFFSET_KNOWN_P to test whether the offset is known, and > MEM_OFFSET to get a HOST_WIDE_INT offset. > (nonoverlapping_memrefs_p): Likewise. Adjust calls to... > (adjust_offset_for_component_ref): Take a bool "known_p" > parameter and a HOST_WIDE_INT "offset" parameter. > * builtins.c (get_memory_rtx): As for ao_ref_from_mem. > Adjust calls to set_mem_offset, passing a HOST_WIDE_INT rather > than an rtx. Use clear_mem_offset to clear the offset. > * cfgcleanup.c (merge_memattrs): Likewise. > * dwarf2out.c (tls_mem_loc_descriptor): Likewise. > * function.c (assign_parm_find_stack_rtl): Likewise. > (assign_parm_setup_stack): Likewise. > * print-rtl.c (print_rtx): Likewise. > * reload.c (find_reloads_subreg_address): Likewise. > * simplify-rtx.c (delegitimize_mem_from_attrs): Likewise. > * var-tracking.c (INT_MEM_OFFSET): Likewise. > * emit-rtl.c (set_reg_attrs_from_value): Likewise. > (get_mem_align_offset): Likewise. > (set_mem_offset): Take a HOST_WIDE_INT rather than an rtx. > (clear_mem_offset): New function. > * config/mips/mips.c (r10k_safe_mem_expr_p): Take a HOST_WIDE_INT > offset rather than an rtx. Assume both the expressio and offset > are available. > (r10k_needs_protection_p_1): Update accordingly, checking the > expression and offset availability here instead. > > Index: gcc/doc/rtl.texi > =================================================================== > --- gcc/doc/rtl.texi 2011-07-17 10:53:19.000000000 +0100 > +++ gcc/doc/rtl.texi 2011-07-17 10:54:22.000000000 +0100 > @@ -409,9 +409,15 @@ and @code{TREE_OPERAND (@var{x}, 0)} con > or another @code{COMPONENT_REF}, or null if there is no compile-time > object associated with the reference. > > +@findex MEM_OFFSET_KNOWN_P > +@item MEM_OFFSET_KNOWN_P (@var{x}) > +True if the offset of the memory reference from @code{MEM_EXPR} is known. > +@samp{MEM_OFFSET (@var{x})} provides the offset if so. > + > @findex MEM_OFFSET > @item MEM_OFFSET (@var{x}) > -The offset from the start of @code{MEM_EXPR} as a @code{CONST_INT} rtx. > +The offset from the start of @code{MEM_EXPR}. The value is only valid if > +@samp{MEM_OFFSET_KNOWN_P (@var{x})} is true. > > @findex MEM_SIZE_KNOWN_P > @item MEM_SIZE_KNOWN_P (@var{x}) > Index: gcc/rtl.h > =================================================================== > --- gcc/rtl.h 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/rtl.h 2011-07-17 10:38:53.000000000 +0100 > @@ -1302,9 +1302,11 @@ #define MEM_ALIAS_SET(RTX) (get_mem_attr > refer to part of a DECL. It may also be a COMPONENT_REF. */ > #define MEM_EXPR(RTX) (get_mem_attrs (RTX)->expr) > > -/* For a MEM rtx, the offset from the start of MEM_EXPR, if known, as a > - RTX that is always a CONST_INT. */ > -#define MEM_OFFSET(RTX) (get_mem_attrs (RTX)->offset) > +/* For a MEM rtx, true if its MEM_OFFSET is known. */ > +#define MEM_OFFSET_KNOWN_P(RTX) (get_mem_attrs (RTX)->offset != NULL_RTX) > + > +/* For a MEM rtx, the offset from the start of MEM_EXPR. */ > +#define MEM_OFFSET(RTX) INTVAL (get_mem_attrs (RTX)->offset) > > /* For a MEM rtx, the address space. */ > #define MEM_ADDR_SPACE(RTX) (get_mem_attrs (RTX)->addrspace) > Index: gcc/emit-rtl.h > =================================================================== > --- gcc/emit-rtl.h 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/emit-rtl.h 2011-07-17 10:38:53.000000000 +0100 > @@ -33,7 +33,10 @@ extern void set_mem_addr_space (rtx, add > extern void set_mem_expr (rtx, tree); > > /* Set the offset for MEM to OFFSET. */ > -extern void set_mem_offset (rtx, rtx); > +extern void set_mem_offset (rtx, HOST_WIDE_INT); > + > +/* Clear the offset recorded for MEM. */ > +extern void clear_mem_offset (rtx); > > /* Set the size for MEM to SIZE. */ > extern void set_mem_size (rtx, HOST_WIDE_INT); > Index: gcc/alias.c > =================================================================== > --- gcc/alias.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/alias.c 2011-07-17 10:43:20.000000000 +0100 > @@ -162,7 +162,6 @@ static const_rtx fixed_scalar_and_varyin > static int aliases_everything_p (const_rtx); > static bool nonoverlapping_component_refs_p (const_tree, const_tree); > static tree decl_for_component_ref (tree); > -static rtx adjust_offset_for_component_ref (tree, rtx); > static int write_dependence_p (const_rtx, const_rtx, int); > > static void memory_modified_1 (rtx, const_rtx, void *); > @@ -315,7 +314,7 @@ ao_ref_from_mem (ao_ref *ref, const_rtx > > /* If MEM_OFFSET or MEM_SIZE are unknown we have to punt. > Keep points-to related information though. */ > - if (!MEM_OFFSET (mem) > + if (!MEM_OFFSET_KNOWN_P (mem) > || !MEM_SIZE_KNOWN_P (mem)) > { > ref->ref = NULL_TREE; > @@ -328,12 +327,11 @@ ao_ref_from_mem (ao_ref *ref, const_rtx > /* If the base decl is a parameter we can have negative MEM_OFFSET in > case of promoted subregs on bigendian targets. Trust the MEM_EXPR > here. */ > - if (INTVAL (MEM_OFFSET (mem)) < 0 > - && ((MEM_SIZE (mem) + INTVAL (MEM_OFFSET (mem))) > - * BITS_PER_UNIT) == ref->size) > + if (MEM_OFFSET (mem) < 0 > + && (MEM_SIZE (mem) + MEM_OFFSET (mem)) * BITS_PER_UNIT == ref->size) > return true; > > - ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT; > + ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT; > ref->size = MEM_SIZE (mem) * BITS_PER_UNIT; > > /* The MEM may extend into adjacent fields, so adjust max_size if > @@ -2201,34 +2199,33 @@ decl_for_component_ref (tree x) > return x && DECL_P (x) ? x : NULL_TREE; > } > > -/* Walk up the COMPONENT_REF list and adjust OFFSET to compensate for the > - offset of the field reference. */ > +/* Walk up the COMPONENT_REF list in X and adjust *OFFSET to compensate > + for the offset of the field reference. *KNOWN_P says whether the > + offset is known. */ > > -static rtx > -adjust_offset_for_component_ref (tree x, rtx offset) > +static void > +adjust_offset_for_component_ref (tree x, bool *known_p, > + HOST_WIDE_INT *offset) > { > - HOST_WIDE_INT ioffset; > - > - if (! offset) > - return NULL_RTX; > - > - ioffset = INTVAL (offset); > + if (!*known_p) > + return; > do > { > - tree offset = component_ref_field_offset (x); > + tree xoffset = component_ref_field_offset (x); > tree field = TREE_OPERAND (x, 1); > > - if (! host_integerp (offset, 1)) > - return NULL_RTX; > - ioffset += (tree_low_cst (offset, 1) > + if (! host_integerp (xoffset, 1)) > + { > + *known_p = false; > + return; > + } > + *offset += (tree_low_cst (xoffset, 1) > + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1) > / BITS_PER_UNIT)); > > x = TREE_OPERAND (x, 0); > } > while (x && TREE_CODE (x) == COMPONENT_REF); > - > - return GEN_INT (ioffset); > } > > /* Return nonzero if we can determine the exprs corresponding to memrefs > @@ -2241,7 +2238,8 @@ nonoverlapping_memrefs_p (const_rtx x, c > tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); > rtx rtlx, rtly; > rtx basex, basey; > - rtx moffsetx, moffsety; > + bool moffsetx_known_p, moffsety_known_p; > + HOST_WIDE_INT moffsetx = 0, moffsety = 0; > HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem; > > /* Unless both have exprs, we can't tell anything. */ > @@ -2250,9 +2248,9 @@ nonoverlapping_memrefs_p (const_rtx x, c > > /* For spill-slot accesses make sure we have valid offsets. */ > if ((exprx == get_spill_slot_decl (false) > - && ! MEM_OFFSET (x)) > + && ! MEM_OFFSET_KNOWN_P (x)) > || (expry == get_spill_slot_decl (false) > - && ! MEM_OFFSET (y))) > + && ! MEM_OFFSET_KNOWN_P (y))) > return 0; > > /* If both are field references, we may be able to determine something. */ > @@ -2263,23 +2261,27 @@ nonoverlapping_memrefs_p (const_rtx x, c > > > /* If the field reference test failed, look at the DECLs involved. */ > - moffsetx = MEM_OFFSET (x); > + moffsetx_known_p = MEM_OFFSET_KNOWN_P (x); > + if (moffsetx_known_p) > + moffsetx = MEM_OFFSET (x); > if (TREE_CODE (exprx) == COMPONENT_REF) > { > tree t = decl_for_component_ref (exprx); > if (! t) > return 0; > - moffsetx = adjust_offset_for_component_ref (exprx, moffsetx); > + adjust_offset_for_component_ref (exprx, &moffsetx_known_p, &moffsetx); > exprx = t; > } > > - moffsety = MEM_OFFSET (y); > + moffsety_known_p = MEM_OFFSET_KNOWN_P (y); > + if (moffsety_known_p) > + moffsety = MEM_OFFSET (y); > if (TREE_CODE (expry) == COMPONENT_REF) > { > tree t = decl_for_component_ref (expry); > if (! t) > return 0; > - moffsety = adjust_offset_for_component_ref (expry, moffsety); > + adjust_offset_for_component_ref (expry, &moffsety_known_p, &moffsety); > expry = t; > } > > @@ -2346,17 +2348,17 @@ nonoverlapping_memrefs_p (const_rtx x, c > > /* If we have an offset for either memref, it can update the values computed > above. */ > - if (moffsetx) > - offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx); > - if (moffsety) > - offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety); > + if (moffsetx_known_p) > + offsetx += moffsetx, sizex -= moffsetx; > + if (moffsety_known_p) > + offsety += moffsety, sizey -= moffsety; > > /* If a memref has both a size and an offset, we can use the smaller size. > We can't do this if the offset isn't known because we must view this > memref as being anywhere inside the DECL's MEM. */ > - if (MEM_SIZE_KNOWN_P (x) && moffsetx) > + if (MEM_SIZE_KNOWN_P (x) && moffsetx_known_p) > sizex = MEM_SIZE (x); > - if (MEM_SIZE_KNOWN_P (y) && moffsety) > + if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p) > sizey = MEM_SIZE (y); > > /* Put the values of the memref with the lower offset in X's values. */ > Index: gcc/builtins.c > =================================================================== > --- gcc/builtins.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/builtins.c 2011-07-17 10:38:53.000000000 +0100 > @@ -1238,9 +1238,8 @@ get_memory_rtx (tree exp, tree len) > > gcc_assert (TREE_CODE (inner) == COMPONENT_REF); > > - if (MEM_OFFSET (mem) > - && CONST_INT_P (MEM_OFFSET (mem))) > - offset = INTVAL (MEM_OFFSET (mem)); > + if (MEM_OFFSET_KNOWN_P (mem)) > + offset = MEM_OFFSET (mem); > > if (offset >= 0 && len && host_integerp (len, 0)) > length = tree_low_cst (len, 0); > @@ -1295,7 +1294,10 @@ get_memory_rtx (tree exp, tree len) > if (mem_expr != MEM_EXPR (mem)) > { > set_mem_expr (mem, mem_expr); > - set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX); > + if (offset >= 0) > + set_mem_offset (mem, offset); > + else > + clear_mem_offset (mem); > } > } > set_mem_alias_set (mem, 0); > Index: gcc/cfgcleanup.c > =================================================================== > --- gcc/cfgcleanup.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/cfgcleanup.c 2011-07-17 10:38:53.000000000 +0100 > @@ -895,13 +895,15 @@ merge_memattrs (rtx x, rtx y) > { > set_mem_expr (x, 0); > set_mem_expr (y, 0); > - set_mem_offset (x, 0); > - set_mem_offset (y, 0); > + clear_mem_offset (x); > + clear_mem_offset (y); > } > - else if (MEM_OFFSET (x) != MEM_OFFSET (y)) > + else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y) > + || (MEM_OFFSET_KNOWN_P (x) > + && MEM_OFFSET (x) != MEM_OFFSET (y))) > { > - set_mem_offset (x, 0); > - set_mem_offset (y, 0); > + clear_mem_offset (x); > + clear_mem_offset (y); > } > > if (MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y)) > Index: gcc/dwarf2out.c > =================================================================== > --- gcc/dwarf2out.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/dwarf2out.c 2011-07-17 10:38:53.000000000 +0100 > @@ -10453,7 +10453,7 @@ tls_mem_loc_descriptor (rtx mem) > tree base; > dw_loc_descr_ref loc_result; > > - if (MEM_EXPR (mem) == NULL_TREE || MEM_OFFSET (mem) == NULL_RTX) > + if (MEM_EXPR (mem) == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem)) > return NULL; > > base = get_base_address (MEM_EXPR (mem)); > @@ -10466,8 +10466,8 @@ tls_mem_loc_descriptor (rtx mem) > if (loc_result == NULL) > return NULL; > > - if (INTVAL (MEM_OFFSET (mem))) > - loc_descr_plus_const (&loc_result, INTVAL (MEM_OFFSET (mem))); > + if (MEM_OFFSET (mem)) > + loc_descr_plus_const (&loc_result, MEM_OFFSET (mem)); > > return loc_result; > } > Index: gcc/function.c > =================================================================== > --- gcc/function.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/function.c 2011-07-17 10:38:53.000000000 +0100 > @@ -2577,14 +2577,12 @@ assign_parm_find_stack_rtl (tree parm, s > && data->promoted_mode != DECL_MODE (parm)) > { > set_mem_size (stack_parm, GET_MODE_SIZE (data->promoted_mode)); > - if (MEM_EXPR (stack_parm) && MEM_OFFSET (stack_parm)) > + if (MEM_EXPR (stack_parm) && MEM_OFFSET_KNOWN_P (stack_parm)) > { > int offset = subreg_lowpart_offset (DECL_MODE (parm), > data->promoted_mode); > if (offset) > - set_mem_offset (stack_parm, > - plus_constant (MEM_OFFSET (stack_parm), > - -offset)); > + set_mem_offset (stack_parm, MEM_OFFSET (stack_parm) - offset); > } > } > } > @@ -3198,10 +3196,9 @@ assign_parm_setup_stack (struct assign_p > /* ??? This may need a big-endian conversion on sparc64. */ > data->stack_parm > = adjust_address (data->stack_parm, data->nominal_mode, 0); > - if (offset && MEM_OFFSET (data->stack_parm)) > + if (offset && MEM_OFFSET_KNOWN_P (data->stack_parm)) > set_mem_offset (data->stack_parm, > - plus_constant (MEM_OFFSET (data->stack_parm), > - offset)); > + MEM_OFFSET (data->stack_parm) + offset); > } > } > > Index: gcc/print-rtl.c > =================================================================== > --- gcc/print-rtl.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/print-rtl.c 2011-07-17 10:38:53.000000000 +0100 > @@ -597,9 +597,8 @@ print_rtx (const_rtx in_rtx) > if (MEM_EXPR (in_rtx)) > print_mem_expr (outfile, MEM_EXPR (in_rtx)); > > - if (MEM_OFFSET (in_rtx)) > - fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, > - INTVAL (MEM_OFFSET (in_rtx))); > + if (MEM_OFFSET_KNOWN_P (in_rtx)) > + fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx)); > > if (MEM_SIZE_KNOWN_P (in_rtx)) > fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx)); > Index: gcc/reload.c > =================================================================== > --- gcc/reload.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/reload.c 2011-07-17 10:38:53.000000000 +0100 > @@ -6137,8 +6137,8 @@ find_reloads_subreg_address (rtx x, int > > XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset); > PUT_MODE (tem, GET_MODE (x)); > - if (MEM_OFFSET (tem)) > - set_mem_offset (tem, plus_constant (MEM_OFFSET (tem), > offset)); > + if (MEM_OFFSET_KNOWN_P (tem)) > + set_mem_offset (tem, MEM_OFFSET (tem) + offset); > if (MEM_SIZE_KNOWN_P (tem) > && MEM_SIZE (tem) != (HOST_WIDE_INT) outer_size) > set_mem_size (tem, outer_size); > Index: gcc/simplify-rtx.c > =================================================================== > --- gcc/simplify-rtx.c 2011-07-17 10:03:00.000000000 +0100 > +++ gcc/simplify-rtx.c 2011-07-17 10:38:53.000000000 +0100 > @@ -268,7 +268,7 @@ delegitimize_mem_from_attrs (rtx x) > use their base addresses as equivalent. */ > if (MEM_P (x) > && MEM_EXPR (x) > - && MEM_OFFSET (x)) > + && MEM_OFFSET_KNOWN_P (x)) > { > tree decl = MEM_EXPR (x); > enum machine_mode mode = GET_MODE (x); > @@ -321,7 +321,7 @@ delegitimize_mem_from_attrs (rtx x) > { > rtx newx; > > - offset += INTVAL (MEM_OFFSET (x)); > + offset += MEM_OFFSET (x); > > newx = DECL_RTL (decl); > > Index: gcc/var-tracking.c > =================================================================== > --- gcc/var-tracking.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/var-tracking.c 2011-07-17 10:38:53.000000000 +0100 > @@ -365,7 +365,7 @@ typedef const struct value_chain_def *co > #define VTI(BB) ((variable_tracking_info) (BB)->aux) > > /* Macro to access MEM_OFFSET as an HOST_WIDE_INT. Evaluates MEM twice. */ > -#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : > 0) > +#define INT_MEM_OFFSET(mem) (MEM_OFFSET_KNOWN_P (mem) ? MEM_OFFSET (mem) : 0) > > /* Alloc pool for struct attrs_def. */ > static alloc_pool attrs_pool; > Index: gcc/emit-rtl.c > =================================================================== > --- gcc/emit-rtl.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/emit-rtl.c 2011-07-17 10:38:53.000000000 +0100 > @@ -969,9 +969,9 @@ set_reg_attrs_from_value (rtx reg, rtx x > offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x)); > if (MEM_P (x)) > { > - if (MEM_OFFSET (x) && CONST_INT_P (MEM_OFFSET (x))) > - REG_ATTRS (reg) > - = get_reg_attrs (MEM_EXPR (x), INTVAL (MEM_OFFSET (x)) + offset); > + if (MEM_OFFSET_KNOWN_P (x)) > + REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x), > + MEM_OFFSET (x) + offset); > if (MEM_POINTER (x)) > mark_reg_pointer (reg, 0); > } > @@ -1460,14 +1460,13 @@ get_mem_align_offset (rtx mem, unsigned > unsigned HOST_WIDE_INT offset; > > /* This function can't use > - if (!MEM_EXPR (mem) || !MEM_OFFSET (mem) > - || !CONST_INT_P (MEM_OFFSET (mem)) > + if (!MEM_EXPR (mem) || !MEM_OFFSET_KNOWN_P (mem) > || (MAX (MEM_ALIGN (mem), > get_object_alignment (MEM_EXPR (mem), align)) > < align)) > return -1; > else > - return (- INTVAL (MEM_OFFSET (mem))) & (align / BITS_PER_UNIT - 1); > + return (- MEM_OFFSET (mem)) & (align / BITS_PER_UNIT - 1); > for two reasons: > - COMPONENT_REFs in MEM_EXPR can have NULL first operand, > for <variable>. get_inner_reference doesn't handle it and > @@ -1477,12 +1476,10 @@ get_mem_align_offset (rtx mem, unsigned > isn't sufficiently aligned, the object it is in might be. */ > gcc_assert (MEM_P (mem)); > expr = MEM_EXPR (mem); > - if (expr == NULL_TREE > - || MEM_OFFSET (mem) == NULL_RTX > - || !CONST_INT_P (MEM_OFFSET (mem))) > + if (expr == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem)) > return -1; > > - offset = INTVAL (MEM_OFFSET (mem)); > + offset = MEM_OFFSET (mem); > if (DECL_P (expr)) > { > if (DECL_ALIGN (expr) < align) > @@ -1901,12 +1898,24 @@ set_mem_expr (rtx mem, tree expr) > /* Set the offset of MEM to OFFSET. */ > > void > -set_mem_offset (rtx mem, rtx offset) > +set_mem_offset (rtx mem, HOST_WIDE_INT offset) > { > struct mem_attrs attrs; > > attrs = *get_mem_attrs (mem); > - attrs.offset = offset; > + attrs.offset = GEN_INT (offset); > + set_mem_attrs (mem, &attrs); > +} > + > +/* Clear the offset of MEM. */ > + > +void > +clear_mem_offset (rtx mem) > +{ > + struct mem_attrs attrs; > + > + attrs = *get_mem_attrs (mem); > + attrs.offset = NULL_RTX; > set_mem_attrs (mem, &attrs); > } > > Index: gcc/config/mips/mips.c > =================================================================== > --- gcc/config/mips/mips.c 2011-07-17 10:18:59.000000000 +0100 > +++ gcc/config/mips/mips.c 2011-07-17 10:38:53.000000000 +0100 > @@ -13777,13 +13777,9 @@ r10k_safe_address_p (rtx x, rtx insn) > a link-time-constant address. */ > > static bool > -r10k_safe_mem_expr_p (tree expr, rtx offset) > +r10k_safe_mem_expr_p (tree expr, HOST_WIDE_INT offset) > { > - if (expr == NULL_TREE > - || offset == NULL_RTX > - || !CONST_INT_P (offset) > - || INTVAL (offset) < 0 > - || INTVAL (offset) >= int_size_in_bytes (TREE_TYPE (expr))) > + if (offset < 0 || offset >= int_size_in_bytes (TREE_TYPE (expr))) > return false; > > while (TREE_CODE (expr) == COMPONENT_REF) > @@ -13809,7 +13805,9 @@ r10k_needs_protection_p_1 (rtx *loc, voi > if (!MEM_P (mem)) > return 0; > > - if (r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem))) > + if (MEM_EXPR (mem) > + && MEM_OFFSET_KNOWN_P (mem) > + && r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem))) > return -1; > > if (r10k_safe_address_p (XEXP (mem, 0), (rtx) data)) >