1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[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
This commit is contained in:
Sanjoy Das 2015-10-23 06:33:47 +00:00
parent c3afafb9c3
commit c16a88d64c

View File

@ -1268,7 +1268,9 @@ static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR, Type *Ty,
// `Step`:
// 1. NSW/NUW flags on the step increment.
const SCEV *PreStart = SE->getAddExpr(DiffOps, SA->getNoWrapFlags());
auto PreStartFlags =
ScalarEvolution::maskFlags(SA->getNoWrapFlags(), SCEV::FlagNUW);
const SCEV *PreStart = SE->getAddExpr(DiffOps, PreStartFlags);
const SCEVAddRecExpr *PreAR = dyn_cast<SCEVAddRecExpr>(
SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagAnyWrap));