diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-13 01:23:21 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-13 01:23:21 +0000 |
commit | 7e2b7567a8110abc5399e8c32ba180c87366e123 (patch) | |
tree | 6a3a37f4ec53dd1f2d91030980d7402b3ab52333 /llvm/lib/IR/Value.cpp | |
parent | b321ecbdcfc9543e8efdf469cebeb8361e8f7e97 (diff) | |
download | bcm5719-llvm-7e2b7567a8110abc5399e8c32ba180c87366e123.tar.gz bcm5719-llvm-7e2b7567a8110abc5399e8c32ba180c87366e123.zip |
Assert that we don't RAUW a Constant with a ConstantExpr that contains it.
We already had an assert for foo->RAUW(foo), but not for something like
foo->RAUW(GEP(foo)) and would go in an infinite loop trying to apply
the replacement.
llvm-svn: 208663
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 2ebdb702cf9..9a79e43359e 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -301,10 +301,45 @@ void Value::takeName(Value *V) { ST->reinsertValue(this); } +#ifndef NDEBUG +static bool contains(SmallPtrSet<ConstantExpr *, 4> &Cache, ConstantExpr *Expr, + Constant *C) { + if (!Cache.insert(Expr)) + return false; + + for (auto &O : Expr->operands()) { + if (O == C) + return true; + auto *CE = dyn_cast<ConstantExpr>(O); + if (!CE) + continue; + if (contains(Cache, CE, C)) + return true; + } + return false; +} + +static bool contains(Value *Expr, Value *V) { + if (Expr == V) + return true; + + auto *C = dyn_cast<Constant>(V); + if (!C) + return false; + + auto *CE = dyn_cast<ConstantExpr>(Expr); + if (!CE) + return false; + + SmallPtrSet<ConstantExpr *, 4> Cache; + return contains(Cache, CE, C); +} +#endif void Value::replaceAllUsesWith(Value *New) { assert(New && "Value::replaceAllUsesWith(<null>) is invalid!"); - assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); + assert(!contains(New, this) && + "this->replaceAllUsesWith(expr(this)) is NOT valid!"); assert(New->getType() == getType() && "replaceAllUses of value with new value of different type!"); |