[PATCH] SCEV should use NSW to get trip count for loop with nonunit stride.

Andrew Trick atrick at apple.com
Fri Oct 18 09:43:52 PDT 2013

I'm not able to defend SCEV's current inability to handle loops with non-unit stride. In other cases, SCEV is rightly conservative in ignoring NSW, and I've been defending that approach, but this particular case keeps coming up and I don't have a good answer.

For example:
void foo(int n, int *x) {
 for (int i = 0; i < n; i += 3) {
   x[i] = i;
   x[i+1] = i+1;
   x[i+2] = i+2;

In ScalarEvolution::HowManyLessThans we ignore the NSW flag when considering whether the loop counter increment may skip the loop test. However, if signed-wrap occurs, the result of the loop test is undefined. Providing a loop trip count to downstream optimization seems harmless. The only assumption we've made is that if executing the loop causes the counter to wrap, then the loop test will fail. In practice the test may not fail, but the assumption is still valid.

There is one cryptic test case (below) attempting to enforce the conservative behavior. But it doesn't reveal why this case is problematic. I haven't been able to pick up clues from old bugs either. I know several related bugs in this area have been fixed since this test case was added. My guess is that either this was test case was preemtive or the original problem was fixed elsewhere.

; Be careful with this one. If %n is INT4_MAX, %i.next will wrap. The nsw bit
; says that the result is undefined, but ScalarEvolution must respect that
; subsequent passes may result the undefined behavior in predictable ways.
; CHECK: Determining loop execution counts for: @nsw_step2
; CHECK: Loop %loop: Unpredictable backedge-taken count.
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
define void @nsw_step2(i4 %n) {
  %s = icmp sgt i4 %n, 0
  br i1 %s, label %loop, label %exit
  %i = phi i4 [ 0, %entry ], [ %i.next, %loop ]
  %i.next = add nsw i4 %i, 2
  %t = icmp slt i4 %i.next, %n
  br i1 %t, label %loop, label %exit
  ret void
-------------- next part --------------
A non-text attachment was scrubbed...
Name: use-nsw-pos-stride.patch
Type: application/octet-stream
Size: 3619 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131018/b6e3c7b4/attachment.obj>

More information about the llvm-commits mailing list