js/src/jit-test/tests/ion/testFloat32-correctness.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 setJitCompilerOption("ion.usecount.trigger", 50);
michael@0 2
michael@0 3 var f32 = new Float32Array(10);
michael@0 4
michael@0 5 function test(setup, f) {
michael@0 6 if (f === undefined) {
michael@0 7 f = setup;
michael@0 8 setup = function(){};
michael@0 9 }
michael@0 10 setup();
michael@0 11 for(var n = 200; n; --n) {
michael@0 12 f();
michael@0 13 }
michael@0 14 }
michael@0 15
michael@0 16 // Basic arithmetic
michael@0 17 function setupBasicArith() {
michael@0 18 f32[0] = -Infinity;
michael@0 19 f32[1] = -1;
michael@0 20 f32[2] = -0;
michael@0 21 f32[3] = 0;
michael@0 22 f32[4] = 1.337;
michael@0 23 f32[5] = 42;
michael@0 24 f32[6] = Infinity;
michael@0 25 f32[7] = NaN;
michael@0 26 }
michael@0 27 function basicArith() {
michael@0 28 for (var i = 0; i < 7; ++i) {
michael@0 29 var opf = Math.fround(f32[i] + f32[i+1]);
michael@0 30 var opd = (1 / (1 / f32[i])) + f32[i+1];
michael@0 31 assertFloat32(opf, true);
michael@0 32 assertFloat32(opd, false);
michael@0 33 assertEq(opf, Math.fround(opd));
michael@0 34
michael@0 35 opf = Math.fround(f32[i] - f32[i+1]);
michael@0 36 opd = (1 / (1 / f32[i])) - f32[i+1];
michael@0 37 assertFloat32(opf, true);
michael@0 38 assertFloat32(opd, false);
michael@0 39 assertEq(opf, Math.fround(opd));
michael@0 40
michael@0 41 opf = Math.fround(f32[i] * f32[i+1]);
michael@0 42 opd = (1 / (1 / f32[i])) * f32[i+1];
michael@0 43 assertFloat32(opf, true);
michael@0 44 assertFloat32(opd, false);
michael@0 45 assertEq(opf, Math.fround(opd));
michael@0 46
michael@0 47 opf = Math.fround(f32[i] / f32[i+1]);
michael@0 48 opd = (1 / (1 / f32[i])) / f32[i+1];
michael@0 49 assertFloat32(opf, true);
michael@0 50 assertFloat32(opd, false);
michael@0 51 assertEq(opf, Math.fround(opd));
michael@0 52 }
michael@0 53 }
michael@0 54 test(setupBasicArith, basicArith);
michael@0 55
michael@0 56 // MAbs
michael@0 57 function setupAbs() {
michael@0 58 f32[0] = -0;
michael@0 59 f32[1] = 0;
michael@0 60 f32[2] = -3.14159;
michael@0 61 f32[3] = 3.14159;
michael@0 62 f32[4] = -Infinity;
michael@0 63 f32[5] = Infinity;
michael@0 64 f32[6] = NaN;
michael@0 65 }
michael@0 66 function abs() {
michael@0 67 for(var i = 0; i < 7; ++i) {
michael@0 68 assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) );
michael@0 69 }
michael@0 70 }
michael@0 71 test(setupAbs, abs);
michael@0 72
michael@0 73 // MSqrt
michael@0 74 function setupSqrt() {
michael@0 75 f32[0] = 0;
michael@0 76 f32[1] = 1;
michael@0 77 f32[2] = 4;
michael@0 78 f32[3] = -1;
michael@0 79 f32[4] = Infinity;
michael@0 80 f32[5] = NaN;
michael@0 81 f32[6] = 13.37;
michael@0 82 }
michael@0 83 function sqrt() {
michael@0 84 for(var i = 0; i < 7; ++i) {
michael@0 85 var sqrtf = Math.fround(Math.sqrt(f32[i]));
michael@0 86 var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops
michael@0 87 assertEq( sqrtf, Math.fround(sqrtd) );
michael@0 88 }
michael@0 89 }
michael@0 90 test(setupSqrt, sqrt);
michael@0 91
michael@0 92 // MTruncateToInt32
michael@0 93 // The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul
michael@0 94 function setupTruncateToInt32() {
michael@0 95 f32[0] = -1;
michael@0 96 f32[1] = 4;
michael@0 97 f32[2] = 5.13;
michael@0 98 }
michael@0 99 function truncateToInt32() {
michael@0 100 assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) );
michael@0 101 assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) );
michael@0 102 }
michael@0 103 test(setupTruncateToInt32, truncateToInt32);
michael@0 104
michael@0 105 // MCompare
michael@0 106 function comp() {
michael@0 107 for(var i = 0; i < 9; ++i) {
michael@0 108 assertEq( f32[i] < f32[i+1], true );
michael@0 109 }
michael@0 110 }
michael@0 111 function setupComp() {
michael@0 112 f32[0] = -Infinity;
michael@0 113 f32[1] = -1;
michael@0 114 f32[2] = -0.01;
michael@0 115 f32[3] = 0;
michael@0 116 f32[4] = 0.01;
michael@0 117 f32[5] = 1;
michael@0 118 f32[6] = 10;
michael@0 119 f32[7] = 13.37;
michael@0 120 f32[8] = 42;
michael@0 121 f32[9] = Infinity;
michael@0 122 }
michael@0 123 test(setupComp, comp);
michael@0 124
michael@0 125 // MNot
michael@0 126 function setupNot() {
michael@0 127 f32[0] = -0;
michael@0 128 f32[1] = 0;
michael@0 129 f32[2] = 1;
michael@0 130 f32[3] = NaN;
michael@0 131 f32[4] = Infinity;
michael@0 132 f32[5] = 42;
michael@0 133 f32[5] = -23;
michael@0 134 }
michael@0 135 function not() {
michael@0 136 assertEq( !f32[0], true );
michael@0 137 assertEq( !f32[1], true );
michael@0 138 assertEq( !f32[2], false );
michael@0 139 assertEq( !f32[3], true );
michael@0 140 assertEq( !f32[4], false );
michael@0 141 assertEq( !f32[5], false );
michael@0 142 assertEq( !f32[6], false );
michael@0 143 }
michael@0 144 test(setupNot, not);
michael@0 145
michael@0 146 // MToInt32
michael@0 147 var str = "can haz cheezburger? okthxbye;";
michael@0 148 function setupToInt32() {
michael@0 149 f32[0] = 0;
michael@0 150 f32[1] = 1;
michael@0 151 f32[2] = 2;
michael@0 152 f32[3] = 4;
michael@0 153 f32[4] = 5;
michael@0 154 }
michael@0 155 function testToInt32() {
michael@0 156 assertEq(str[f32[0]], 'c');
michael@0 157 assertEq(str[f32[1]], 'a');
michael@0 158 assertEq(str[f32[2]], 'n');
michael@0 159 assertEq(str[f32[3]], 'h');
michael@0 160 assertEq(str[f32[4]], 'a');
michael@0 161 }
michael@0 162 test(setupToInt32, testToInt32);
michael@0 163
michael@0 164 function setupBailoutToInt32() {
michael@0 165 f32[0] = .5;
michael@0 166 }
michael@0 167 function testBailoutToInt32() {
michael@0 168 assertEq(typeof str[f32[0]], 'undefined');
michael@0 169 }
michael@0 170 test(setupBailoutToInt32, testBailoutToInt32);
michael@0 171
michael@0 172 // MMath (no trigo - see also testFloat32-trigo.js
michael@0 173 function assertNear(a, b) {
michael@0 174 var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b;
michael@0 175 if (!r) {
michael@0 176 print('Precision error: ');
michael@0 177 print(new Error().stack);
michael@0 178 print('Got', a, ', expected near', b);
michael@0 179 assertEq(false, true);
michael@0 180 }
michael@0 181 }
michael@0 182
michael@0 183 function setupOtherMath() {
michael@0 184 setupComp();
michael@0 185 f32[8] = 4.2;
michael@0 186 }
michael@0 187 function otherMath() {
michael@0 188 for (var i = 0; i < 9; ++i) {
michael@0 189 assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i]));
michael@0 190 assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i]));
michael@0 191 }
michael@0 192 };
michael@0 193 test(setupOtherMath, otherMath);
michael@0 194
michael@0 195 function setupFloor() {
michael@0 196 f32[0] = -5.5;
michael@0 197 f32[1] = -0.5;
michael@0 198 f32[2] = 0;
michael@0 199 f32[3] = 1.5;
michael@0 200 }
michael@0 201 function setupFloorDouble() {
michael@0 202 f32[4] = NaN;
michael@0 203 f32[5] = -0;
michael@0 204 f32[6] = Infinity;
michael@0 205 f32[7] = -Infinity;
michael@0 206 f32[8] = Math.pow(2,31); // too big to fit into a int
michael@0 207 }
michael@0 208 function testFloor() {
michael@0 209 for (var i = 0; i < 4; ++i) {
michael@0 210 var f = Math.floor(f32[i]);
michael@0 211 assertFloat32(f, false); // f is an int32
michael@0 212
michael@0 213 var g = Math.floor(-0 + f32[i]);
michael@0 214 assertFloat32(g, false);
michael@0 215
michael@0 216 assertEq(f, g);
michael@0 217 }
michael@0 218 }
michael@0 219 function testFloorDouble() {
michael@0 220 for (var i = 4; i < 9; ++i) {
michael@0 221 var f = Math.fround(Math.floor(f32[i]));
michael@0 222 assertFloat32(f, true);
michael@0 223
michael@0 224 var g = Math.floor(-0 + f32[i]);
michael@0 225 assertFloat32(g, false);
michael@0 226
michael@0 227 assertEq(f, g);
michael@0 228 }
michael@0 229 }
michael@0 230 test(setupFloor, testFloor);
michael@0 231 test(setupFloorDouble, testFloorDouble);
michael@0 232
michael@0 233 function setupRound() {
michael@0 234 f32[0] = -5.5;
michael@0 235 f32[1] = -0.6;
michael@0 236 f32[2] = 1.5;
michael@0 237 f32[3] = 1;
michael@0 238 }
michael@0 239 function setupRoundDouble() {
michael@0 240 f32[4] = NaN;
michael@0 241 f32[5] = -0.49; // rounded to -0
michael@0 242 f32[6] = Infinity;
michael@0 243 f32[7] = -Infinity;
michael@0 244 f32[8] = Math.pow(2,31); // too big to fit into a int
michael@0 245 f32[9] = -0;
michael@0 246 }
michael@0 247 function testRound() {
michael@0 248 for (var i = 0; i < 4; ++i) {
michael@0 249 var r32 = Math.round(f32[i]);
michael@0 250 assertFloat32(r32, false); // r32 is an int32
michael@0 251
michael@0 252 var r64 = Math.round(-0 + f32[i]);
michael@0 253 assertFloat32(r64, false);
michael@0 254
michael@0 255 assertEq(r32, r64);
michael@0 256 }
michael@0 257 }
michael@0 258 function testRoundDouble() {
michael@0 259 for (var i = 4; i < 10; ++i) {
michael@0 260 var r32 = Math.fround(Math.round(f32[i]));
michael@0 261 assertFloat32(r32, true);
michael@0 262
michael@0 263 var r64 = Math.round(-0 + f32[i]);
michael@0 264 assertFloat32(r64, false);
michael@0 265
michael@0 266 assertEq(r32, r64);
michael@0 267 }
michael@0 268 }
michael@0 269 test(setupRound, testRound);
michael@0 270 test(setupRoundDouble, testRoundDouble);
michael@0 271
michael@0 272 function setupCeil() {
michael@0 273 f32[0] = -5.5;
michael@0 274 f32[1] = -1.5;
michael@0 275 f32[2] = 0;
michael@0 276 f32[3] = 1.5;
michael@0 277 }
michael@0 278 function setupCeilDouble() {
michael@0 279 f32[4] = NaN;
michael@0 280 f32[5] = -0;
michael@0 281 f32[6] = Infinity;
michael@0 282 f32[7] = -Infinity;
michael@0 283 f32[8] = Math.pow(2,31); // too big to fit into a int
michael@0 284 }
michael@0 285 function testCeil() {
michael@0 286 for(var i = 0; i < 2; ++i) {
michael@0 287 var f = Math.ceil(f32[i]);
michael@0 288 assertFloat32(f, false);
michael@0 289
michael@0 290 var g = Math.ceil(-0 + f32[i]);
michael@0 291 assertFloat32(g, false);
michael@0 292
michael@0 293 assertEq(f, g);
michael@0 294 }
michael@0 295 }
michael@0 296 function testCeilDouble() {
michael@0 297 for(var i = 4; i < 9; ++i) {
michael@0 298 var f = Math.fround(Math.ceil(f32[i]));
michael@0 299 assertFloat32(f, true);
michael@0 300
michael@0 301 var g = Math.ceil(-0 + f32[i]);
michael@0 302 assertFloat32(g, false);
michael@0 303
michael@0 304 assertEq(f, g);
michael@0 305 }
michael@0 306 }
michael@0 307 test(setupCeil, testCeil);
michael@0 308 test(setupCeilDouble, testCeilDouble);

mercurial