[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)
commitcc71fa3794051f088c8f1cfc32a2e1b1a8d1a8f6
treec6296f67dc76b0dd2994fd97d9ed487ab4ae1f37
parentbd1e97920ae282c0a8353173941ef5cef44c94cd
[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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251097 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Analysis/ScalarEvolution.cpp