[llvm-commits] [PATCH] Teach SCEV about <= comparisons for trip count computation

Nick Lewycky nlewycky at google.com
Wed Sep 19 19:47:22 PDT 2012


On 30 August 2012 23:51, Nick Lewycky <nicholas at mxc.ca> wrote:

> Tobias von Koch wrote:
>
>> Dear all,
>>
>> SCEV currently has a weakness in the loop trip count computation code
>> when it comes to loops whose bounds are determined by a <= comparison.
>>
>> Take the example from the attached test case:
>>
>> int Proc_8 (int arg1)
>> {
>>    int result = 0;
>>    for (int i = arg1; i <= arg1 + 5; ++i)
>>      result++;
>>    return result;
>> }
>>
>> GCC is able to determine the trip count exactly and translates this
>> whole function into a single instruction (+ return) on PPC.
>>
>> LLVM fails on two fronts:
>> - First of all, it can't deal with the <= comparison because the code to
>> handle this isn't there. It was added in an earlier version of SCEV
>> years ago but then reverted alongside a lot of other (buggy) code. The
>> attached patch fixes this.
>> - Secondly, even once the patch has been applied, LLVM can only derive a
>> smax() expression for the trip count of this loop. While this is a lot
>> better already, it's still not an exact number. I get the impression
>> that this has something to do with the 'nsw' flag on the original
>> addition not being propagated through the SCEV analysis, but I'm not
>> entirely sure here.
>>
>
> These two issues are related. You're right that we aren't getting the
> 'nsw' information to where scev needs it, though we have to be very careful
> when doing that.
>
> Because we aren't, your patch miscompiles this function:
>   unsigned char test(unsigned char n) {
>     unsigned char i;
>     for (i = 0; i <= n; ++i) {
>     }
>     return i;
>   }
> where 'n' == 255, because the loop would be infinite and we make it return
> zero. (Yes this may be a valid transform for certain versions of C and C++
> but it isn't valid in LLVM IR at this time.)
>
>
>  The patch passes all regression tests and the nightly test suite. I do
>> have one worry about the line marked with a 'FIXME', though. Is it
>> necessary to check for overflow here? Can this be done using the same
>> method as in ScalarEvolution::getBECount, i.e. zero-extend to larger
>> type, add, compare results?
>>
>
> No, even a zero-extended computation would not correctly model the
> infinite loop.
>
> I don't know how we ought to fix this.
>

Some thoughts! Consider the loop:

  for (int i = 0; i <= n; ++i) {
    x += 7;
  }
  use(x);

What's the trip count? Right now it's CouldNotCompute, and that's the ideal
answer given the SCEV expressions that exist today. What is it
mathematically, ignoring no-signed-wrapping? It's an infinite loop if n ==
INT_MAX otherwise the trip count is n. Note that it isn't undefined when n
== INT_MAX, it's defined to be an infinite loop (we have a
language-specific pass to eliminate such infinite loops with no
side-effects, but we won't do it here).

Continuing to keep the no-signed-wrapping aside, what about x? To start,
exit-value-of(x) = starting-value-of(x) + 7 * (infinite loop if n ==
INT_MAX, otherwise n), but that expression simplifies. Implicit in the
question "exit-value-of(x)" is the assumption that the loop wasn't infinite
after all, so it's exit-value-of(x) = starting-value-of(x) + 7 * n.

So it seems like we don't really need nsw here, we could simplify this away
by adding a new SCEV expression that is conditionally an infinite loop. We
could teach the SCEV expander to emit an infinite loop and a branch to it.
It's not clear to me how this works though -- what does it mean to have "X
+ 7 * (infinite loop)" in a scev expression? Consider the next loop:

  for (int i = 0; i <= n; ++i) {
    x += 7;
    for (j = i; j <= n; ++j) {
      y += x + 1;
    }
    use(y);
  }

How do we evaluate y at the point it's used? It hasn't lost its
"potentially-unreachable"ness yet.

And a few more questions, like how does this expression simplify? Can we
always hoist out the potentially-infinite part to the outer-most level? Do
folks think this new expression is sensible?

Nick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120919/93c612d0/attachment.html>


More information about the llvm-commits mailing list