[SCEV] Fix a latent bug in `getPreStartForExtend`
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 23 Oct 2015 06:33:47 +0000 (06:33 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 23 Oct 2015 06:33:47 +0000 (06:33 +0000)
commit0714e3e245c20e33205a078d53b3b52fa8cee815
tree9614b4d7793be88b7acceb5ff0a77d4be89c1fb9
parent57cee79f7c6302bb94a1520cd33a676c31565743
[SCEV] Fix a latent bug in `getPreStartForExtend`

I could not come up a way to test this -- I think this bug is latent
today, and will not actually result in a miscompile.

In `getPreStartForExtend`, SCEV constructs `PreStart` as a sum of all of
`SA`'s operands except `Op`.  It also uses `SA`'s no-wrap flags, and
this is problematic because removing an element from an add expression
can make it signed-wrap.  E.g. if `SA` was `(127 + 1 + -1)`, then it
could safely be `<nsw>` (since `sext(127) + sext(1) + sext(-1)` ==
`sext(127 + 1 + -1)`), but `(127 + 1)` (== `PreStart` if `Op` is `-1`)
is not `<nsw>`.

Transferring `<nuw>` from `SA` to `PreStart` is safe, as far as I can
tell.

llvm-svn: 251097
llvm/lib/Analysis/ScalarEvolution.cpp