On Tue, Mar 19, 2024 at 03:47:37PM +0100, Richard Biener wrote: > The following fixes bogus truncation of a value-range for an int128 > array index when computing the maximum extent for a variable array > reference. Instead of possibly slowing things down by using > widest_int the following makes sure the range bounds fit within > the constraints offset_int were designed for.
Perhaps you could use wide_int/poly_wide_int with precision of offset_int if it is at most 64-bit precision and twice that precision otherwise. I think large BITINT_TYPEs shouldn't be a problem since r14-7200, so another fix might to truncate at gimplification time ARRAY_REF indexes wider than sizetype to sizetype. Maybe GCC 15-ish material though. Anyway, guess your patch is ok as is too. > PR middle-end/113396 > * tree-dfa.cc (get_ref_base_and_extent): Use index range > bounds only if they fit within the address-range constraints > of offset_int. > > * gcc.dg/torture/pr113396.c: New testcase. > --- > gcc/testsuite/gcc.dg/torture/pr113396.c | 19 +++++++++++++++++++ > gcc/tree-dfa.cc | 6 ++++-- > 2 files changed, 23 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr113396.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr113396.c > b/gcc/testsuite/gcc.dg/torture/pr113396.c > new file mode 100644 > index 00000000000..585f717bdda > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr113396.c > @@ -0,0 +1,19 @@ > +/* { dg-do run } */ > +/* { dg-require-effective-target int128 } */ > + > +unsigned char m[] = {5, 79, 79, 79, 79}; > +__int128 p; > +int main() > +{ > + int g1 = 0; > + p = 0; > + for (int aj = 0; aj < 256; aj++) > + { > + m[0] = -4; > + for (; p >= 0; p -= 1) { > + g1 = m[p]; > + } > + } > + if (g1 != 0xfc) > + __builtin_abort(); > +} > diff --git a/gcc/tree-dfa.cc b/gcc/tree-dfa.cc > index cbd3774b21f..93e53b29a6d 100644 > --- a/gcc/tree-dfa.cc > +++ b/gcc/tree-dfa.cc > @@ -549,7 +549,8 @@ get_ref_base_and_extent (tree exp, poly_int64 *poffset, > /* Try to constrain maxsize with range information. */ > offset_int omax > = offset_int::from (max, TYPE_SIGN (TREE_TYPE (index))); > - if (known_lt (lbound, omax)) > + if (wi::get_precision (max) <= ADDR_MAX_BITSIZE > + && known_lt (lbound, omax)) > { > poly_offset_int rmaxsize; > rmaxsize = (omax - lbound + 1) > @@ -567,7 +568,8 @@ get_ref_base_and_extent (tree exp, poly_int64 *poffset, > /* Try to adjust bit_offset with range information. */ > offset_int omin > = offset_int::from (min, TYPE_SIGN (TREE_TYPE (index))); > - if (known_le (lbound, omin)) > + if (wi::get_precision (min) <= ADDR_MAX_BITSIZE > + && known_le (lbound, omin)) > { > poly_offset_int woffset > = wi::sext (omin - lbound, > -- > 2.35.3 Jakub