Skip to content

Commit 68099bf

Browse files
GeorgNeisCommit Bot
authored andcommitted
[turbofan] Fix bug in Typer::TypeInductionVariablePhi, again
Regrettably the previous fix was flawed because a zero increment can change the type of the induction variable. Bug: chromium:1051017 Change-Id: I2d7aeffb2065e739445118a2d0c5f7732eecdcbb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2064222 Reviewed-by: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#66345}
1 parent 4e11ad9 commit 68099bf

2 files changed

Lines changed: 25 additions & 16 deletions

File tree

src/compiler/typer.cc

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -850,26 +850,21 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
850850
Type initial_type = Operand(node, 0);
851851
Type increment_type = Operand(node, 2);
852852

853-
// If we do not have enough type information for the initial value or
854-
// the increment, just return the initial value's type.
853+
// Fallback to normal phi typing in a variety of cases: when the induction
854+
// variable is not initially of type Integer (we want to work with ranges
855+
// below), when the increment is zero (in that case, phi typing will generally
856+
// yield a better type), and when the induction variable can become NaN
857+
// (through addition/subtraction of opposing infinities).
855858
if (initial_type.IsNone() ||
856-
increment_type.Is(typer_->cache_->kSingletonZero)) {
857-
return initial_type;
858-
}
859-
860-
// We only handle integer induction variables (otherwise ranges do not apply
861-
// and we cannot do anything). Moreover, we don't support infinities in
862-
// {increment_type} because the induction variable can become NaN through
863-
// addition/subtraction of opposing infinities.
864-
if (!initial_type.Is(typer_->cache_->kInteger) ||
859+
increment_type.Is(typer_->cache_->kSingletonZero) ||
860+
!initial_type.Is(typer_->cache_->kInteger) ||
865861
!increment_type.Is(typer_->cache_->kInteger) ||
866862
increment_type.Min() == -V8_INFINITY ||
867863
increment_type.Max() == +V8_INFINITY) {
868-
// Fallback to normal phi typing, but ensure monotonicity.
869-
// (Unfortunately, without baking in the previous type, monotonicity might
870-
// be violated because we might not yet have retyped the incrementing
871-
// operation even though the increment's type might been already reflected
872-
// in the induction variable phi.)
864+
// Unfortunately, without baking in the previous type, monotonicity might be
865+
// violated because we might not yet have retyped the incrementing operation
866+
// even though the increment's type might been already reflected in the
867+
// induction variable phi.
873868
Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
874869
: Type::None();
875870
for (int i = 0; i < arity; ++i) {

test/mjsunit/compiler/regress-1051017.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,17 @@ assertEquals(NaN, foo2());
3232
assertEquals(NaN, foo2());
3333
%OptimizeFunctionOnNextCall(foo2);
3434
assertEquals(NaN, foo2());
35+
36+
37+
function foo3(b) {
38+
var k = 0;
39+
let str = b ? "42" : "0";
40+
for (var i = str; i < 1 && k++ < 1; i -= 0) { }
41+
return i;
42+
}
43+
44+
%PrepareFunctionForOptimization(foo3);
45+
assertEquals(0, foo3());
46+
assertEquals(0, foo3());
47+
%OptimizeFunctionOnNextCall(foo3);
48+
assertEquals(0, foo3());

0 commit comments

Comments
 (0)