On Tue, 19 Mar 2024, Jakub Jelinek wrote: > 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.
Yeah, I was thinking of instead comparing to the effective biggest index supporting the (half) address-space limit but I guess that's what the get_precision check effectively does as well. But yeah, I guess truncating ARRAY_REF indices like we truncate shift amounts is the way to go in the end. For GCC 15 indeed. I've installed the patch as-is. Thanks, Richard. > 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 > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)