This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix array_ref_element_size and friends
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 30 Aug 2004 14:45:23 -0700
- Subject: fix array_ref_element_size and friends
These functions use size_binop to compute their values. Except that
the value here may not be sizetype, which leads to an abort.
It'll not be sizetype in the case that there is a value in a type the
same size and signedness as sizetype, but is not actually sizetype.
The cast to sizetype will be eliminated as useless. Which, given that
the value involved is provably unchanged seems totally reasonable as
far as the optimizers are concerned.
Yet Another Reason why these routines should not be doing any computation
at all, but I didn't have the patience to change that just yet.
This triggered with a Fortran front-end change I have queued.
Tested on i686, alpha, and amd64 linux.
r~
* expr.c (array_ref_element_size): Force aligned_size back to
sizetype.
(component_ref_field_offset): Similarly for aligned_offset.
* tree.c (recompute_tree_invarant_for_addr_expr): Mark raw
low-bound, element-size, field-offset fields rather than
computed values.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.712
diff -c -p -d -r1.712 expr.c
*** expr.c 30 Aug 2004 18:34:32 -0000 1.712
--- expr.c 30 Aug 2004 21:36:13 -0000
*************** array_ref_element_size (tree exp)
*** 5481,5488 ****
/* If a size was specified in the ARRAY_REF, it's the size measured
in alignment units of the element type. So multiply by that value. */
if (aligned_size)
! return size_binop (MULT_EXPR, aligned_size,
! size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
/* Otherwise, take the size from that of the element type. Substitute
any PLACEHOLDER_EXPR that we have. */
--- 5481,5494 ----
/* If a size was specified in the ARRAY_REF, it's the size measured
in alignment units of the element type. So multiply by that value. */
if (aligned_size)
! {
! /* ??? tree_ssa_useless_type_conversion will eliminate casts to
! sizetype from another type of the same width and signedness. */
! if (TREE_TYPE (aligned_size) != sizetype)
! aligned_size = fold_convert (sizetype, aligned_size);
! return size_binop (MULT_EXPR, aligned_size,
! size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
! }
/* Otherwise, take the size from that of the element type. Substitute
any PLACEHOLDER_EXPR that we have. */
*************** component_ref_field_offset (tree exp)
*** 5541,5548 ****
in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that
value. */
if (aligned_offset)
! return size_binop (MULT_EXPR, aligned_offset,
! size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
/* Otherwise, take the offset from that of the field. Substitute
any PLACEHOLDER_EXPR that we have. */
--- 5547,5560 ----
in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT. So multiply by that
value. */
if (aligned_offset)
! {
! /* ??? tree_ssa_useless_type_conversion will eliminate casts to
! sizetype from another type of the same width and signedness. */
! if (TREE_TYPE (aligned_offset) != sizetype)
! aligned_offset = fold_convert (sizetype, aligned_offset);
! return size_binop (MULT_EXPR, aligned_offset,
! size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
! }
/* Otherwise, take the offset from that of the field. Substitute
any PLACEHOLDER_EXPR that we have. */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.417
diff -c -p -d -r1.417 tree.c
*** tree.c 27 Aug 2004 00:55:38 -0000 1.417
--- tree.c 30 Aug 2004 21:36:14 -0000
*************** do { tree _node = (NODE); \
*** 2252,2266 ****
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
{
UPDATE_TITCSE (TREE_OPERAND (node, 1));
! UPDATE_TITCSE (array_ref_low_bound (node));
! UPDATE_TITCSE (array_ref_element_size (node));
}
/* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
FIELD_DECL, apparently. The G++ front end can put something else
there, at least temporarily. */
else if (TREE_CODE (node) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! UPDATE_TITCSE (component_ref_field_offset (node));
else if (TREE_CODE (node) == BIT_FIELD_REF)
UPDATE_TITCSE (TREE_OPERAND (node, 2));
}
--- 2252,2271 ----
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
{
UPDATE_TITCSE (TREE_OPERAND (node, 1));
! if (TREE_OPERAND (node, 2))
! UPDATE_TITCSE (TREE_OPERAND (node, 2));
! if (TREE_OPERAND (node, 3))
! UPDATE_TITCSE (TREE_OPERAND (node, 3));
}
/* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
FIELD_DECL, apparently. The G++ front end can put something else
there, at least temporarily. */
else if (TREE_CODE (node) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! {
! if (TREE_OPERAND (node, 2))
! UPDATE_TITCSE (TREE_OPERAND (node, 2));
! }
else if (TREE_CODE (node) == BIT_FIELD_REF)
UPDATE_TITCSE (TREE_OPERAND (node, 2));
}