PR-URL: https://github.com/nodejs/node/pull/49639 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
175 lines
4.3 KiB
JavaScript
175 lines
4.3 KiB
JavaScript
// Copyright 2023 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --maglev --allow-natives-syntax
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// Without Phis
|
|
|
|
function basic_int32(a) {
|
|
let c = a + 2;
|
|
if (c) {
|
|
return 42;
|
|
} else {
|
|
return 19;
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(basic_int32);
|
|
assertEquals(19, basic_int32(-2));
|
|
assertEquals(42, basic_int32(3));
|
|
%OptimizeMaglevOnNextCall(basic_int32);
|
|
assertEquals(19, basic_int32(-2));
|
|
assertEquals(42, basic_int32(3));
|
|
|
|
|
|
function basic_float64(a) {
|
|
let c = a + 2.5;
|
|
if (c) {
|
|
return 1.6;
|
|
} else {
|
|
if (c == c) {
|
|
return 2.42;
|
|
} else {
|
|
return 3.11;
|
|
}
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(basic_float64);
|
|
assertEquals(2.42, basic_float64(-2.5));
|
|
assertEquals(1.6, basic_float64(3.5));
|
|
assertEquals(3.11, basic_float64(NaN));
|
|
%OptimizeMaglevOnNextCall(basic_float64);
|
|
assertEquals(2.42, basic_float64(-2.5));
|
|
assertEquals(1.6, basic_float64(3.5));
|
|
assertEquals(3.11, basic_float64(NaN));
|
|
|
|
function basic_holey_float64(a) {
|
|
let c = a + 2.5;
|
|
if (c) {
|
|
return 1.6;
|
|
} else {
|
|
if (a == a) {
|
|
return 3.6 + a;
|
|
} else {
|
|
return 3.11;
|
|
}
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(basic_holey_float64);
|
|
assertEquals(1.1, basic_holey_float64(-2.5));
|
|
assertEquals(1.6, basic_holey_float64(3.5));
|
|
assertEquals(3.11, basic_holey_float64(NaN));
|
|
assertEquals(NaN, basic_holey_float64([1.1, , 2.2][1]));
|
|
%OptimizeMaglevOnNextCall(basic_holey_float64);
|
|
assertEquals(1.1, basic_holey_float64(-2.5));
|
|
assertEquals(1.6, basic_holey_float64(3.5));
|
|
assertEquals(3.11, basic_holey_float64(NaN));
|
|
assertEquals(NaN, basic_holey_float64([1.1, , 2.2][1]));
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// With Phis as condition.
|
|
//
|
|
// When Phi untagging is enabled, the condition should start as
|
|
// BranchIfToBooleanTrue, and later be updated to BranchIfInt32ToBooleanTrue or
|
|
// BranchIfFloat64ToBooleanTrue.
|
|
|
|
function phi_int32(a) {
|
|
let phi = a ? 4 : 0;
|
|
if (phi) {
|
|
return phi + 5;
|
|
} else {
|
|
return phi + 3;
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(phi_int32);
|
|
assertEquals(3, phi_int32(0));
|
|
assertEquals(9, phi_int32(1));
|
|
%OptimizeMaglevOnNextCall(phi_int32);
|
|
assertEquals(3, phi_int32(0));
|
|
assertEquals(9, phi_int32(1));
|
|
|
|
|
|
|
|
function phi_float64_no_nan(a) {
|
|
let phi = a ? 3.5 : 0;
|
|
if (phi) {
|
|
return phi + 1.6;
|
|
} else {
|
|
return phi + 2.5;
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(phi_float64_no_nan);
|
|
assertEquals(2.5, phi_float64_no_nan(0));
|
|
assertEquals(5.1, phi_float64_no_nan(1));
|
|
%OptimizeMaglevOnNextCall(phi_float64_no_nan);
|
|
assertEquals(2.5, phi_float64_no_nan(0));
|
|
assertEquals(5.1, phi_float64_no_nan(1));
|
|
|
|
|
|
|
|
function phi_float64_nan(a, b) {
|
|
let nan = 0 / a;
|
|
let f64 = b + 0.5;
|
|
let phi = a ? f64 : nan;
|
|
if (phi) {
|
|
return phi + 4.5;
|
|
} else {
|
|
if (phi == phi) {
|
|
return phi + 2.1;
|
|
} else {
|
|
return 4.25;
|
|
}
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(phi_float64_nan);
|
|
assertEquals(4.25, phi_float64_nan(0, 0.5));
|
|
assertEquals(2.1, phi_float64_nan(1, -0.5));
|
|
assertEquals(5.5, phi_float64_nan(1, 0.5));
|
|
%OptimizeMaglevOnNextCall(phi_float64_nan);
|
|
assertEquals(4.25, phi_float64_nan(0, 0.5));
|
|
assertEquals(2.1, phi_float64_nan(1, -0.5));
|
|
assertEquals(5.5, phi_float64_nan(1, 0.5));
|
|
|
|
|
|
|
|
let arr = [1.5, , NaN, 0.0];
|
|
|
|
function phi_float64_holey(a, arr) {
|
|
let holey_f64 = arr[a];
|
|
let phi = arr ? holey_f64 : 4;
|
|
if (phi) {
|
|
return phi + 1.7;
|
|
} else {
|
|
// We should get here for:
|
|
// a == 1 ==> the_hole
|
|
// a == 2 ==> NaN
|
|
// a == 3 ==> 0.0
|
|
// To distinguish between the 3 cases, we add a branch on "a".
|
|
if (a != 2) {
|
|
return phi + 2.1;
|
|
} else {
|
|
return 4.25;
|
|
}
|
|
}
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(phi_float64_holey);
|
|
assertEquals(3.2, phi_float64_holey(0, arr));
|
|
// We don't load the_hole during feedback collection, as this would lead to
|
|
// megamorphic feedback.
|
|
// assertEquals(NaN, phi_float64_holey(1, arr));
|
|
assertEquals(4.25, phi_float64_holey(2, arr));
|
|
assertEquals(2.1, phi_float64_holey(3, arr));
|
|
%OptimizeMaglevOnNextCall(phi_float64_holey);
|
|
assertEquals(3.2, phi_float64_holey(0, arr));
|
|
assertEquals(NaN, phi_float64_holey(1, arr));
|
|
assertEquals(4.25, phi_float64_holey(2, arr));
|
|
assertEquals(2.1, phi_float64_holey(3, arr));
|