Properly fold ARRAY_REF in expand_expr
Richard Kenner
kenner@vlsi1.ultra.nyu.edu
Wed Nov 24 22:51:00 GMT 2004
I can't read my notes as to which ACATS test this fixes, but I know it was one
of them. The problem here is that the folding of ARRAY_REF when the
lower bound is nonzero if subtracting the bound from the index it's looking
for and that's wrong. Do you agree?
Tested on x86_64-linux-gnu.
2004-11-24 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (expand_expr_real_1, case ARRAY_REF): Properly fold with
non-zero lower bound.
*** expr.c 24 Nov 2004 11:41:29 -0000 1.743
--- expr.c 24 Nov 2004 14:54:53 -0000
*************** expand_expr_real_1 (tree exp, rtx target
*** 6739,6758 ****
{
tree array = TREE_OPERAND (exp, 0);
! tree low_bound = array_ref_low_bound (exp);
! tree index = convert (sizetype, TREE_OPERAND (exp, 1));
! HOST_WIDE_INT i;
!
! gcc_assert (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE);
!
! /* Optimize the special-case of a zero lower bound.
!
! We convert the low_bound to sizetype to avoid some problems
! with constant folding. (E.g. suppose the lower bound is 1,
! and its mode is QI. Without the conversion, (ARRAY
! +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
! +INDEX), which becomes (ARRAY+255+INDEX). Oops!) */
!
! if (! integer_zerop (low_bound))
! index = size_diffop (index, convert (sizetype, low_bound));
/* Fold an expression like: "foo"[2].
--- 6745,6749 ----
{
tree array = TREE_OPERAND (exp, 0);
! tree index = TREE_OPERAND (exp, 1);
/* Fold an expression like: "foo"[2].
*************** expand_expr_real_1 (tree exp, rtx target
*** 6781,6797 ****
&& TREE_CODE (array) == CONSTRUCTOR
&& ! TREE_SIDE_EFFECTS (array)
! && TREE_CODE (index) == INTEGER_CST
! && 0 > compare_tree_int (index,
! list_length (CONSTRUCTOR_ELTS
! (TREE_OPERAND (exp, 0)))))
{
tree elem;
! for (elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
! i = TREE_INT_CST_LOW (index);
! elem != 0 && i != 0; i--, elem = TREE_CHAIN (elem))
;
! if (elem)
return expand_expr (fold (TREE_VALUE (elem)), target, tmode,
modifier);
--- 6772,6785 ----
&& TREE_CODE (array) == CONSTRUCTOR
&& ! TREE_SIDE_EFFECTS (array)
! && TREE_CODE (index) == INTEGER_CST)
{
tree elem;
! for (elem = CONSTRUCTOR_ELTS (array);
! (elem && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
! elem = TREE_CHAIN (elem))
;
! if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
return expand_expr (fold (TREE_VALUE (elem)), target, tmode,
modifier);
More information about the Gcc-patches
mailing list