// Comprehensively test wasm compare-then-select, for all combinations of // // compare in i32 i64 // select in i32 i64 // compare-op in eq ne lt_s lt_u gt_s gt_u le_s le_u ge_s ge_u // // and using comparison values from all 4 quadrant points of the range, // including at least one either side, so as to catch off-by-one comparison // errors. In total 9000 tests. const cmpVals32 = [ 0x00000000, 0x00000001, 0x00000002, 0x3fffffff, 0x40000000, 0x40000001, 0x7fffffff, 0x80000000, 0x80000001, 0xbfffffff, 0xc0000000, 0xc0000001, 0xfffffffd, 0xfffffffe, 0xffffffff ]; const cmpVals64 = [ 0x0000000000000000n, 0x0000000000000001n, 0x0000000000000002n, 0x3fffffffffffffffn, 0x4000000000000000n, 0x4000000000000001n, 0x7fffffffffffffffn, 0x8000000000000000n, 0x8000000000000001n, 0xbfffffffffffffffn, 0xc000000000000000n, 0xc000000000000001n, 0xfffffffffffffffdn, 0xfffffffffffffffen, 0xffffffffffffffffn ]; const selVal32L = 0x55551234; const selVal32R = 0x55554321; const selVal64L = 0x5555555555554771n; const selVal64R = 0x5555555555551337n; function getCmpVals(cmpTy) { if (cmpTy === 'i32') { return cmpVals32; } else { assertEq(cmpTy, 'i64'); return cmpVals64; } } function classifyResult(selTy, result) { if (selTy === 'i32') { if (result === selVal32L) { return '0'; } if (result === selVal32R) { return '1'; } } else { assertEq(selTy, 'i64'); if (result === selVal64L) { return '2'; } if (result === selVal64R) { return '3'; } } // Anything that is not '0', '1', '2' or '3' will cause the final // summary-string comparison below to fail. return 'BAD'; } let actualSummaryString = ''; for ( cmpTy of [ 'i32', 'i64' ] ) { for ( selTy of [ 'i32', 'i64' ] ) { for ( cmpOp of [ 'eq', 'ne', 'lt_s', 'lt_u', 'gt_s', 'gt_u', 'le_s', 'le_u', 'ge_s', 'ge_u' ] ) { let t = `(module (func (export "f") (param $p1 ${cmpTy}) (param $p2 ${cmpTy}) (param $p3 ${selTy}) (param $p4 ${selTy}) (result ${selTy}) (select (local.get $p3) (local.get $p4) (${cmpTy}.${cmpOp} (local.get $p1) (local.get $p2))) ) )`; let i = new WebAssembly.Instance( new WebAssembly.Module(wasmTextToBinary(t))); let cmpVals = getCmpVals(cmpTy); let selValL, selValR; if (selTy === 'i32') { selValL = selVal32L; selValR = selVal32R; } else { assertEq(selTy, 'i64'); selValL = selVal64L; selValR = selVal64R; } for ( cmpValL of cmpVals ) { for ( cmpValR of cmpVals ) { let res = i.exports.f(cmpValL, cmpValR, selValL, selValR); // We expect res to be one of selVal{L,R} values. // Check that and add its summary to the running string. let classified = classifyResult(selTy, res); actualSummaryString += classified; } } } } } // We expect to run exactly 9000 tests: // 2 cmp types x 2 sel types x 10 conditions (= 40 wasm functions) // x 15 cmp argLs x 15 cmp argRs = 9000 assertEq(actualSummaryString.length, 9000); // The expected summary string, one char for each test, encoded per // function classifyResult above. 150 lines of 60 chars each. let expectedSummaryString = '011111111111111101111111111111110111111111111111011111111111' + '111101111111111111110111111111111111011111111111111101111111' + '111111110111111111111111011111111111111101111111111111110111' + '111111111111011111111111111101111111111111110100000000000000' + '010000000000000001000000000000000100000000000000010000000000' + '000001000000000000000100000000000000010000000000000001000000' + '000000000100000000000000010000000000000001000000000000000100' + '000000000000010000000000000001100000011111111110000011111111' + '111000011111111111100011111111111110011111111111111011111111' + '111111111111111000000010000000000000011000000000000011100000' + '000000011110000000000011111000000000011111100000000011111110' + '000000011111111100000000000000110000000000000111000000000000' + '111100000000000111110000000000111111000000000111111100000000' + '111111110000000111111111000000111111111100000111111111110000' + '111111111111000111111111111100111111111111110111111111111111' + '111111100000000011111100000000001111100000000000111100000000' + '000011100000000000001100000000000000100000000111111111111111' + '111111101111111111111100111111111111100011111111111100001111' + '111111100000111111111100000011111111100000001111111111111111' + '011111111111111001111111111111000111111111111000011111111111' + '000001111111111000000111111111000000011111111000000001111111' + '000000000111111000000000011111000000000001111000000000000111' + '000000000000011000000000000001000000011111111100000011111111' + '110000011111111111000011111111111100011111111111110011111111' + '111111011111111000000000000000000000010000000000000011000000' + '000000011100000000000011110000000000011111000000000011111100' + '000000011111110000000000000000100000000000000110000000000000' + '111000000000000111100000000000111110000000000111111000000000' + '111111100000000111111110000000111111111000000111111111100000' + '111111111110000111111111111000111111111111100111111111111110' + '011111100000000001111100000000000111100000000000011100000000' + '000001100000000000000100000000000000000000000111111101111111' + '111111100111111111111100011111111111100001111111111100000111' + '111111100000011111111100000001111111100000000011111111111111' + '001111111111111000111111111111000011111111111000001111111111' + '000000111111111000000011111111000000001111111000000000111111' + '000000000011111000000000001111000000000000111000000000000011' + '000000000000001000000000000000233333333333333323333333333333' + '332333333333333333233333333333333323333333333333332333333333' + '333333233333333333333323333333333333332333333333333333233333' + '333333333323333333333333332333333333333333233333333333333323' + '333333333333332322222222222222232222222222222223222222222222' + '222322222222222222232222222222222223222222222222222322222222' + '222222232222222222222223222222222222222322222222222222232222' + '222222222223222222222222222322222222222222232222222222222223' + '322222233333333332222233333333333222233333333333322233333333' + '333332233333333333333233333333333333333333333222222232222222' + '222222233222222222222233322222222222233332222222222233333222' + '222222233333322222222233333332222222233333333322222222222222' + '332222222222222333222222222222333322222222222333332222222222' + '333333222222222333333322222222333333332222222333333333222222' + '333333333322222333333333332222333333333333222333333333333322' + '333333333333332333333333333333333333322222222233333322222222' + '223333322222222222333322222222222233322222222222223322222222' + '222222322222222333333333333333333333323333333333333322333333' + '333333322233333333333322223333333333322222333333333322222233' + '333333322222223333333333333333233333333333333223333333333333' + '222333333333333222233333333333222223333333333222222333333333' + '222222233333333222222223333333222222222333333222222222233333' + '222222222223333222222222222333222222222222233222222222222223' + '222222233333333322222233333333332222233333333333222233333333' + '333322233333333333332233333333333333233333333222222222222222' + '222222232222222222222233222222222222233322222222222233332222' + '222222233333222222222233333322222222233333332222222222222222' + '322222222222222332222222222222333222222222222333322222222222' + '333332222222222333333222222222333333322222222333333332222222' + '333333333222222333333333322222333333333332222333333333333222' + '333333333333322333333333333332233333322222222223333322222222' + '222333322222222222233322222222222223322222222222222322222222' + '222222222222222333333323333333333333322333333333333322233333' + '333333322223333333333322222333333333322222233333333322222223' + '333333322222222233333333333333223333333333333222333333333333' + '222233333333333222223333333333222222333333333222222233333333' + '222222223333333222222222333333222222222233333222222222223333' + '222222222222333222222222222233222222222222223222222222222222' + '011111111111111101111111111111110111111111111111011111111111' + '111101111111111111110111111111111111011111111111111101111111' + '111111110111111111111111011111111111111101111111111111110111' + '111111111111011111111111111101111111111111110100000000000000' + '010000000000000001000000000000000100000000000000010000000000' + '000001000000000000000100000000000000010000000000000001000000' + '000000000100000000000000010000000000000001000000000000000100' + '000000000000010000000000000001100000011111111110000011111111' + '111000011111111111100011111111111110011111111111111011111111' + '111111111111111000000010000000000000011000000000000011100000' + '000000011110000000000011111000000000011111100000000011111110' + '000000011111111100000000000000110000000000000111000000000000' + '111100000000000111110000000000111111000000000111111100000000' + '111111110000000111111111000000111111111100000111111111110000' + '111111111111000111111111111100111111111111110111111111111111' + '111111100000000011111100000000001111100000000000111100000000' + '000011100000000000001100000000000000100000000111111111111111' + '111111101111111111111100111111111111100011111111111100001111' + '111111100000111111111100000011111111100000001111111111111111' + '011111111111111001111111111111000111111111111000011111111111' + '000001111111111000000111111111000000011111111000000001111111' + '000000000111111000000000011111000000000001111000000000000111' + '000000000000011000000000000001000000011111111100000011111111' + '110000011111111111000011111111111100011111111111110011111111' + '111111011111111000000000000000000000010000000000000011000000' + '000000011100000000000011110000000000011111000000000011111100' + '000000011111110000000000000000100000000000000110000000000000' + '111000000000000111100000000000111110000000000111111000000000' + '111111100000000111111110000000111111111000000111111111100000' + '111111111110000111111111111000111111111111100111111111111110' + '011111100000000001111100000000000111100000000000011100000000' + '000001100000000000000100000000000000000000000111111101111111' + '111111100111111111111100011111111111100001111111111100000111' + '111111100000011111111100000001111111100000000011111111111111' + '001111111111111000111111111111000011111111111000001111111111' + '000000111111111000000011111111000000001111111000000000111111' + '000000000011111000000000001111000000000000111000000000000011' + '000000000000001000000000000000233333333333333323333333333333' + '332333333333333333233333333333333323333333333333332333333333' + '333333233333333333333323333333333333332333333333333333233333' + '333333333323333333333333332333333333333333233333333333333323' + '333333333333332322222222222222232222222222222223222222222222' + '222322222222222222232222222222222223222222222222222322222222' + '222222232222222222222223222222222222222322222222222222232222' + '222222222223222222222222222322222222222222232222222222222223' + '322222233333333332222233333333333222233333333333322233333333' + '333332233333333333333233333333333333333333333222222232222222' + '222222233222222222222233322222222222233332222222222233333222' + '222222233333322222222233333332222222233333333322222222222222' + '332222222222222333222222222222333322222222222333332222222222' + '333333222222222333333322222222333333332222222333333333222222' + '333333333322222333333333332222333333333333222333333333333322' + '333333333333332333333333333333333333322222222233333322222222' + '223333322222222222333322222222222233322222222222223322222222' + '222222322222222333333333333333333333323333333333333322333333' + '333333322233333333333322223333333333322222333333333322222233' + '333333322222223333333333333333233333333333333223333333333333' + '222333333333333222233333333333222223333333333222222333333333' + '222222233333333222222223333333222222222333333222222222233333' + '222222222223333222222222222333222222222222233222222222222223' + '222222233333333322222233333333332222233333333333222233333333' + '333322233333333333332233333333333333233333333222222222222222' + '222222232222222222222233222222222222233322222222222233332222' + '222222233333222222222233333322222222233333332222222222222222' + '322222222222222332222222222222333222222222222333322222222222' + '333332222222222333333222222222333333322222222333333332222222' + '333333333222222333333333322222333333333332222333333333333222' + '333333333333322333333333333332233333322222222223333322222222' + '222333322222222222233322222222222223322222222222222322222222' + '222222222222222333333323333333333333322333333333333322233333' + '333333322223333333333322222333333333322222233333333322222223' + '333333322222222233333333333333223333333333333222333333333333' + '222233333333333222223333333333222222333333333222222233333333' + '222222223333333222222222333333222222222233333222222222223333' + '222222222222333222222222222233222222222222223222222222222222'; assertEq(expectedSummaryString.length, 9000); // stay sane assertEq(actualSummaryString, expectedSummaryString);