pmaddubsw-x64-ion-codegen.js (4412B)
1 // |jit-test| --setpref=wasm_unroll_loops=false; skip-if: !wasmSimdEnabled() || wasmCompileMode() != "ion" 2 3 // Testing _mm_maddubs_epi16 / vpmaddubsw behavoir for all platforms. 4 // 5 // Bug 1762413 adds specialization for emscripten's pattern to directly 6 // emit PMADDUBSW machine code. 7 8 const isX64 = getBuildConfiguration("x64") && !getBuildConfiguration("simulator"); 9 10 // Simple test. 11 const simple = wasmTextToBinary(`(module 12 (memory (export "memory") 1 1) 13 (func $_mm_maddubs_epi16 (export "t") (param v128 v128) (result v128) 14 local.get 1 15 i32.const 8 16 i16x8.shl 17 i32.const 8 18 i16x8.shr_s 19 local.get 0 20 v128.const i32x4 0x00ff00ff 0x00ff00ff 0x00ff00ff 0x00ff00ff 21 v128.and 22 i16x8.mul 23 local.get 1 24 i32.const 8 25 i16x8.shr_s 26 local.get 0 27 i32.const 8 28 i16x8.shr_u 29 i16x8.mul 30 i16x8.add_sat_s) 31 (func (export "run") 32 i32.const 0 33 v128.const i8x16 0 2 1 2 1 2 -1 1 255 255 255 255 0 0 255 255 34 v128.const i8x16 1 0 3 4 -3 -4 -128 127 127 127 -128 -128 0 0 -128 127 35 call $_mm_maddubs_epi16 36 v128.store 37 ) 38 )`); 39 var ins = new WebAssembly.Instance(new WebAssembly.Module(simple)); 40 ins.exports.run(); 41 var mem16 = new Int16Array(ins.exports.memory.buffer, 0, 8); 42 assertSame(mem16, [0, 11, -11, -32513, 32767, -32768, 0, -255]); 43 44 if (hasDisassembler() && isX64) { 45 assertEq(wasmDis(ins.exports.t, {tier:"ion", asString:true}).includes('pmaddubsw'), true); 46 } 47 48 if (hasDisassembler() && isX64) { 49 // Two pmaddubsw has common operand, and code was optimized. 50 const realWorldOutput = wasmTextToBinary(`(module 51 (memory 1 1) 52 (func (export "test") 53 (local i32 i32 i32 i32 v128 v128 v128 v128 v128 v128) 54 local.get 0 55 local.get 1 56 i32.add 57 local.set 2 58 local.get 0 59 i32.const 16 60 i32.add 61 local.set 0 62 local.get 3 63 local.set 1 64 loop 65 local.get 5 66 local.get 0 67 v128.load 68 local.tee 5 69 i32.const 7 70 i8x16.shr_s 71 local.tee 8 72 local.get 1 73 v128.load offset=240 74 local.get 5 75 v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000 76 i8x16.eq 77 local.tee 7 78 v128.andnot 79 i8x16.add 80 local.get 8 81 v128.xor 82 local.tee 4 83 i32.const 8 84 i16x8.shl 85 i32.const 8 86 i16x8.shr_s 87 local.get 5 88 i8x16.abs 89 local.tee 5 90 v128.const i32x4 0x00ff00ff 0x00ff00ff 0x00ff00ff 0x00ff00ff 91 v128.and 92 local.tee 9 93 i16x8.mul 94 local.get 4 95 i32.const 8 96 i16x8.shr_s 97 local.get 5 98 i32.const 8 99 i16x8.shr_u 100 local.tee 4 101 i16x8.mul 102 i16x8.add_sat_s 103 i16x8.add_sat_s 104 local.set 5 105 106 local.get 6 107 local.get 8 108 local.get 1 109 v128.load offset=224 110 local.get 7 111 v128.andnot 112 i8x16.add 113 local.get 8 114 v128.xor 115 local.tee 6 116 i32.const 8 117 i16x8.shl 118 i32.const 8 119 i16x8.shr_s 120 local.get 9 121 i16x8.mul 122 local.get 6 123 i32.const 8 124 i16x8.shr_s 125 local.get 4 126 i16x8.mul 127 i16x8.add_sat_s 128 i16x8.add_sat_s 129 local.set 6 130 131 local.get 1 132 i32.const 128 133 i32.add 134 local.set 1 135 local.get 0 136 i32.const 16 137 i32.add 138 local.tee 0 139 local.get 2 140 i32.ne 141 br_if 0 142 end 143 ))`); 144 145 var ins = new WebAssembly.Instance(new WebAssembly.Module(realWorldOutput)); 146 const output = wasmDis(ins.exports.test, {tier:"ion", asString:true}).replace(/^[0-9a-f]{8} (?:[0-9a-f]{2} )+\n?\s+/gmi, ""); 147 // Find two pmaddubsw+paddsw. 148 const re = /\bv?pmaddubsw[^\n]+\nv?paddsw /g; 149 assertEq(re.exec(output) != null, true); 150 assertEq(re.exec(output) != null, true); 151 assertEq(re.exec(output) == null, true); 152 // No leftover PMULL, PSLLW, or PSRAW. 153 assertEq(/pmullw|psllw|psraw/.test(output), false); 154 }