Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIMD splat causes compiler error #1409

Closed
postspectacular opened this issue Jul 23, 2020 · 6 comments · Fixed by #1411
Closed

SIMD splat causes compiler error #1409

postspectacular opened this issue Jul 23, 2020 · 6 comments · Fixed by #1411
Labels

Comments

@postspectacular
Copy link

postspectacular commented Jul 23, 2020

I've just been trying to upgrade my assemblyscript dependency from 0.9.4 to 0.14.3 and am now getting a not very informative compiler error for code which worked completely fine in the older version. After various back and fro, removing code in my project and slowly going back with trying older assemblyscript versions, I managed to narrow it down and replicate the issue first appearing in assemblyscript 0.10.0 and using this small test function:

export function foo(out: usize): usize {
    const one = f32x4.splat(1);
    v128.store(out, one);
    return out;
}

Btw. In the actual code base this issue arises in this function..

asc assembly/index.ts -b simd.wasm -t simd.wat --optimize --enable simd --runtime none --importMemory --memoryBase 0

Error [AssertionError]: assertion failed
    at assert (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/std/portable/index.js:193:9)
    at m.compileVariableStatement (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:3093:17)
    at m.compileStatement (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:2145:21)
    at m.compileStatements (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:2193:23)
    at m.compileFunctionBody (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:1502:20)
    at m.compileFunction (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:1428:16)
    at m.compileElement (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:878:38)
    at m.compileExports (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:919:62)
    at m.compileExports (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:927:14)
    at m.compile (<...>/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:445:14)

<...>/node_modules/binaryen/index.js:57
function r(b){if(a.onAbort)a.onAbort(b);v(b);Aa=!0;throw new za("abort("+b+"). Build with -s ASSERTIONS=1 for more info.");}function Wa(b){var f=Xa;return String.prototype.startsWith?b.startsWith(f):0===b.indexOf(f)}var Xa="data:application/octet-stream;base64,",Ya="";if(!Wa(Ya)){var Za=Ya;Ya=a.locateFile?a.locateFile(Za,q):q+Za}var $a,ab;La.push({ga:function(){bb()}});var K={},cb=[];
                                                         ^
Error: abort(AssertionError: assertion failed). Build with -s ASSERTIONS=1 for more info.
    at process.r (<...>/node_modules/binaryen/index.js:57:58)
@MaxGraey
Copy link
Member

Could confirm. I guess it could be during module.runExpression. cc @dcodeIO

@dcodeIO dcodeIO added the bug label Jul 24, 2020
@dcodeIO
Copy link
Member

dcodeIO commented Jul 24, 2020

Problem appears to be that Binaryen can precompute the splat to a constant nowadays, but the code there really only expects an integer or a float to inline as a constant. A workaround would be to replace the const one with a let one.

Regarding a proper fix, an important question is if it even makes sense to inline v128s, i.e. instructions are almost always smaller than a constant and there might not even be a perf benefit between a v128.const and a v128.splat (really just guessing, not sure).

@MaxGraey
Copy link
Member

MaxGraey commented Jul 24, 2020

v128.splat<i32>(1) will be definitely smaller 51 bytes vs 65 bytes (I calc whole module) for (v128.const i32x4 1 1 1 1). So I guess better skip pre-computation for splat

@postspectacular
Copy link
Author

Thank you both @dcodeIO & @MaxGraey for the quick fix and workaround to use let instead of const. Using v0.14.4 I can now successfully compile again, however getting a runtime error during module init mentioning a different function and SIMD opcode under Node 14.5.0 (seemingly for f32x4.abs, opcode: fd e0 01). Will do some more digging first and then might open another issue... sorry!

@MaxGraey
Copy link
Member

MaxGraey commented Jul 25, 2020

Node 14.5.0 (seemingly for f32x4.abs, opcode: fd e0 01)

It seems Node 14.5.0 still using old opcodes before renumbering: WebAssembly/simd#209
So it's not relate to AS. I could only suggest to use nightly version of node. Also try node 14.6.0

@postspectacular
Copy link
Author

Thanks @MaxGraey! Very much the case what @zeux mentioned in that linked issue:

Here's the practical problems that I foresee with this:

  • Existing binary blobs will have to be recompiled to work, so this adds churn for all users of SIMD, as well as all implementors of SIMD
  • For a period of a month or more WASM SIMD will be very hard to use because of the mismatch in tools. This may be exacerbated by the lag time in delivery due to COVID on the Chrome side

postspectacular added a commit to thi-ng/umbrella that referenced this issue Jul 25, 2020
- update asmscript to 0.14.4
- implement workaround as mentioned here:
  AssemblyScript/assemblyscript#1409 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants