Bug 1317675: Check that phis are not guards before removing them; r=h4writer

MozReview-Commit-ID: DO4BWhaTPev

--HG--
extra : rebase_source : cf6663951a345d7b047cf38fde23ed56952c8cd9
This commit is contained in:
Benjamin Bouvier 2016-11-15 18:54:57 +01:00
Родитель a53239598d
Коммит b1840b3633
3 изменённых файлов: 44 добавлений и 3 удалений

Просмотреть файл

@ -0,0 +1,18 @@
// |jit-test| error: InternalError: too much recursion
function f() {
var phi1 = 0;
var phi2 = 0;
while (true) {
if (!phi2) {
var add = phi1 + 1;
f(add);
if (!phi2)
return;
phi1 = 1;
phi2 = 0;
}
}
}
f(0);

Просмотреть файл

@ -0,0 +1,22 @@
load(libdir + "wasm.js");
wasmEvalText(`(module
(type $type0 (func (param i32)))
(func $f (param $p i32)
(local $x i32) (local $y i32)
loop $top
get_local $x
get_local $p
get_local $x
br_if $top
i32.const 1
tee_local $p
get_local $y
set_local $x
i32.add
call $f
br_if $top
return
end
)
)`);

Просмотреть файл

@ -480,6 +480,7 @@ ValueNumberer::removePredecessorAndDoDCE(MBasicBlock* block, MBasicBlock* pred,
for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ) { for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ) {
MPhi* phi = *iter++; MPhi* phi = *iter++;
MOZ_ASSERT(!values_.has(phi), "Visited phi in block having predecessor removed"); MOZ_ASSERT(!values_.has(phi), "Visited phi in block having predecessor removed");
MOZ_ASSERT(!phi->isGuard());
MDefinition* op = phi->getOperand(predIndex); MDefinition* op = phi->getOperand(predIndex);
phi->removeOperand(predIndex); phi->removeOperand(predIndex);
@ -488,9 +489,9 @@ ValueNumberer::removePredecessorAndDoDCE(MBasicBlock* block, MBasicBlock* pred,
if (!handleUseReleased(op, DontSetUseRemoved) || !processDeadDefs()) if (!handleUseReleased(op, DontSetUseRemoved) || !processDeadDefs())
return false; return false;
// If |nextDef_| became dead while we had it pinned, advance the iterator // If |nextDef_| became dead while we had it pinned, advance the
// and discard it now. // iterator and discard it now.
while (nextDef_ && !nextDef_->hasUses()) { while (nextDef_ && !nextDef_->hasUses() && !nextDef_->isGuardRangeBailouts()) {
phi = nextDef_->toPhi(); phi = nextDef_->toPhi();
iter++; iter++;
nextDef_ = iter != end ? *iter : nullptr; nextDef_ = iter != end ? *iter : nullptr;