diff options
Diffstat (limited to 'js/src/jit-test/tests/ion/test-scalar-replacement-float32.js')
-rw-r--r-- | js/src/jit-test/tests/ion/test-scalar-replacement-float32.js | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js b/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js new file mode 100644 index 0000000000..3302381f14 --- /dev/null +++ b/js/src/jit-test/tests/ion/test-scalar-replacement-float32.js @@ -0,0 +1,98 @@ +setJitCompilerOption("ion.warmup.trigger", 30); +var max = 40; + +// This test case verify that even if we do some scalar replacement, we keep a +// correct computation of Float32 maths. In this case, when the object is not +// escaped, the "store" instruction are preventing any float32 optimization to +// kick-in. After Scalar Replacement, the store is removed, and the Float32 +// optimizations can avoid Double coercions. +function escape_object(o) { + if (o.e) { + print(o); + } +} + +var func = null; +var check_object_argument_func = function (i, res) { + with ({}) { /* trun off the jit for this function, do not inline */ }; + if (i == max - 1) + return funname.arguments[1].d; + return res; +}; + +var test_object_ref_check = eval(`(${check_object_argument_func})`.replace("funname", "test_object_ref")); +function test_object_ref(x, tmp) { + tmp = { + a: Math.fround(Math.pow(2 * x / max, 0)), + b: Math.fround(Math.pow(2 * x / max, 25)), + c: Math.fround(Math.pow(2 * x / max, 50)), + d: 0 + }; + + tmp.d = tmp.a + tmp.b; + assertFloat32(tmp.d, false); + escape_object(tmp); + return test_object_ref_check(x, Math.fround(tmp.c + Math.fround(tmp.d))); +} + +var test_object_check = eval(`(${check_object_argument_func})`.replace("funname", "test_object")); +function test_object(x, tmp) { + tmp = { + a: Math.fround(Math.pow(2 * x / max, 0)), + b: Math.fround(Math.pow(2 * x / max, 25)), + c: Math.fround(Math.pow(2 * x / max, 50)), + d: 0 + }; + + tmp.d = tmp.a + tmp.b; + assertFloat32(tmp.d, false); + return test_object_check(x, Math.fround(tmp.c + Math.fround(tmp.d))); +} + +// Same test with Arrays. +function escape_array(o) { + if (o.length == 0) { + print(o); + } +} + +var check_array_argument_func = function (i, res) { + with ({}) { /* trun off the jit for this function, do not inline */ }; + if (i == max - 1) { + return funname.arguments[1][3]; + } + return res; +}; + +var test_array_ref_check = eval(`(${check_array_argument_func})`.replace("funname", "test_array_ref")); +function test_array_ref(x, tmp) { + tmp = [ + Math.fround(Math.pow(2 * x / max, 0)), + Math.fround(Math.pow(2 * x / max, 25)), + Math.fround(Math.pow(2 * x / max, 50)), + 0 + ]; + tmp[3] = tmp[0] + tmp[1]; + assertFloat32(tmp[3], false); + escape_array(tmp); + return test_array_ref_check(x, Math.fround(tmp[2] + Math.fround(tmp[3]))); +} + +var test_array_check = eval(`(${check_array_argument_func})`.replace("funname", "test_array")); +function test_array(x, tmp) { + tmp = [ + Math.fround(Math.pow(2 * x / max, 0)), + Math.fround(Math.pow(2 * x / max, 25)), + Math.fround(Math.pow(2 * x / max, 50)), + 0 + ]; + tmp[3] = tmp[0] + tmp[1]; + assertFloat32(tmp[3], false); + return test_array_check(x, Math.fround(tmp[2] + Math.fround(tmp[3]))); +} + + +for (var i = 0; i < max; i++) { + assertEq(test_object_ref(i, undefined), test_object(i, undefined)); + assertEq(test_array_ref(i, undefined), test_array(i, undefined)); +} |