blob: a1c962ecb23353c60e210a445070c29c8c49c471 [file] [log] [blame]
// Copyright (c) 2019, 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.
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
// This test checks for obscure interaction between LICM and AssertAssignable
// strengthening performed by Type Propagator. The later would use deopt_id
// from an environment attached to AssertAssignable, and this deopt id under
// certain conditions would be set to -1. The code was changed to never
// use deopt_id from the environment but this regression test is provided for
// completeness.
class A<T> {
var foo = 42;
}
class B extends A<String> {}
class C extends B {}
void foo(dynamic a) {
// To prevent AssertAssignable strengthening from occuring too early we
// need to hide the fact that CheckClass and AssertAssignable are performed
// against the same SSA value. To achieve that we store a into an array and
// then load it back. Load Forwarding would happen just before LICM and
// will remove the indirection. Then LICM would hoist both CheckClass
// and AssertAssignable out of the loop and then strengthening would happen.
final box = <dynamic>[null];
box[0] = a;
for (var i = 0; i < 1; i++) {
a as A<String>;
if (box[0].foo != 42) {
throw "unexpected";
}
}
}
void main() {
for (var i = 0; i < 100; i++) {
foo(B());
}
// Trigger deoptimization on the CheckClass produced by strengthened
// AssertAssignable - if this CheckClass has wrong deoptimization id a crash
// would occur.
foo(C());
}