[IndVars] Make loop varying predicates loop invariant.
authorSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 27 Jul 2015 21:42:49 +0000 (21:42 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Mon, 27 Jul 2015 21:42:49 +0000 (21:42 +0000)
commit39d6da003da8fc0e13e7a227600b519a83a07cad
tree6a3454c50fe25fec1a29adbeba0401c9a4e0c499
parentca5ed7446385ef2a607fd806f284d9b3d470fc72
[IndVars] Make loop varying predicates loop invariant.

Summary:
Was D9784: "Remove loop variant range check when induction variable is
strictly increasing"

This change re-implements D9784 with the two differences:

 1. It does not use SCEVExpander and does not generate new
    instructions.  Instead, it does a quick local search for existing
    `llvm::Value`s that it needs when modifying the `icmp`
    instruction.

 2. It is more general -- it deals with both increasing and decreasing
    induction variables.

I've added all of the tests included with D9784, and two more.

As an example on what this change does (copied from D9784):

Given C code:

```
for (int i = M; i < N; i++) // i is known not to overflow
  if (i < 0) break;
  a[i] = 0;
}
```

This transformation produces:

```
for (int i = M; i < N; i++)
  if (M < 0) break;
  a[i] = 0;
}
```

Which can be unswitched into:

```
if (!(M < 0))
  for (int i = M; i < N; i++)
    a[i] = 0;
}
```

I went back and forth on whether the top level logic should live in
`SimplifyIndvar::eliminateIVComparison` or be put into its own
routine.  Right now I've put it under `eliminateIVComparison` because
even though the `icmp` is not *eliminated*, it no longer is an IV
comparison.  I'm open to putting it in its own helper routine if you
think that is better.

Reviewers: reames, nicholas, atrick

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D11278

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243331 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Analysis/ScalarEvolution.h
lib/Analysis/ScalarEvolution.cpp
lib/Transforms/Utils/SimplifyIndVar.cpp
test/Transforms/IndVarSimplify/loop-invariant-conditions.ll [new file with mode: 0644]