===================================================================
@@ -1569,7 +1569,7 @@ get_mem_align_offset (rtx mem, unsigned
set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
HOST_WIDE_INT bitpos)
{
- HOST_WIDE_INT apply_bitpos = 0;
+ tree expr = NULL_TREE;
tree type;
struct mem_attrs attrs, *defattrs, *refattrs;
addr_space_t as;
@@ -1679,11 +1679,7 @@ set_mem_attributes_minus_bitpos (rtx ref
attrs.align = MAX (attrs.align, TYPE_ALIGN (type));
/* If the size is known, we can set that. */
- if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
- {
- attrs.size_known_p = true;
- attrs.size = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
- }
+ tree new_size = TYPE_SIZE_UNIT (type);
/* If T is not a type, we may be able to deduce some more information about
the expression. */
@@ -1738,17 +1734,10 @@ set_mem_attributes_minus_bitpos (rtx ref
/* If this is a decl, set the attributes of the MEM from it. */
if (DECL_P (t))
{
- attrs.expr = t;
+ expr = t;
attrs.offset_known_p = true;
attrs.offset = 0;
- apply_bitpos = bitpos;
- if (DECL_SIZE_UNIT (t) && host_integerp (DECL_SIZE_UNIT (t), 1))
- {
- attrs.size_known_p = true;
- attrs.size = tree_low_cst (DECL_SIZE_UNIT (t), 1);
- }
- else
- attrs.size_known_p = false;
+ new_size = DECL_SIZE_UNIT (t);
attrs.align = DECL_ALIGN (t);
align_computed = true;
}
@@ -1770,10 +1759,9 @@ set_mem_attributes_minus_bitpos (rtx ref
else if (TREE_CODE (t) == COMPONENT_REF
&& ! DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
{
- attrs.expr = t;
+ expr = t;
attrs.offset_known_p = true;
attrs.offset = 0;
- apply_bitpos = bitpos;
/* ??? Any reason the field size would be different than
the size we got from the type? */
}
@@ -1812,7 +1800,7 @@ set_mem_attributes_minus_bitpos (rtx ref
if (DECL_P (t2))
{
- attrs.expr = t2;
+ expr = t2;
attrs.offset_known_p = false;
if (host_integerp (off_tree, 1))
{
@@ -1824,18 +1812,16 @@ set_mem_attributes_minus_bitpos (rtx ref
align_computed = true;
attrs.offset_known_p = true;
attrs.offset = ioff;
- apply_bitpos = bitpos;
}
}
else if (TREE_CODE (t2) == COMPONENT_REF)
{
- attrs.expr = t2;
+ expr = t2;
attrs.offset_known_p = false;
if (host_integerp (off_tree, 1))
{
attrs.offset_known_p = true;
attrs.offset = tree_low_cst (off_tree, 1);
- apply_bitpos = bitpos;
}
/* ??? Any reason the field size would be different than
the size we got from the type? */
@@ -1846,10 +1832,9 @@ set_mem_attributes_minus_bitpos (rtx ref
else if (TREE_CODE (t) == MEM_REF
|| TREE_CODE (t) == TARGET_MEM_REF)
{
- attrs.expr = t;
+ expr = t;
attrs.offset_known_p = true;
attrs.offset = 0;
- apply_bitpos = bitpos;
}
if (!align_computed)
@@ -1861,17 +1846,22 @@ set_mem_attributes_minus_bitpos (rtx ref
else
as = TYPE_ADDR_SPACE (type);
- /* If we modified OFFSET based on T, then subtract the outstanding
- bit position offset. Similarly, increase the size of the accessed
- object to contain the negative offset. */
- if (apply_bitpos)
+ if (expr)
{
- gcc_assert (attrs.offset_known_p);
- attrs.offset -= apply_bitpos / BITS_PER_UNIT;
- if (attrs.size_known_p)
- attrs.size += apply_bitpos / BITS_PER_UNIT;
+ attrs.expr = expr;
+ /* If we modified OFFSET based on T, then subtract the outstanding
+ bit position offset. */
+ if (attrs.offset_known_p)
+ attrs.offset -= bitpos / BITS_PER_UNIT;
}
-
+ if (host_integerp (new_size, 1))
+ {
+ attrs.size_known_p = true;
+ /* Include the outstanding bit offset in the size, so that the
+ initial reference includes the leading gap and T. */
+ attrs.size = tree_low_cst (new_size, 1) + bitpos / BITS_PER_UNIT;
+ }
+
/* Now set the attributes we computed above. */
attrs.addrspace = as;
set_mem_attrs (ref, &attrs);