1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit-test/tests/ion/testFloat32-correctness.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 1.4 +setJitCompilerOption("ion.usecount.trigger", 50); 1.5 + 1.6 +var f32 = new Float32Array(10); 1.7 + 1.8 +function test(setup, f) { 1.9 + if (f === undefined) { 1.10 + f = setup; 1.11 + setup = function(){}; 1.12 + } 1.13 + setup(); 1.14 + for(var n = 200; n; --n) { 1.15 + f(); 1.16 + } 1.17 +} 1.18 + 1.19 +// Basic arithmetic 1.20 +function setupBasicArith() { 1.21 + f32[0] = -Infinity; 1.22 + f32[1] = -1; 1.23 + f32[2] = -0; 1.24 + f32[3] = 0; 1.25 + f32[4] = 1.337; 1.26 + f32[5] = 42; 1.27 + f32[6] = Infinity; 1.28 + f32[7] = NaN; 1.29 +} 1.30 +function basicArith() { 1.31 + for (var i = 0; i < 7; ++i) { 1.32 + var opf = Math.fround(f32[i] + f32[i+1]); 1.33 + var opd = (1 / (1 / f32[i])) + f32[i+1]; 1.34 + assertFloat32(opf, true); 1.35 + assertFloat32(opd, false); 1.36 + assertEq(opf, Math.fround(opd)); 1.37 + 1.38 + opf = Math.fround(f32[i] - f32[i+1]); 1.39 + opd = (1 / (1 / f32[i])) - f32[i+1]; 1.40 + assertFloat32(opf, true); 1.41 + assertFloat32(opd, false); 1.42 + assertEq(opf, Math.fround(opd)); 1.43 + 1.44 + opf = Math.fround(f32[i] * f32[i+1]); 1.45 + opd = (1 / (1 / f32[i])) * f32[i+1]; 1.46 + assertFloat32(opf, true); 1.47 + assertFloat32(opd, false); 1.48 + assertEq(opf, Math.fround(opd)); 1.49 + 1.50 + opf = Math.fround(f32[i] / f32[i+1]); 1.51 + opd = (1 / (1 / f32[i])) / f32[i+1]; 1.52 + assertFloat32(opf, true); 1.53 + assertFloat32(opd, false); 1.54 + assertEq(opf, Math.fround(opd)); 1.55 + } 1.56 +} 1.57 +test(setupBasicArith, basicArith); 1.58 + 1.59 +// MAbs 1.60 +function setupAbs() { 1.61 + f32[0] = -0; 1.62 + f32[1] = 0; 1.63 + f32[2] = -3.14159; 1.64 + f32[3] = 3.14159; 1.65 + f32[4] = -Infinity; 1.66 + f32[5] = Infinity; 1.67 + f32[6] = NaN; 1.68 +} 1.69 +function abs() { 1.70 + for(var i = 0; i < 7; ++i) { 1.71 + assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) ); 1.72 + } 1.73 +} 1.74 +test(setupAbs, abs); 1.75 + 1.76 +// MSqrt 1.77 +function setupSqrt() { 1.78 + f32[0] = 0; 1.79 + f32[1] = 1; 1.80 + f32[2] = 4; 1.81 + f32[3] = -1; 1.82 + f32[4] = Infinity; 1.83 + f32[5] = NaN; 1.84 + f32[6] = 13.37; 1.85 +} 1.86 +function sqrt() { 1.87 + for(var i = 0; i < 7; ++i) { 1.88 + var sqrtf = Math.fround(Math.sqrt(f32[i])); 1.89 + var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops 1.90 + assertEq( sqrtf, Math.fround(sqrtd) ); 1.91 + } 1.92 +} 1.93 +test(setupSqrt, sqrt); 1.94 + 1.95 +// MTruncateToInt32 1.96 +// The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul 1.97 +function setupTruncateToInt32() { 1.98 + f32[0] = -1; 1.99 + f32[1] = 4; 1.100 + f32[2] = 5.13; 1.101 +} 1.102 +function truncateToInt32() { 1.103 + assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) ); 1.104 + assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) ); 1.105 +} 1.106 +test(setupTruncateToInt32, truncateToInt32); 1.107 + 1.108 +// MCompare 1.109 +function comp() { 1.110 + for(var i = 0; i < 9; ++i) { 1.111 + assertEq( f32[i] < f32[i+1], true ); 1.112 + } 1.113 +} 1.114 +function setupComp() { 1.115 + f32[0] = -Infinity; 1.116 + f32[1] = -1; 1.117 + f32[2] = -0.01; 1.118 + f32[3] = 0; 1.119 + f32[4] = 0.01; 1.120 + f32[5] = 1; 1.121 + f32[6] = 10; 1.122 + f32[7] = 13.37; 1.123 + f32[8] = 42; 1.124 + f32[9] = Infinity; 1.125 +} 1.126 +test(setupComp, comp); 1.127 + 1.128 +// MNot 1.129 +function setupNot() { 1.130 + f32[0] = -0; 1.131 + f32[1] = 0; 1.132 + f32[2] = 1; 1.133 + f32[3] = NaN; 1.134 + f32[4] = Infinity; 1.135 + f32[5] = 42; 1.136 + f32[5] = -23; 1.137 +} 1.138 +function not() { 1.139 + assertEq( !f32[0], true ); 1.140 + assertEq( !f32[1], true ); 1.141 + assertEq( !f32[2], false ); 1.142 + assertEq( !f32[3], true ); 1.143 + assertEq( !f32[4], false ); 1.144 + assertEq( !f32[5], false ); 1.145 + assertEq( !f32[6], false ); 1.146 +} 1.147 +test(setupNot, not); 1.148 + 1.149 +// MToInt32 1.150 +var str = "can haz cheezburger? okthxbye;"; 1.151 +function setupToInt32() { 1.152 + f32[0] = 0; 1.153 + f32[1] = 1; 1.154 + f32[2] = 2; 1.155 + f32[3] = 4; 1.156 + f32[4] = 5; 1.157 +} 1.158 +function testToInt32() { 1.159 + assertEq(str[f32[0]], 'c'); 1.160 + assertEq(str[f32[1]], 'a'); 1.161 + assertEq(str[f32[2]], 'n'); 1.162 + assertEq(str[f32[3]], 'h'); 1.163 + assertEq(str[f32[4]], 'a'); 1.164 +} 1.165 +test(setupToInt32, testToInt32); 1.166 + 1.167 +function setupBailoutToInt32() { 1.168 + f32[0] = .5; 1.169 +} 1.170 +function testBailoutToInt32() { 1.171 + assertEq(typeof str[f32[0]], 'undefined'); 1.172 +} 1.173 +test(setupBailoutToInt32, testBailoutToInt32); 1.174 + 1.175 +// MMath (no trigo - see also testFloat32-trigo.js 1.176 +function assertNear(a, b) { 1.177 + var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b; 1.178 + if (!r) { 1.179 + print('Precision error: '); 1.180 + print(new Error().stack); 1.181 + print('Got', a, ', expected near', b); 1.182 + assertEq(false, true); 1.183 + } 1.184 +} 1.185 + 1.186 +function setupOtherMath() { 1.187 + setupComp(); 1.188 + f32[8] = 4.2; 1.189 +} 1.190 +function otherMath() { 1.191 + for (var i = 0; i < 9; ++i) { 1.192 + assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i])); 1.193 + assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i])); 1.194 + } 1.195 +}; 1.196 +test(setupOtherMath, otherMath); 1.197 + 1.198 +function setupFloor() { 1.199 + f32[0] = -5.5; 1.200 + f32[1] = -0.5; 1.201 + f32[2] = 0; 1.202 + f32[3] = 1.5; 1.203 +} 1.204 +function setupFloorDouble() { 1.205 + f32[4] = NaN; 1.206 + f32[5] = -0; 1.207 + f32[6] = Infinity; 1.208 + f32[7] = -Infinity; 1.209 + f32[8] = Math.pow(2,31); // too big to fit into a int 1.210 +} 1.211 +function testFloor() { 1.212 + for (var i = 0; i < 4; ++i) { 1.213 + var f = Math.floor(f32[i]); 1.214 + assertFloat32(f, false); // f is an int32 1.215 + 1.216 + var g = Math.floor(-0 + f32[i]); 1.217 + assertFloat32(g, false); 1.218 + 1.219 + assertEq(f, g); 1.220 + } 1.221 +} 1.222 +function testFloorDouble() { 1.223 + for (var i = 4; i < 9; ++i) { 1.224 + var f = Math.fround(Math.floor(f32[i])); 1.225 + assertFloat32(f, true); 1.226 + 1.227 + var g = Math.floor(-0 + f32[i]); 1.228 + assertFloat32(g, false); 1.229 + 1.230 + assertEq(f, g); 1.231 + } 1.232 +} 1.233 +test(setupFloor, testFloor); 1.234 +test(setupFloorDouble, testFloorDouble); 1.235 + 1.236 +function setupRound() { 1.237 + f32[0] = -5.5; 1.238 + f32[1] = -0.6; 1.239 + f32[2] = 1.5; 1.240 + f32[3] = 1; 1.241 +} 1.242 +function setupRoundDouble() { 1.243 + f32[4] = NaN; 1.244 + f32[5] = -0.49; // rounded to -0 1.245 + f32[6] = Infinity; 1.246 + f32[7] = -Infinity; 1.247 + f32[8] = Math.pow(2,31); // too big to fit into a int 1.248 + f32[9] = -0; 1.249 +} 1.250 +function testRound() { 1.251 + for (var i = 0; i < 4; ++i) { 1.252 + var r32 = Math.round(f32[i]); 1.253 + assertFloat32(r32, false); // r32 is an int32 1.254 + 1.255 + var r64 = Math.round(-0 + f32[i]); 1.256 + assertFloat32(r64, false); 1.257 + 1.258 + assertEq(r32, r64); 1.259 + } 1.260 +} 1.261 +function testRoundDouble() { 1.262 + for (var i = 4; i < 10; ++i) { 1.263 + var r32 = Math.fround(Math.round(f32[i])); 1.264 + assertFloat32(r32, true); 1.265 + 1.266 + var r64 = Math.round(-0 + f32[i]); 1.267 + assertFloat32(r64, false); 1.268 + 1.269 + assertEq(r32, r64); 1.270 + } 1.271 +} 1.272 +test(setupRound, testRound); 1.273 +test(setupRoundDouble, testRoundDouble); 1.274 + 1.275 +function setupCeil() { 1.276 + f32[0] = -5.5; 1.277 + f32[1] = -1.5; 1.278 + f32[2] = 0; 1.279 + f32[3] = 1.5; 1.280 +} 1.281 +function setupCeilDouble() { 1.282 + f32[4] = NaN; 1.283 + f32[5] = -0; 1.284 + f32[6] = Infinity; 1.285 + f32[7] = -Infinity; 1.286 + f32[8] = Math.pow(2,31); // too big to fit into a int 1.287 +} 1.288 +function testCeil() { 1.289 + for(var i = 0; i < 2; ++i) { 1.290 + var f = Math.ceil(f32[i]); 1.291 + assertFloat32(f, false); 1.292 + 1.293 + var g = Math.ceil(-0 + f32[i]); 1.294 + assertFloat32(g, false); 1.295 + 1.296 + assertEq(f, g); 1.297 + } 1.298 +} 1.299 +function testCeilDouble() { 1.300 + for(var i = 4; i < 9; ++i) { 1.301 + var f = Math.fround(Math.ceil(f32[i])); 1.302 + assertFloat32(f, true); 1.303 + 1.304 + var g = Math.ceil(-0 + f32[i]); 1.305 + assertFloat32(g, false); 1.306 + 1.307 + assertEq(f, g); 1.308 + } 1.309 +} 1.310 +test(setupCeil, testCeil); 1.311 +test(setupCeilDouble, testCeilDouble);