tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cmp-bitselect.js (5022B)


      1 // |jit-test| skip-if: !wasmSimdEnabled()
      2 // Tests if combination of comparsion and bitselect produces correct result.
      3 // On x86/64 platforms, it is expected to replace slow bitselect emulation,
      4 // with its faster laneselect equivalent (pblendvb).
      5 // See bug 1751488 for more information.
      6 
      7 let verifyCodegen = _method => {};
      8 if (hasDisassembler() && wasmCompileMode() == "ion" &&
      9    getBuildConfiguration("x64") && !getBuildConfiguration("simulator")) {
     10  if (isAvxPresent()) {
     11    verifyCodegen = method => {
     12        assertEq(wasmDis(method, {asString: true}).includes('vpblendvb'), true);
     13    };
     14  } else {
     15    verifyCodegen = method => {
     16        assertEq(wasmDis(method, {asString: true}).includes("pblendvb"), true);
     17    };
     18  }
     19 }
     20 
     21 const checkOps = {
     22  eq(a, b) { return a == b; },
     23  ne(a, b) { return a != b; },
     24  lt(a, b) { return a < b; },
     25  le(a, b) { return a <= b; },
     26  gt(a, b) { return a > b; },
     27  ge(a, b) { return a >= b; },
     28 };
     29 const checkPattern = new Uint8Array(Array(32).fill(null).map((_, i) => i));
     30 
     31 for (let [laneSize, aty_s, aty_u] of [
     32    [8, Int8Array, Uint8Array], [16, Int16Array, Uint16Array],
     33    [32, Int32Array, Uint32Array], [64, BigInt64Array, BigUint64Array]]) {
     34    const laneCount = 128 / laneSize; 
     35    const ty = `i${laneSize}x${laneCount}`;
     36    for (let op of ['eq', 'ne', 'lt_s', 'le_s', 'gt_s', 'ge_s', 'lt_u', 'le_u', 'gt_u', 'ge_u']) {
     37        if (laneSize == 64 && op.includes('_u')) continue;
     38        const wrap = laneSize < 64 ? x => x : x => BigInt(x);
     39        const aty = op.includes('_u') ? aty_u : aty_s;
     40        const check = checkOps[op.replace(/_[us]$/, "")];
     41        // Items to test: 0, 1, all 1s, top half 1s, low half 1s, top bit 1
     42        const testData = new aty([wrap(0), wrap(1), ~wrap(0), ~wrap(0) << wrap(laneSize / 2),
     43                                  ~((~wrap(0)) << wrap(laneSize / 2)), wrap(1) << wrap(laneSize - 1)]);
     44        const ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
     45            (memory (export "memory") 1)
     46            (func (export "run")
     47              (v128.store (i32.const 32)
     48                (v128.bitselect (v128.load (i32.const 64)) (v128.load (i32.const 80)) (${ty}.${op} (v128.load (i32.const 0)) (v128.load (i32.const 16))))) ))`)));
     49        const mem = new aty(ins.exports.memory.buffer);
     50        const memI8 = new Uint8Array(ins.exports.memory.buffer);
     51        memI8.subarray(64, 96).set(checkPattern);
     52        verifyCodegen(ins.exports.run);
     53        for (let i = 0; i < testData.length; i++) {
     54            for (let j = 0; j < testData.length; j++) {
     55                for (let q = 0; q < laneCount; q++) {
     56                    mem[q] = testData[(i + q) % testData.length];
     57                    mem[q + laneCount] = testData[(j + q) % testData.length];
     58                }
     59                ins.exports.run();
     60                for (let q = 0; q < laneCount; q++) {
     61                    const val = check(mem[q], mem[q + laneCount]);
     62                    const n = laneSize >> 3;
     63                    for (let k = 0; k < n; k++) {
     64                        assertEq(checkPattern[q * n + k + (val ? 0 : 16)],
     65                                 memI8[32 + q * n + k]);
     66                    }
     67                }
     68            }
     69        }
     70    }
     71 }
     72 
     73 for (let [laneSize, aty] of [[32, Float32Array], [64, Float64Array]]) {
     74    const laneCount = 128 / laneSize; 
     75    const ty = `f${laneSize}x${laneCount}`;
     76    for (let op of ['eq', 'ne', 'lt', 'le', 'gt', 'ge']) {
     77        const check = checkOps[op];
     78        // Items to test: 0, 1, -1, PI, NaN, Inf, -0, -Inf
     79        const testData = new aty([0, 1, -1, Math.PI, NaN, Infinity, 0/-Infinity, -Infinity]);
     80        const ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
     81            (memory (export "memory") 1)
     82            (func (export "run")
     83              (v128.store (i32.const 32)
     84                (v128.bitselect (v128.load (i32.const 64)) (v128.load (i32.const 80)) (${ty}.${op} (v128.load (i32.const 0)) (v128.load (i32.const 16))))) ))`)));
     85        const mem = new aty(ins.exports.memory.buffer);
     86        const memI8 = new Uint8Array(ins.exports.memory.buffer);
     87        memI8.subarray(64, 96).set(checkPattern);
     88        verifyCodegen(ins.exports.run);        
     89        for (let i = 0; i < testData.length; i++) {
     90            for (let j = 0; j < testData.length; j++) {
     91                for (let q = 0; q < laneCount; q++) {
     92                    mem[q] = testData[(i + q) % testData.length];
     93                    mem[q + laneCount] = testData[(j + q) % testData.length];
     94                }
     95                ins.exports.run();
     96                for (let q = 0; q < laneCount; q++) {
     97                    const val = check(mem[q], mem[q + laneCount]);
     98                    const n = laneSize >> 3;
     99                    for (let k = 0; k < n; k++) {
    100                        assertEq(checkPattern[q * n + k + (val ? 0 : 16)],
    101                                 memI8[32 + q * n + k]);
    102                    }
    103                }
    104            }
    105        }
    106    }
    107 }