On Mon, Apr 11, 2022 at 12:44:32AM +0200, Jan Hubicka via Gcc-patches wrote: > Hi, > the testcase triggers ICE since computation overflows on two accesses > that are very far away d->b[-144115188075855873] and d->b[144678138029277184]. > This patch makes the relevant part of modref to use poly_offset_int. > > It is kind of weird to store bit offsets into poly_int64 but it is what > alias oracle does. There are some other places where computations are > done that may overflow, I will fix them incrementally (it is not > completely mechanical due to signed/unsigned info). > > Bootstrapped/regtested x86_64-linux. I plan to commit it tomorrow if > there are no complains. > > gcc/ChangeLog: > > 2022-04-11 Jan Hubicka <hubi...@ucw.cz> >
Please add PR ipa/103818 so that it will link to bugzilla. > * ipa-modref-tree.cc (modref_access_node::closer_pair_p): Use > poly_offset_int to avoid overflow. > (modref_access_node::update2): Likewise. > > gcc/testsuite/ChangeLog: > > 2022-04-11 Jan Hubicka <hubi...@ucw.cz> > > * gcc.c-torture/compile/103818.c: New test. > > diff --git a/gcc/ipa-modref-tree.cc b/gcc/ipa-modref-tree.cc > index f19af8c2b55..44cb645954f 100644 > --- a/gcc/ipa-modref-tree.cc > +++ b/gcc/ipa-modref-tree.cc > @@ -267,34 +267,42 @@ modref_access_node::closer_pair_p (const > modref_access_node &a1, > > > /* Now compute distance of the intervals. */ > - poly_int64 dist1, dist2; > + poly_offset_int dist1, dist2; > if (known_le (offseta1, offsetb1)) > { > if (!known_size_p (a1.max_size)) > dist1 = 0; > else > - dist1 = offsetb1 - offseta1 - a1.max_size; > + dist1 = (poly_offset_int)offsetb1 > + - (poly_offset_int)offseta1 > + - (poly_offset_int)a1.max_size; I think we usually put a space between the (type) and following expression after it. > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/compile/103818.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile { target lp64 } } */ > +struct a { > + int b[0]; > +} c(struct a *d) { > + d->b[0] = d->b[-144115188075855873] + d->b[11] * d->b[2] + > + d->b[0] % d->b[1025] + d->b[5]; > + d->b[0] = > + d->b[144678138029277184] + d->b[0] & d->b[-3] * d->b[053] + d->b[7] ^ > + d->b[-9] + d->b[14] + d->b[9] % d->b[49] + d->b[024] + d->b[82] & > + d->b[4096]; > +} > +void main() {} Can you please slightly fix up the testcase? I mean e.g. the struct a definition in return type of c when it doesn't return anything or main returning void (when it isn't needed at all) are unnecessary, and the lp64 requirement can be avoided by using LL suffix on the 2 large indexes. Also, having the b[0] array and b[0] accesses isn't necessary for the ICE. So say: struct A { int b[1]; }; void foo (struct A *d) { d->b[0] = d->b[-144115188075855873LL] + d->b[11] * d->b[2] + d->b[0] % d->b[1025] + d->b[5]; d->b[0] = d->b[144678138029277184LL] + d->b[0] & d->b[-3] * d->b[053] + d->b[7] ^ d->b[-9] + d->b[14] + d->b[9] % d->b[49] + d->b[024] + d->b[82] & d->b[4096]; } ? Sure, the testcase is still heavily invalid, but slightly less so. Otherwise LGTM, thanks for fixing it. Jakub