diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc index f55ce2a2bd..6c2935f7ca 100644 --- a/src/compiler/load-elimination.cc +++ b/src/compiler/load-elimination.cc @@ -535,7 +535,7 @@ LoadElimination::AbstractState::KillFields(Node* object, Zone* zone) const { AbstractField const* that_field = this_field->Kill(object, zone); if (that_field != this_field) { AbstractState* that = new (zone) AbstractState(*this); - that->fields_[i] = this_field; + that->fields_[i] = that_field; while (++i < arraysize(fields_)) { if (this->fields_[i] != nullptr) { that->fields_[i] = this->fields_[i]->Kill(object, zone); diff --git a/test/unittests/compiler/load-elimination-unittest.cc b/test/unittests/compiler/load-elimination-unittest.cc index 22e843aa36..8d34fb9699 100644 --- a/test/unittests/compiler/load-elimination-unittest.cc +++ b/test/unittests/compiler/load-elimination-unittest.cc @@ -174,6 +174,46 @@ TEST_F(LoadEliminationTest, StoreFieldAndLoadField) { EXPECT_EQ(value, r.replacement()); } +TEST_F(LoadEliminationTest, StoreFieldAndKillFields) { + Node* object = Parameter(Type::Any(), 0); + Node* value = Parameter(Type::Any(), 1); + Node* effect = graph()->start(); + Node* control = graph()->start(); + + FieldAccess access1 = {kTaggedBase, kPointerSize, + MaybeHandle(), MaybeHandle(), + Type::Any(), MachineType::AnyTagged(), + kNoWriteBarrier}; + + // Offset that out of field cache size. + FieldAccess access2 = {kTaggedBase, 2048 * kPointerSize, + MaybeHandle(), MaybeHandle(), + Type::Any(), MachineType::AnyTagged(), + kNoWriteBarrier}; + + StrictMock editor; + LoadElimination load_elimination(&editor, jsgraph(), zone()); + + load_elimination.Reduce(graph()->start()); + + Node* store1 = effect = graph()->NewNode(simplified()->StoreField(access1), + object, value, effect, control); + load_elimination.Reduce(store1); + + // Invalidate caches of object. + Node* store2 = effect = graph()->NewNode(simplified()->StoreField(access2), + object, value, effect, control); + load_elimination.Reduce(store2); + + Node* store3 = graph()->NewNode(simplified()->StoreField(access1), + object, value, effect, control); + + Reduction r = load_elimination.Reduce(store3); + + // store3 shall not be replaced, since caches were invalidated. + EXPECT_EQ(store3, r.replacement()); +} + TEST_F(LoadEliminationTest, StoreFieldAndStoreElementAndLoadField) { Node* object = Parameter(Type::Any(), 0); Node* value = Parameter(Type::Any(), 1);