diff options
Diffstat (limited to 'js/src/jit-test/tests/ion/pow-base-power-of-two.js')
-rw-r--r-- | js/src/jit-test/tests/ion/pow-base-power-of-two.js | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/pow-base-power-of-two.js b/js/src/jit-test/tests/ion/pow-base-power-of-two.js new file mode 100644 index 0000000000..35ae52a28d --- /dev/null +++ b/js/src/jit-test/tests/ion/pow-base-power-of-two.js @@ -0,0 +1,75 @@ +// Lowering provides a specialisation when the base operand is a constant which +// is a power of two. + +loadRelativeToScript("../../../tests/non262/Math/shell.js"); + +function test(x, y, z) { + function pow(x, y) { return `Math.pow(${x}, ${y})` }; + function exp(x, y) { return `((${x}) ** ${y})` }; + + function make(fn, x, y, z) { + return Function(` + // Load from array to prevent constant-folding. + // (Ion is currently not smart enough to realise that both array + // values are the same.) + var ys = [${y}, ${y}]; + var zs = [${z}, ${z}]; + for (var i = 0; i < 1000; ++i) { + assertNear(${fn(x, "ys[i & 1]")}, zs[i & 1]); + } + `); + } + + function double(v) { + // NB: numberToDouble() always returns a double value. + return `numberToDouble(${v})`; + } + + function addTests(fn) { + tests.push(make(fn, x, y, z)); + tests.push(make(fn, x, double(y), z)); + tests.push(make(fn, double(x), y, z)); + tests.push(make(fn, double(x), double(y), z)); + } + + var tests = []; + addTests(pow); + addTests(exp); + + for (var i = 0; i < tests.length; ++i) { + for (var j = 0; j < 2; ++j) { + tests[i](); + } + } +} + +function* range(a, b, fn) { + for (var i = a; i <= b; ++i) { + yield fn(i); + } +} + +// Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test +// the next power-of-two values, 1 and 0, and negative base-of-two values. +var values = [ + ...range(1, 10, i => 2 ** i), + 1, + 0, + ...range(1, 4, i => -(2 ** i)), +]; + +for (var x of values) { + test(x, 0, 1); + test(x, 1, x); + test(x, 2, x * x); + + // 0**(negative) is Infinity, 1**(negative) is 1. + if (Math.abs(x) > 1) { + test(x, -1076, 0); + } + + // (negative)**(odd-negative) is -0. + if (x > 1) { + test(x, -1075, 0); + } +} |