https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107986
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #2)
> (In reply to Richard Biener from comment #1)
> >
> > void bar ();
> > void foo (int *a)
> > {
> > int qa = 0;
> > for (int i = 0; i < 3; i++)
> > if (a[i])
> > a[qa++] = 0;
> > if (qa > 3)
> > bar ();
> > }
> >
> > where we should be able to eliminate the call to bar ().
>
> What is interesting is we can optimize away the call to bar in this slightly
> modified case during vrp2:
> void bar ();
> bool cond;
> void foo (int *a)
> {
> int qa = 0;
> for (int i = 0; i < 3; i++)
> if (cond)
> a[qa++] = 0;
> if (qa > 3)
> bar ();
> }
>
> But I don't see why having the load inside the loop would make a difference
> ....
It's because we can jump-thread the invariant condition. The most
canonical testcase would be sth like
int foo (int *a)
{
int qa = 0;
for (int i = 0; i < 3; i++)
if (a[i++])
qa++;
if (qa < 0 || qa > 3)
bar ();
return qa;
}