| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- // Compares the value set by interpreter with the jitted code
- // need to run with -mic:1 -off:simplejit -off:jitloopbody -off:inline -off:globopt:1.18-1.30
- // Run locally with -trace:memop -trace:bailout to help find bugs
- let testCases = [
- function() {
- return {
- start: 0,
- end: 100,
- test: function testBasic(a, src) {
- for(let i = 0; i < 100; i++) {
- a[i] = src[i];
- }
- }
- };
- },
- function() {
- return {
- start: 0,
- end: 100,
- test: function testChangedIndex(a, src) {
- // This is an invalid memcopy
- for(let i = 0; i < 100;) {
- a[i] = src[++i];
- }
- }
- };
- },
- function() {
- let src = new Array(100);
- for(let i = 0; i < 100; ++i) {
- src[i] = i;
- }
- return {
- start: 0,
- end: 100,
- test: function testLdSlot(a) {
- // Invalid pattern, src is not considered invariant
- for(let i = 0; i < 100; ++i) {
- a[i] = src[i];
- }
- }
- };
- },
- function() {
- let start = 5, end = 101;
- return {
- start: start,
- end: end,
- size: end,
- test: function testReverse(a, src) {
- for(let i = 100; i >= 5; i--) {
- a[i] = src[i];
- }
- }
- };
- },
- function() {
- let results = [];
- let start = 0, end = 10;
- return {
- start: start,
- end: end,
- runner: function testMultipleMemcopy(arrayGen, src) {
- let a = arrayGen(), b = arrayGen(), c = arrayGen();
- // Currently this is not a valid memcopy pattern (would it be more performant?)
- for(let i = 0; i < 10; i++) {
- a[i] = b[i] = c[i] = src[i];
- }
- results.push([a, b, c]);
- },
- check: function() {
- let base = results[0];
- for(let i = 1; i < results.length; ++i) {
- for(let j = 0; j < 3; ++j) {
- compareResult("testMultipleMemcopy", base[j], results[i][j], start, end);
- }
- }
- }
- };
- },
- function() {
- return {
- start: 0,
- end: 10,
- test: function preIncr(a, src) {
- let ri = -1;
- for(let i = 0; i < 10; ++i) {
- a[++ri] = src[ri];
- }
- }
- };
- },
- function() {
- return {
- start: -50,
- end: 10,
- loop: 10, // Run this a few times to cause rejit,
- test: function testNegativeStartIndex(a, src) {
- for(let i = -50; i < 10; i++) {
- // This should bailout on MemOp because the index will be negative
- a[i] = src[i];
- }
- }
- };
- },
- function() {
- return {
- start: 0,
- end: 128,
- test: function bug4468518(a, src) {
- let x = 0;
- for(let i = 0; i < 128; i++) {
- let m = src[i];
- x += m;
- a[i] = m;
- }
- return x;
- }
- };
- }
- ];
- let passed = true;
- function compareResult(name, a, b, start, end, start2) {
- for(let i = start, j = start2 || start; i < end; ++i, ++j) {
- if(a[i] !== b[j]) {
- print(`Error ${name}: a[${i}](${a[i]}) !== b[${j}](${b[j]})`);
- passed = false;
- return false;
- }
- }
- return true;
- }
- const isFloatTest = WScript.Arguments[0] === "float";
- function makeArray(size = 10) {
- let a = new Array(size);
- for(let i = 0; i < size; ++i) {
- a[i] = isFloatTest ? 0.5 : 0;
- }
- if (isFloatTest) {
- return eval(`[${a.join(", ")}]`);
- }
- return a;
- }
- let arrayGenerators = [
- makeArray,
- ];
- function makeFloatArray(size = 10) {
- const arrayValues = new Array(size);
- for(let i = 0; i < size; ++i) {
- arrayValues[i] = Math.random() / Math.random() * (Math.random() < 0.2 ? -1 : 1);
- }
- return eval(`[${arrayValues.join(", ")}]`);
- }
- function makeSource(size = 10) {
- if (isFloatTest) return makeFloatArray(size);
- let s = new Array(size);
- for(let i = 0; i < size; ++i) {
- s[i] = i;
- }
- return s;
- }
- for(let testCase of testCases) {
- let results = [];
- let testInfo = testCase();
- let name = testInfo.runner && testInfo.runner.name || testInfo.test && testInfo.test.name || "Unknown";
- let src;
- if(!testInfo.makeSource) {
- if (testInfo.size !== undefined) {
- src = makeSource(testInfo.size);
- } else if(
- testInfo.start !== undefined &&
- testInfo.end !== undefined
- ) {
- src = makeSource(testInfo.end - testInfo.start);
- }
- }
- function run(gen) {
- if(testInfo.makeSource) {
- src = testInfo.makeSource();
- }
- if(testInfo.runner) {
- let result = testInfo.runner(gen, src);
- results.push(result);
- } else {
- let newArray = gen(testInfo.size || testInfo.end - testInfo.start);
- testInfo.test(newArray, src);
- results.push(newArray);
- }
- }
- // Run once for the interpreter
- run(makeArray);
- for(let gen of arrayGenerators) {
- if(testInfo.loop | 0) {
- for(let i = 0; i < testInfo.loop; ++i) {
- run(gen);
- }
- } else {
- run(gen);
- }
- }
- if(testInfo.check) {
- testInfo.check(results);
- } else {
- let base = results[0]; // result from the interpreter
- for(let i = 1; i < results.length; ++i) {
- compareResult(name, base, results[i], testInfo.start, testInfo.end);
- }
- }
- }
- if(passed) {
- print("PASSED");
- } else {
- print("FAILED");
- }
|