blob: 813e98cbaa85f2ed246a0daea583a29617afcde7 [file] [log] [blame]
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Verifies that Dead Store Elimination (DSE) doesn't eliminate
// stores after incorrectly propagating "dead store" state beyond
// definition of instance and index of a store via loop backedge.
// Regression test for https://github.com/dart-lang/sdk/issues/55607.
import 'package:expect/expect.dart';
// Original example.
// Verifies that "dead store" state is not be propagated for indexed place
// 'part[offset]' beyond definition of index 'offset' which changes in a loop.
@pragma('vm:never-inline')
List<int> test1() {
int offset = 0;
List<int> part = [0, 0, 0];
for (int i = 0; i < 2; i++) {
part[offset] = 2;
offset++;
}
part[offset] = 10;
return part;
}
class A {
int aField;
A(this.aField);
operator ==(Object other) => other is A && this.aField == other.aField;
String toString() => 'A($aField)';
}
// Verifies that "dead store" state is not be propagated for instance field
// place 'obj.aField' beyond definition of instance 'obj' which changes in
// a loop.
@pragma('vm:never-inline')
List<A> test2() {
A obj1 = A(0);
A obj2 = A(0);
final list = [obj1, obj2];
A obj = obj1;
for (int i = 0; i < 1; i++) {
obj.aField = 2;
obj = obj2;
}
obj.aField = 10;
return list;
}
class B {
A obj;
B(this.obj);
operator ==(Object other) => other is B && this.obj == other.obj;
String toString() => 'B($obj)';
}
@pragma('vm:never-inline')
confuse(x) => x;
// Same as previous, but 'obj' definition is LoadField, not a Phi.
@pragma('vm:never-inline')
List<B> test3() {
B b1 = confuse(B(A(0)));
B b2 = confuse(B(A(0)));
final list = [b1, b2];
A obj;
B bb = b1;
for (int i = 0; (obj = bb.obj) != null && i < 1; i++) {
obj.aField = 2;
bb = b2;
}
obj.aField = 10;
return list;
}
void main() {
Expect.deepEquals([2, 2, 10], test1());
Expect.deepEquals([A(2), A(10)], test2());
Expect.deepEquals([B(A(2)), B(A(10))], test3());
}