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 code does not validate as asm.js. #2855

Closed
juj opened this issue Oct 2, 2014 · 12 comments
Closed

SIMD code does not validate as asm.js. #2855

juj opened this issue Oct 2, 2014 · 12 comments
Labels

Comments

@juj
Copy link
Collaborator

juj commented Oct 2, 2014

Marking this down from earlier discussions. If one compiles SIMD-utilizing code with Emscripten, the linker will complain

WARNING  root: disabling asm.js validation due to use of non-supported features: SIMD types in use

as a workaround, one must go to the compiled output, and search-replace the string "almost asm" to "use asm" to have the output enable asm.js in the browser. However, doing so and trying to run in current Firefox Nightly (FF 35.0a1 2014-10-02) gives the following asm.js validation error

TypeError: asm.js type error: 'notEqual' is not an operation supported by the SIMD type

when compiling e.g. https://github.com/juj/emscripten/blob/sse1/tests/benchmark_sse1.cpp

@juj juj added the SIMD label Oct 2, 2014
@sunfishcode
Copy link
Collaborator

Emscripten is anticipating the spec change to add int32x4 notEqual:

tc39/ecmascript_simd#46

Odin does not yet implement this, though there's a preliminary patch on this bug:

https://bugzilla.mozilla.org/show_bug.cgi?id=1072368

@juj
Copy link
Collaborator Author

juj commented Oct 2, 2014

Thanks - so Emscripten is more up to date than current FF Nightly and once 1072368 lands, FF Nightly should start validating what Emscripten is currently spewing out?

@juj
Copy link
Collaborator Author

juj commented Oct 2, 2014

Hmm nm actually, I see that there are other todos as well. If I try to work around this manually by avoiding the use of functions that are not yet implemented, that I need to remove the following lines from the compiled code:

var SIMD_int32x4_notEqual=SIMD_int32x4.notEqual;
var SIMD_int32x4_lessThanOrEqual=SIMD_int32x4.lessThanOrEqual;
var SIMD_int32x4_greaterThanOrEqual=SIMD_int32x4.greaterThanOrEqual;
var SIMD_int32x4_not=SIMD_int32x4.not;
var SIMD_int32x4_shuffle=SIMD_int32x4.shuffle;
var SIMD_int32x4_shuffleMix=SIMD_int32x4.shuffleMix;
var SIMD_int32x4_load=SIMD_int32x4.load;
var SIMD_int32x4_loadX=SIMD_int32x4.loadX;
var SIMD_int32x4_loadXY=SIMD_int32x4.loadXY;
var SIMD_int32x4_loadXYZ=SIMD_int32x4.loadXYZ;
var SIMD_int32x4_store=SIMD_int32x4.store;
var SIMD_int32x4_storeX=SIMD_int32x4.storeX;
var SIMD_int32x4_storeXY=SIMD_int32x4.storeXY;
var SIMD_int32x4_storeXYZ=SIMD_int32x4.storeXYZ;
var SIMD_float32x4_not=SIMD_float32x4.not;
var SIMD_float32x4_shuffle=SIMD_float32x4.shuffle;
var SIMD_float32x4_shuffleMix=SIMD_float32x4.shuffleMix;
var SIMD_float32x4_load=SIMD_float32x4.load;
var SIMD_float32x4_loadX=SIMD_float32x4.loadX;
var SIMD_float32x4_loadXY=SIMD_float32x4.loadXY;
var SIMD_float32x4_loadXYZ=SIMD_float32x4.loadXYZ;
var SIMD_float32x4_store=SIMD_float32x4.store;
var SIMD_float32x4_storeX=SIMD_float32x4.storeX;
var SIMD_float32x4_storeXY=SIMD_float32x4.storeXY;
var SIMD_float32x4_storeXYZ=SIMD_float32x4.storeXYZ;
var SIMD_float32x4_sqrt=SIMD_float32x4.sqrt;
var SIMD_float32x4_fromInt32x44Bits=SIMD_float32x4.fromInt32x44Bits;

and after that, I get a failure TypeError: asm.js type error: double is not a subtype of floatish on a line $50 = SIMD_float32x4_splat($49);. This is when trying to compile https://github.com/juj/emscripten/blob/sse1/tests/benchmark_sse1.cpp

@juj
Copy link
Collaborator Author

juj commented Oct 2, 2014

Btw, is fromInt32x44Bits a typo?

@sunfishcode
Copy link
Collaborator

