summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/alias.c72
-rw-r--r--gcc/builtins.c10
-rw-r--r--gcc/cfgcleanup.c12
-rw-r--r--gcc/config/mips/mips.c12
-rw-r--r--gcc/doc/rtl.texi8
-rw-r--r--gcc/dwarf2out.c6
-rw-r--r--gcc/emit-rtl.c33
-rw-r--r--gcc/emit-rtl.h5
-rw-r--r--gcc/function.c11
-rw-r--r--gcc/print-rtl.c5
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/rtl.h8
-rw-r--r--gcc/simplify-rtx.c4
-rw-r--r--gcc/var-tracking.c2
15 files changed, 142 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71049d0cbb7..d4bd6d765f6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,41 @@
2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
+ * 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.
+
+2011-07-19 Richard Sandiford <rdsandiford@googlemail.com>
+
* doc/rtl.texi (MEM_SIZE_KNOWN_P): Document.
(MEM_SIZE): Change from returning an rtx to returning a HOST_WIDE_INT.
* rtl.h (MEM_SIZE_KNOWN_P): New macro.
diff --git a/gcc/alias.c b/gcc/alias.c
index 1d74e341187..ef624a1bfe4 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -162,7 +162,6 @@ static const_rtx fixed_scalar_and_varying_struct_p (const_rtx, const_rtx, rtx, r
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 mem)
/* 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 mem)
/* 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, const_rtx y, bool loop_invariant)
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, const_rtx y, bool loop_invariant)
/* 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, const_rtx y, bool loop_invariant)
/* 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, const_rtx y, bool loop_invariant)
/* 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. */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6818fe20d86..afe1ed05a2f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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);
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index f41379114e2..7f72e683482 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -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))
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 06a13f8d782..89371734d4e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -13765,13 +13765,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)
@@ -13797,7 +13793,9 @@ r10k_needs_protection_p_1 (rtx *loc, void *data)
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))
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 0d348dc6b56..0d60594e38e 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -409,9 +409,15 @@ and @code{TREE_OPERAND (@var{x}, 0)} contains the declaration,
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})
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 44a27584b65..6046ba9c6ab 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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;
}
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 88624904f01..fd1e5dbe6c3 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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 int align)
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 int align)
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);
}
diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
index cc145b96e1c..bc91193fb62 100644
--- a/gcc/emit-rtl.h
+++ b/gcc/emit-rtl.h
@@ -33,7 +33,10 @@ extern void set_mem_addr_space (rtx, addr_space_t);
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);
diff --git a/gcc/function.c b/gcc/function.c
index 9e65bfd0129..361a8dce197 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2577,14 +2577,12 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
&& 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_parm_data_all *all, tree parm,
/* ??? 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);
}
}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index bff2483d14b..8e80630fbb3 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -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));
diff --git a/gcc/reload.c b/gcc/reload.c
index 5f48ae7277b..b5e991e386d 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -6137,8 +6137,8 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
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);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 7e09a1103bc..2ef6d1e32aa 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1302,9 +1302,11 @@ do { \
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)
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 82b818b02f1..2d7d8dd03f9 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -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);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index ce9aec4eebf..d5a45483ab7 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -365,7 +365,7 @@ typedef const struct value_chain_def *const_value_chain;
#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;