Skip to content

SIMD splat causes compiler error #1409

Closed

Description

@postspectacular

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)

Activity

  1. MaxGraey commented on Jul 24, 2020

    @MaxGraey
    Member

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

  2. dcodeIO commented on Jul 24, 2020

    @dcodeIO
    Member

    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).

  3. MaxGraey commented on Jul 24, 2020

    @MaxGraey
    Member

    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

  4. postspectacular commented on Jul 25, 2020

    @postspectacular
    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!

  5. MaxGraey commented on Jul 25, 2020

    @MaxGraey
    Member

    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

  6. postspectacular commented on Jul 25, 2020

    @postspectacular
    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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions