PR-URL: https://github.com/nodejs/node/pull/58070 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
105 lines
3.8 KiB
JavaScript
105 lines
3.8 KiB
JavaScript
// Copyright 2024 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: --no-always-turbofan --turbofan --js-staging
|
|
// Flags: --allow-natives-syntax
|
|
|
|
function storeAndLoad(x) {
|
|
var a = new Float16Array(1)
|
|
a[0] = x
|
|
return a[0]
|
|
}
|
|
|
|
%PrepareFunctionForOptimization(storeAndLoad);
|
|
|
|
function assertAlmostEquals(expected, actual, epsilon = 1e-4) {
|
|
assertTrue(
|
|
Math.abs(expected - actual) < epsilon,
|
|
`value difference bigger than ${epsilon} got ${actual} expected ${expected}`
|
|
)
|
|
}
|
|
|
|
const testCases = [
|
|
{ input: 0, expected: 0 },
|
|
{ input: 0.1, expected: 0.1 },
|
|
{ input: 0.01, expected: 0.01 },
|
|
{ input: 0.001, expected: 0.001 },
|
|
{ input: 0.0001, expected: 0.0001 },
|
|
{ input: 0.00001, expected: 0.00001 },
|
|
{ input: 12, expected: 12 },
|
|
{ input: 32, expected: 32 },
|
|
{ input: 123, expected: 123 },
|
|
{ input: 12.12, expected: 12.12, epsilon: 0.01 },
|
|
{ input: 32.333, expected: 32.333, epsilon: 0.015 },
|
|
{ input: 123.11, expected: 123.11, epsilon: 0.0151 },
|
|
];
|
|
|
|
testCases.forEach(({ input, expected, epsilon }) => {
|
|
assertAlmostEquals(expected, storeAndLoad(input), epsilon);
|
|
});
|
|
|
|
testCases.forEach(({ input, expected, epsilon }) => {
|
|
%OptimizeFunctionOnNextCall(storeAndLoad);
|
|
assertAlmostEquals(expected, storeAndLoad(input), epsilon);
|
|
|
|
assertOptimized(storeAndLoad);
|
|
});
|
|
|
|
const edgeCases = [
|
|
// an integer which rounds down under ties-to-even when cast to float16
|
|
{ input: 2049, expected: 2048 },
|
|
// an integer which rounds up under ties-to-even when cast to float16
|
|
{ input: 2051, expected: 2052 },
|
|
// smallest normal float16
|
|
{ input: 0.00006103515625, expected: 0.00006103515625 },
|
|
// largest subnormal float16
|
|
{ input: 0.00006097555160522461, expected: 0.00006097555160522461 },
|
|
// smallest float16
|
|
{ input: 5.960464477539063e-8, expected: 5.960464477539063e-8 },
|
|
// largest double which rounds to 0 when cast to float16
|
|
{ input: 2.9802322387695312e-8, expected: 0 },
|
|
// smallest double which does not round to 0 when cast to float16
|
|
{ input: 2.980232238769532e-8, expected: 5.960464477539063e-8 },
|
|
// a double which rounds up to a subnormal under ties-to-even when cast to float16
|
|
{ input: 8.940696716308594e-8, expected: 1.1920928955078125e-7 },
|
|
// a double which rounds down to a subnormal under ties-to-even when cast to float16
|
|
{ input: 1.4901161193847656e-7, expected: 1.1920928955078125e-7 },
|
|
// the next double above the one on the previous line one
|
|
{ input: 1.490116119384766e-7, expected: 1.7881393432617188e-7 },
|
|
// max finite float16
|
|
{ input: 65504, expected: 65504 },
|
|
// largest double which does not round to infinity when cast to float16
|
|
{ input: 65519.99999999999, expected: 65504 },
|
|
// lowest negative double which does not round to infinity when cast to float16
|
|
{ input: -65519.99999999999, expected: -65504 },
|
|
// smallest double which rounds to a non-subnormal when cast to float16
|
|
{ input: 0.000061005353927612305, expected: 0.00006103515625 },
|
|
// largest double which rounds to a subnormal when cast to float16
|
|
{ input: 0.0000610053539276123, expected: 0.00006097555160522461 },
|
|
{ input: NaN, expected: NaN },
|
|
{ input: Infinity, expected: Infinity },
|
|
{ input: -Infinity, expected: -Infinity },
|
|
// smallest double which rounds to infinity when cast to float16
|
|
{ input: 65520, expected: Infinity },
|
|
{ input: -65520, expected: - Infinity },
|
|
|
|
];
|
|
|
|
edgeCases.forEach(({ input, expected }) => {
|
|
assertEquals(expected, storeAndLoad(input));
|
|
});
|
|
|
|
edgeCases.forEach(({ input, expected }) => {
|
|
%OptimizeFunctionOnNextCall(storeAndLoad);
|
|
assertEquals(expected, storeAndLoad(input));
|
|
assertOptimized(storeAndLoad);
|
|
});
|
|
|
|
const source = new Float16Array([0.1, 0.2, 0.3])
|
|
const copied = new Float32Array(source)
|
|
|
|
for (let i = 0; i < source.length; i++) {
|
|
assertAlmostEquals(source[i], copied[i])
|
|
}
|