aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorDanila Malyutin <danilaml@users.noreply.github.com>2023-10-30 14:50:57 -0700
committerGitHub <noreply@github.com>2023-10-31 00:50:57 +0300
commitba1349fc31295a3670b34c189838a133e18c0bed (patch)
tree4240eafde07d49fb12b561497ba71b9c6ca69cf9 /llvm/lib/Analysis/ScalarEvolution.cpp
parent6995183e174280f3987858bd13a4eca9905f6365 (diff)
downloadllvm-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.cpp13
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;