diff options
author | Danila Malyutin <danilaml@users.noreply.github.com> | 2023-10-30 14:50:57 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-31 00:50:57 +0300 |
commit | ba1349fc31295a3670b34c189838a133e18c0bed (patch) | |
tree | 4240eafde07d49fb12b561497ba71b9c6ca69cf9 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | 6995183e174280f3987858bd13a4eca9905f6365 (diff) | |
download | llvm-ba1349fc31295a3670b34c189838a133e18c0bed.zip llvm-ba1349fc31295a3670b34c189838a133e18c0bed.tar.gz llvm-ba1349fc31295a3670b34c189838a133e18c0bed.tar.bz2 |
[SCEV] Fix "quick and dirty" difference that could lead to assert (#70688)
The old algorithm would remove all operands matching %step SCEV when it
intended to only remove a single one. This lead to assert when
SCEVAddExpr was of the form %step + %step and potential miscompiles in
similar cases. Such SCEVs could be created when construction reached
depth thresholds.
Fixes #70348
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 2368003..f13e508 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1335,11 +1335,14 @@ static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR, Type *Ty, // Create an AddExpr for "PreStart" after subtracting Step. Full SCEV // subtraction is expensive. For this purpose, perform a quick and dirty - // difference, by checking for Step in the operand list. - SmallVector<const SCEV *, 4> DiffOps; - for (const SCEV *Op : SA->operands()) - if (Op != Step) - DiffOps.push_back(Op); + // difference, by checking for Step in the operand list. Note, that + // SA might have repeated ops, like %a + %a + ..., so only remove one. + SmallVector<const SCEV *, 4> DiffOps(SA->operands()); + for (auto It = DiffOps.begin(); It != DiffOps.end(); ++It) + if (*It == Step) { + DiffOps.erase(It); + break; + } if (DiffOps.size() == SA->getNumOperands()) return nullptr; |