forked from OSchip/llvm-project
[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:
parent
57cee79f7c
commit
0714e3e245
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in New Issue