[PATCH] D22377: [SCEV] trip count calculation for loops with unknown stride

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 21 15:55:14 PDT 2016


sanjoy added a comment.

Hi Pankaj,

In https://reviews.llvm.org/D22377#485645, @pankajchawla wrote:

> loopHasNoAbonormalExits() calls isGuaranteedToTransferExecutionToSuccessor() which checks for volatile loads/stores. This function also has a comment inside implying that this function checks for side effects. What other checks do we need? I don't know what it takes to prove that the loop has no side effects. Can you please give me some pointers?


You need to make sure that there are no volatile loads or stores, and no function calls that may write memory.

It is possible that isGuaranteedToTransferExecutionToSuccessor incidentally checks for the same thing; but I'd prefer an explicit loopHasNoSideEffects() that checks that the only instructions in the loop returning true for mayHaveSideEffects() are non-volatile stores non atomic stores.

> > - It looks like you're saying if `Start` - `Stride` < `RHS` then the loop cannot be a single iteration loop.  I think that is incorrect, what if we have:

> 

> >   - `Start` = `-1`, `Stride` = `-2`, `RHS` = `5` for an unsigned compare? `Start` - `Stride` = `1` which is u< `RHS`, but if the backedge is controlled by `{-1,+,-2}` u< `5` then it won't be taken even once.

> 

> >   - `Start` = `INT_MAX`, `Stride` = `-1`, `RHS` = `5` for a signed compare? `Start` - `Stride` = `INT_MIN` which is s< `RHS`, but if the backedge is controlled by `{INT_MAX,+,-1}` s< `5` then it won't be taken even once.

> 

> > 

> 

> >     I think the right precondition is `Start` < `RHS` -- if that precondition is true then we know that `{Start,+,Stride}` is true on the first iteration, and if `Stride` is negative then we'll keep executing the loop till `{Start,+,Stride}` wraps.

> 

> > - I don't think the logic as written is correct for unsigned compares.  I can legitimately have `{0,+,-1}<nuw>` u< `-1` execute one backedge (i.e. with a "negative" step).

> 

> 

> 




> For your first example when the IV is `{-1,+,-2}` it cannot have nuw flag.


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.

But that's besides the point -- generally, whether the increment operation has `nuw` or `nsw` is distinct from whether the SCEV expression mapped to the increment operation is `nuw` or `nsw`.  Specifically, we mark `{A,+,B}` as `nsw` (resp `nuw`) if `sext({A,+,B})` (resp. `zext({A,+,B})`) is equal to `{sext A,+,sext B}` (resp. `{zext A,+,zext B}`) for every iteration of the loop that executes.  In some cases we can use the no-wrap flags on the increment to prove this, but e.g. for a loop that that does not take the backedge even once, every add recurrence in the loop is `nuw` and `nsw` irrespective of the no-wrap flags present in the increment operations.  That includes loop like this:

  i = INT_MIN
  if (i s< 5) {
    do {
      i += (-1);
    } while (i s< 5);
  }

The increment operation itself is not NSW, but the add recurrence mapped to the post-incremented value of `i` can still be marked NSW, since it follows our rule that for every iteration of the loop (there is only one), `sext({INT_MIN,+,-1})` == `{sext(INT_MIN), +, sext(-1)}` (since in the one iteration, both the LHS and RHS are `sext(INT_MIN)`).

Now it is unlikely that SCEV will mark the add recurrence with NSW in the trip computing code itself, since it does not yet know the trip count; but marking it is NSW is legal, and we must allow for it.


https://reviews.llvm.org/D22377





More information about the llvm-commits mailing list