> > Sure, no opposition by me to applying the whole set of patches. > > Done now.
This has introduced a couple of ACATS failures on x86: FAIL: c52102a FAIL: c52102c The problem is that a builtin_memmove is wrongly folded into an assignment between MEM_EXPRs, although source and destination are slices which overlap. In fold_builtin_memory_op: (gdb) p debug_generic_expr(destvar) a[0 ...]{lb: 4294967292 sz: 4} $14 = void (gdb) p debug_generic_expr(dest_base) a $15 = void (gdb) p dest_offset $16 = -137438953344 get_ref_base_and_extent (unlike get_inner_reference) doesn't correctly compute the offset for ARRAY_REF/ARRAY_RANGE_REF. The code is also duplicated in fold_const_aggregate_ref_1. Fixing this yields another ACATS failure: FAIL: cd2a31a because fold_array_ctor_reference needs to be adjusted backwards for the now correct offset computed by get_ref_base_and_extent. Tentative fix attached. Tested on x86_64-suse-linux and i586-suse-linux. 2012-05-07 Eric Botcazou <ebotca...@adacore.com> * tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset computation using the precision of the index type. * gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise. (fold_array_ctor_reference): Do index computations in the index type. -- Eric Botcazou
Index: gimple-fold.c =================================================================== --- gimple-fold.c (revision 187216) +++ gimple-fold.c (working copy) @@ -2745,7 +2745,7 @@ fold_array_ctor_reference (tree type, tr double_int low_bound, elt_size; double_int index, max_index; double_int access_index; - tree domain_type = NULL_TREE; + tree domain_type = NULL_TREE, index_type = NULL_TREE; HOST_WIDE_INT inner_offset; /* Compute low bound and elt size. */ @@ -2755,6 +2755,7 @@ fold_array_ctor_reference (tree type, tr { /* Static constructors for variably sized objects makes no sense. */ gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST); + index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type)); low_bound = tree_to_double_int (TYPE_MIN_VALUE (domain_type)); } else @@ -2778,6 +2779,10 @@ fold_array_ctor_reference (tree type, tr access_index = double_int_udiv (uhwi_to_double_int (offset / BITS_PER_UNIT), elt_size, TRUNC_DIV_EXPR); access_index = double_int_add (access_index, low_bound); + if (index_type) + access_index = double_int_ext (access_index, + TYPE_PRECISION (index_type), + TYPE_UNSIGNED (index_type)); /* And offset within the access. */ inner_offset = offset % (double_int_to_uhwi (elt_size) * BITS_PER_UNIT); @@ -2788,6 +2793,11 @@ fold_array_ctor_reference (tree type, tr return NULL_TREE; index = double_int_sub (low_bound, double_int_one); + if (index_type) + index = double_int_ext (index, + TYPE_PRECISION (index_type), + TYPE_UNSIGNED (index_type)); + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) { /* Array constructor might explicitely set index, or specify range @@ -2805,7 +2815,14 @@ fold_array_ctor_reference (tree type, tr } } else - max_index = index = double_int_add (index, double_int_one); + { + index = double_int_add (index, double_int_one); + if (index_type) + index = double_int_ext (index, + TYPE_PRECISION (index_type), + TYPE_UNSIGNED (index_type)); + max_index = index; + } /* Do we have match? */ if (double_int_cmp (access_index, index, 1) >= 0 @@ -2960,18 +2977,23 @@ fold_const_aggregate_ref_1 (tree t, tree if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME && valueize && (idx = (*valueize) (TREE_OPERAND (t, 1))) - && host_integerp (idx, 0)) + && TREE_CODE (idx) == INTEGER_CST) { tree low_bound, unit_size; + double_int doffset; /* If the resulting bit-offset is constant, track it. */ if ((low_bound = array_ref_low_bound (t), - host_integerp (low_bound, 0)) + TREE_CODE (low_bound) == INTEGER_CST) && (unit_size = array_ref_element_size (t), - host_integerp (unit_size, 1))) + host_integerp (unit_size, 1)) + && (doffset = double_int_sext + (double_int_sub (TREE_INT_CST (idx), + TREE_INT_CST (low_bound)), + TYPE_PRECISION (TREE_TYPE (idx))), + double_int_fits_in_shwi_p (doffset))) { - offset = TREE_INT_CST_LOW (idx); - offset -= TREE_INT_CST_LOW (low_bound); + offset = double_int_to_shwi (doffset); offset *= TREE_INT_CST_LOW (unit_size); offset *= BITS_PER_UNIT; Index: tree-dfa.c =================================================================== --- tree-dfa.c (revision 187216) +++ tree-dfa.c (working copy) @@ -814,21 +814,24 @@ get_ref_base_and_extent (tree exp, HOST_ { tree index = TREE_OPERAND (exp, 1); tree low_bound, unit_size; + double_int doffset; /* If the resulting bit-offset is constant, track it. */ if (TREE_CODE (index) == INTEGER_CST - && host_integerp (index, 0) && (low_bound = array_ref_low_bound (exp), - host_integerp (low_bound, 0)) + TREE_CODE (low_bound) == INTEGER_CST) && (unit_size = array_ref_element_size (exp), - host_integerp (unit_size, 1))) + host_integerp (unit_size, 1)) + && (doffset = double_int_sext + (double_int_sub (TREE_INT_CST (index), + TREE_INT_CST (low_bound)), + TYPE_PRECISION (TREE_TYPE (index))), + double_int_fits_in_shwi_p (doffset))) { - HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index); - - hindex -= TREE_INT_CST_LOW (low_bound); - hindex *= TREE_INT_CST_LOW (unit_size); - hindex *= BITS_PER_UNIT; - bit_offset += hindex; + HOST_WIDE_INT hoffset = double_int_to_shwi (doffset); + hoffset *= TREE_INT_CST_LOW (unit_size); + hoffset *= BITS_PER_UNIT; + bit_offset += hoffset; /* An array ref with a constant index up in the structure hierarchy will constrain the size of any variable array ref