From e2b37447b715b1eaa507de117fcb18beea6a4601 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 13 May 2014 01:23:21 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208663 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Value.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'lib/IR/Value.cpp') diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index 2ebdb702cf..9a79e43359 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -301,10 +301,45 @@ void Value::takeName(Value *V) { ST->reinsertValue(this); } +#ifndef NDEBUG +static bool contains(SmallPtrSet &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(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(V); + if (!C) + return false; + + auto *CE = dyn_cast(Expr); + if (!CE) + return false; + + SmallPtrSet Cache; + return contains(Cache, CE, C); +} +#endif void Value::replaceAllUsesWith(Value *New) { assert(New && "Value::replaceAllUsesWith() 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!"); -- cgit v1.2.3