[PATCH] D22377: [SCEV] trip count calculation for loops with unknown stride
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 22 15:25:50 PDT 2016
sanjoy added a comment.
Hi Pankaj,
In https://reviews.llvm.org/D22377#493355, @pankajchawla wrote:
>
> Regarding the loop entry guard check:
> Please note that I haven't changed this check and I believe the
> original check is correct. The loop entry guard tells us whether the
Yes, for what it is doing it is correct.
> loop will be executed at least once. It cannot tell us whether the
> loop will be executed more than once. Please also note that the
> backedge taken count for the loop mentioned in the description is:
> ((-1 + %n) /u %s)
> A more generic formula with unknown initial value is: ((-1 + %n -
> %init) /u %s)
>
> Now lets go through your examples:
>
> > The example I was thinking of was:
>
> >
>
> > for (unsigned i = 1; i < 5; i += (-2)) {
>
> > }
>
> >
>
> >
>
> > ==
>
> >
>
> > i = 1;
>
> > if (i < 5) {
>
> > do {
>
> > i += (-2); // NUW
>
> > } while (i u< 5);
>
> > }
>
> >
>
> >
>
> > then the pre-increment IV is {1,+,-2}. It does not unsigned-overflow on the first increment (1 + (-2) == -1), and then it exits the loop.
>
>
> The backedge taken count for this loop according to the formula above will be:
> (5 -1 -1) /u (-2) ==> 0
>
> So it is correct.
I was trying to come up with examples where (based on the change
description):
- The add recurrence, AR, being compared to in the loop exit check is legitimately nuw or nsw
- The loop decrement amount (stride) is negative
- The loop is guarded by "AR->getStart() - AR->getStride()"
If I understand you correctly, you're saying that even if the stride
is negative the expression that computes the backedge taken count is
valid. That may be correct (I'll re-review with that understanding),
but then the change description needs to say that instead of saying
"then we can assume the stride to be positive." Is that a correct
assessment?
Btw, if you think a real-time chat can help and are in PDT, we can
talk about this on the #llvm IRC channel on Monday.
> Here's your second example-
>
> >
>
> >
>
> > i = INT_MIN
>
> > if (i s< 5) {
>
> > do {
>
> > i += (-1);
>
> > } while (i s< 5);
>
> > }
>
> >
>
>
> I believe this loop has undefined behavior since adding INT_MIN
> and -1 leads to signed underflow.
I was using that as a shorthand for LLVM IR. :) You could have
something like:
i = INT_MIN
if (i s< 5) {
do {
i = wrapping_add(i, -1);
} while (i s< 5);
}
with
int wrapping_add(int a, int b) {
return (int)(((unsigned)a) + ((unsigned)b));
}
> I guess my point is that once we have checked the loop entry guard, single trip loops will be handled just as well as multi-trip loops.
> Please let me know if I am still missing anything.
>
> Please note that the nsw marking on the IV AddRec is quite conservative. If I initialize the IV to anything else than 0 in the original loop, we lose the marking and the backedge taken count is not computed.
https://reviews.llvm.org/D22377
More information about the llvm-commits
mailing list