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