diff options
Diffstat (limited to 'js/src/jit-test/tests/ion/testFloat32-correctness.js')
-rw-r--r-- | js/src/jit-test/tests/ion/testFloat32-correctness.js | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/testFloat32-correctness.js b/js/src/jit-test/tests/ion/testFloat32-correctness.js new file mode 100644 index 000000000..ac6b5bc87 --- /dev/null +++ b/js/src/jit-test/tests/ion/testFloat32-correctness.js @@ -0,0 +1,340 @@ +setJitCompilerOption("ion.warmup.trigger", 50); + +var f32 = new Float32Array(10); + +function test(setup, f) { + if (f === undefined) { + f = setup; + setup = function(){}; + } + setup(); + for(var n = 200; n; --n) { + f(); + } +} + +// Basic arithmetic +function setupBasicArith() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0; + f32[3] = 0; + f32[4] = 1.337; + f32[5] = 42; + f32[6] = Infinity; + f32[7] = NaN; +} +function basicArith() { + for (var i = 0; i < 7; ++i) { + var opf = Math.fround(f32[i] + f32[i+1]); + var opd = (1 / (1 / f32[i])) + f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] - f32[i+1]); + opd = (1 / (1 / f32[i])) - f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] * f32[i+1]); + opd = (1 / (1 / f32[i])) * f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + + opf = Math.fround(f32[i] / f32[i+1]); + opd = (1 / (1 / f32[i])) / f32[i+1]; + assertFloat32(opf, true); + assertFloat32(opd, false); + assertEq(opf, Math.fround(opd)); + } +} +test(setupBasicArith, basicArith); + +// MAbs +function setupAbs() { + f32[0] = -0; + f32[1] = 0; + f32[2] = -3.14159; + f32[3] = 3.14159; + f32[4] = -Infinity; + f32[5] = Infinity; + f32[6] = NaN; +} +function abs() { + for(var i = 0; i < 7; ++i) { + assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) ); + } +} +test(setupAbs, abs); + +// MSqrt +function setupSqrt() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 4; + f32[3] = -1; + f32[4] = Infinity; + f32[5] = NaN; + f32[6] = 13.37; +} +function sqrt() { + for(var i = 0; i < 7; ++i) { + var sqrtf = Math.fround(Math.sqrt(f32[i])); + var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops + assertEq( sqrtf, Math.fround(sqrtd) ); + } +} +test(setupSqrt, sqrt); + +// MMinMax +function setupMinMax() { + f32[0] = -0; + f32[1] = 0; + f32[2] = 1; + f32[3] = 4; + f32[4] = -1; + f32[5] = Infinity; + f32[6] = NaN; + f32[7] = 13.37; + f32[8] = -Infinity; + f32[9] = Math.pow(2,31) - 1; +} +function minMax() { + for(var i = 0; i < 9; ++i) { + for(var j = 0; j < 9; j++) { + var minf = Math.fround(Math.min(f32[i], f32[j])); + var mind = 1 / (1 / Math.min(f32[i], f32[j])); // force no float32 by chaining arith ops + assertFloat32(minf, true); + assertFloat32(mind, false); + assertEq( minf, Math.fround(mind) ); + + var maxf = Math.fround(Math.max(f32[i], f32[j])); + var maxd = 1 / (1 / Math.max(f32[i], f32[j])); // force no float32 by chaining arith ops + assertFloat32(maxf, true); + assertFloat32(maxd, false); + assertEq( maxf, Math.fround(maxd) ); + } + } +} +test(setupMinMax, minMax); + +// MTruncateToInt32 +// The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul +function setupTruncateToInt32() { + f32[0] = -1; + f32[1] = 4; + f32[2] = 5.13; +} +function truncateToInt32() { + assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) ); + assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) ); +} +test(setupTruncateToInt32, truncateToInt32); + +// MCompare +function comp() { + for(var i = 0; i < 9; ++i) { + assertEq( f32[i] < f32[i+1], true ); + } +} +function setupComp() { + f32[0] = -Infinity; + f32[1] = -1; + f32[2] = -0.01; + f32[3] = 0; + f32[4] = 0.01; + f32[5] = 1; + f32[6] = 10; + f32[7] = 13.37; + f32[8] = 42; + f32[9] = Infinity; +} +test(setupComp, comp); + +// MNot +function setupNot() { + f32[0] = -0; + f32[1] = 0; + f32[2] = 1; + f32[3] = NaN; + f32[4] = Infinity; + f32[5] = 42; + f32[6] = -23; +} +function not() { + assertEq( !f32[0], true ); + assertEq( !f32[1], true ); + assertEq( !f32[2], false ); + assertEq( !f32[3], true ); + assertEq( !f32[4], false ); + assertEq( !f32[5], false ); + assertEq( !f32[6], false ); +} +test(setupNot, not); + +// MToInt32 +var str = "can haz cheezburger? okthxbye;"; +function setupToInt32() { + f32[0] = 0; + f32[1] = 1; + f32[2] = 2; + f32[3] = 4; + f32[4] = 5; +} +function testToInt32() { + assertEq(str[f32[0]], 'c'); + assertEq(str[f32[1]], 'a'); + assertEq(str[f32[2]], 'n'); + assertEq(str[f32[3]], 'h'); + assertEq(str[f32[4]], 'a'); +} +test(setupToInt32, testToInt32); + +function setupBailoutToInt32() { + f32[0] = .5; +} +function testBailoutToInt32() { + assertEq(typeof str[f32[0]], 'undefined'); +} +test(setupBailoutToInt32, testBailoutToInt32); + +// MMath (no trigo - see also testFloat32-trigo.js +function assertNear(a, b) { + var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b; + if (!r) { + print('Precision error: '); + print(new Error().stack); + print('Got', a, ', expected near', b); + assertEq(false, true); + } +} + +function setupOtherMath() { + setupComp(); + f32[8] = 4.2; +} +function otherMath() { + for (var i = 0; i < 9; ++i) { + assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i])); + assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i])); + } +}; +test(setupOtherMath, otherMath); + +function setupFloor() { + f32[0] = -5.5; + f32[1] = -0.5; + f32[2] = 0; + f32[3] = 1.5; +} +function setupFloorDouble() { + f32[4] = NaN; + f32[5] = -0; + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int +} +function testFloor() { + for (var i = 0; i < 4; ++i) { + var f = Math.floor(f32[i]); + assertFloat32(f, false); // f is an int32 + + var g = Math.floor(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +function testFloorDouble() { + for (var i = 4; i < 9; ++i) { + var f = Math.fround(Math.floor(f32[i])); + assertFloat32(f, true); + + var g = Math.floor(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +test(setupFloor, testFloor); +test(setupFloorDouble, testFloorDouble); + +function setupRound() { + f32[0] = -5.5; + f32[1] = -0.6; + f32[2] = 1.5; + f32[3] = 1; +} +function setupRoundDouble() { + f32[4] = NaN; + f32[5] = -0.49; // rounded to -0 + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int + f32[9] = -0; +} +function testRound() { + for (var i = 0; i < 4; ++i) { + var r32 = Math.round(f32[i]); + assertFloat32(r32, false); // r32 is an int32 + + var r64 = Math.round(-0 + f32[i]); + assertFloat32(r64, false); + + assertEq(r32, r64); + } +} +function testRoundDouble() { + for (var i = 4; i < 10; ++i) { + var r32 = Math.fround(Math.round(f32[i])); + assertFloat32(r32, true); + + var r64 = Math.round(-0 + f32[i]); + assertFloat32(r64, false); + + assertEq(r32, r64); + } +} +test(setupRound, testRound); +test(setupRoundDouble, testRoundDouble); + +function setupCeil() { + f32[0] = -5.5; + f32[1] = -1.5; + f32[2] = 0; + f32[3] = 1.5; +} +function setupCeilDouble() { + f32[4] = NaN; + f32[5] = -0; + f32[6] = Infinity; + f32[7] = -Infinity; + f32[8] = Math.pow(2,31); // too big to fit into a int +} +function testCeil() { + for(var i = 0; i < 2; ++i) { + var f = Math.ceil(f32[i]); + assertFloat32(f, false); + + var g = Math.ceil(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +function testCeilDouble() { + for(var i = 4; i < 9; ++i) { + var f = Math.fround(Math.ceil(f32[i])); + assertFloat32(f, true); + + var g = Math.ceil(-0 + f32[i]); + assertFloat32(g, false); + + assertEq(f, g); + } +} +test(setupCeil, testCeil); +test(setupCeilDouble, testCeilDouble); |