Yes, fromInt32x44Bits was a typo. Fixed now.

@juj
Copy link
Collaborator Author

juj commented Oct 24, 2014

I've updated the pull request branch for the SSE1 tests and benchmarks to latest at #2792 . Testing with Emscripten and Nightly today, there are still validation errors. I ran a new benchmark at http://clb.demon.fi/dump/results_sse1_20141024.html

If you want to reproduce locally, you can run

cd $EMSCRIPTEN
git remote add juj https://github.com/juj/emscripten.git
git fetch juj sse1
git checkout juj/sse1

to set up, and

cd $EMSCRIPTEN
python tests/runner.py ALL.test_sse1

to run the correctness test, and

cd $EMSCRIPTEN
python tests/benchmark_sse1.py

to run the benchmark suite. When the benchmark suite finishes, it generates a file results_sse1.html that contains the graphed results like shown in the above link.

@huningxin
Copy link
Contributor

Just rebased the #2792 to latest incoming 0681d355102c329cb594675f62648199ed8965cc. There are 14 failure test cases:

_mm_rcp_ps(a) failed! [0.125, 0.166667, 0.25, 0.5] != [0.124969, 0.166626, 0.249939, 0.499878]
_mm_rcp_ss(a) failed! [8, 6, 4, 0.5] != [8, 6, 4, 0.499878]
_mm_rsqrt_ps(a) failed! [0.353553, 0.408248, 0.5, 0.707107] != [0.353455, 0.408203, 0.499878, 0.706909]
_mm_rsqrt_ss(a) failed! [8, 6, 4, 0.707107] != [8, 6, 4, 0.706909]
_mm_and_ps(i1, i2) failed! [0x83200100, 0x0fc00000, 0x80244021, 0x13400000] != [0x83200100, 0x0fecc988, 0x80244021, 0x13458a88]
_mm_andnot_ps(i1, i2) failed! [0x388a9888, 0x70000000, 0x7000289c, 0x00179ace] != [0x388a9888, 0xf0021444, 0x7000289c, 0x00121046]
_mm_or_ps(i1, i2) failed! [0xbfefdba9, 0x7fedcba9, 0xf7656bbd, 0x7fd79ace] != [0xbfefdba9, 0xffefdfed, 0xf7656bbd, 0xffffdbef]
_mm_xor_ps(i1, i2) failed! [0x3ccfdaa9, 0x702dcba9, 0x77412b9c, 0x6c979ace] != [0x3ccfdaa9, 0xf0031665, 0x77412b9c, 0xecba5167]
Condition '_mm_ucomieq_ss(a, nan1) == 1' failed!
Condition '_mm_ucomile_ss(a, nan1) == 1' failed!
Condition '_mm_ucomilt_ss(a, nan1) == 1' failed!
Condition '_mm_ucomineq_ss(a, nan1) == 0' failed!
Condition '_mm_cvtss_si32(e) == 4' failed!
Condition '_mm_cvt_ss2si(e) == 4' failed!

@juj and @sunfishcode , how about merge juj/sse1 branch? Then fix the failure cases.

@juj
Copy link
Collaborator Author

juj commented Oct 29, 2014

I've updated the pull request with the rebase and updated the test_sse test with this commit juj@036ca52 so that it is good to merge. We don't want the test to potentially fail for a long time in the test suite until the spec matures and fixes are found, so I #ifdeffed out the failing cases for now and annotated the failures in that commit.

@huningxin
Copy link
Contributor

@juj , thanks much for your efforts. Your change looks good to me. @sunfishcode , any thoughts?

@huningxin
Copy link
Contributor

ping @sunfishcode

@sunfishcode
Copy link
Collaborator

On the failures: It's not surprising that rcp and rsqrt are failing, as the polyfill probably isn't approximating the approximation closely enough ;-). For and, andnot, etc., is this a NaN canonicalization issue, due to the polyfill being unable to do a bitcast from int32 to float32 without NaN canonicalizing? For _mm_ucomieq_ss, this instruction does not handle NaN the same way '==' does, so we'll need to do something else there. We're unlikely to be able to support _mm_cvtss_si32 or _mm_cvt_ss2si because we're unlikely to support dynamic rounding modes (for the forseeable future). I'll take a look at the pull request soon too see what makes sense there.

@juj
Copy link
Collaborator Author

juj commented Sep 3, 2015

Works in current incoming.

@juj juj closed this as completed Sep 3, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants