-
Notifications
You must be signed in to change notification settings - Fork 13k
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
wasm link failures - "The end of the file was unexpectedly encountered" #38558
Comments
Thanks for the report @kballard. I intend to make a sweep through all the emscripten issues soon and try to make some fresh progress. |
Same as the secondary issue in #37185 |
I'm seeing the same issue on an up-to-date ArchLinux, with Rust 1.14.0 and Emscripten 1.37.1 (following the same steps). The asm.js build works fine though. |
Also seeing what @wehlutyk reported on Ubuntu 16 on nightly. In this case, it only happens when I build for release, but the debug build fails regardless ( with error: "Uncaught no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: " ). |
on OSX 10.11.5, rustc 1.17.0-nightly (956e2bc 2017-02-12), emcc 1.36.11 (commit c5af8f63f00bb03aa2177c71d16628474918b60f), I get a similar but slightly different error if I compile with target wasm and with the It works perfectly if I leave out the |
This is a "duplicate" of this issue: WebAssembly/binaryen#855 Pretty sure this is due to the vector instructions that rustc emits. This should happen a lot more with the recent changes @RReverser introduced, since |
@CryZe |
@RReverser That's pretty weird then. Cause Rust passing -O3 to emcc is what breaks it. But the thing is that half of all trivial projects and no larger Rust project can be compiled to wasm because of this bug. If this is not caused by Rust, then it would be really weird how no one on emscripten's side noticed that. They are even starting to prepare to release 1.0 now, so I doubt that they fail to build trivial projects and all larger ones. I guess I'll look into the generated IR later today. |
@CryZe Given the original report in this thread, it appears that it was throwing even without -O3? |
@RReverser the original issue might be unrelated then. Anyways, -O3 is definitely what makes it not compile due to vector instruction in about half of the ~30 projects I tried to compile to wasm (with the rest working). |
Ok I can reproduce this, but only with wasm target and only with -O3 as @CryZe said. Original report could reproduce without -O3, but I noticed it used older Emscripten issue. Now, I tried small file with few functions, one of which works with array in vectorizable manner ( |
I think the next step would be figuring out if those vector instructions get emitted on emscripten's side or rustc. |
Yep. Function: #[no_mangle]
pub extern fn f3(x: &mut [i32]) {
for item in x {
*item |= 10;
}
} LL: ; Function Attrs: nounwind uwtable
define void @f3(i32* nonnull, i32) unnamed_addr #0 {
entry-block:
%2 = getelementptr inbounds i32, i32* %0, i32 %1
%3 = icmp eq i32 %1, 0
br i1 %3, label %bb4, label %bb5.preheader
bb5.preheader: ; preds = %entry-block
%4 = shl i32 %1, 2
%5 = add i32 %4, -4
%6 = lshr exact i32 %5, 2
%7 = add nuw nsw i32 %6, 1
%min.iters.check = icmp ult i32 %7, 4
br i1 %min.iters.check, label %bb5.preheader19, label %min.iters.checked
bb5.preheader19: ; preds = %middle.block, %min.iters.checked, %bb5.preheader
%iter.sroa.0.0.in12.ph = phi i32* [ %0, %min.iters.checked ], [ %0, %bb5.preheader ], [ %ind.end, %middle.block ]
br label %bb5
min.iters.checked: ; preds = %bb5.preheader
%n.vec = and i32 %7, 2147483644
%cmp.zero = icmp eq i32 %n.vec, 0
%ind.end = getelementptr i32, i32* %0, i32 %n.vec
br i1 %cmp.zero, label %bb5.preheader19, label %vector.body.preheader
vector.body.preheader: ; preds = %min.iters.checked
br label %vector.body
vector.body: ; preds = %vector.body.preheader, %vector.body
%index = phi i32 [ %index.next, %vector.body ], [ 0, %vector.body.preheader ]
%next.gep = getelementptr i32, i32* %0, i32 %index
%8 = bitcast i32* %next.gep to <4 x i32>*
%wide.load = load <4 x i32>, <4 x i32>* %8, align 4
%9 = or <4 x i32> %wide.load, <i32 10, i32 10, i32 10, i32 10>
%10 = bitcast i32* %next.gep to <4 x i32>*
store <4 x i32> %9, <4 x i32>* %10, align 4
%index.next = add i32 %index, 4
%11 = icmp eq i32 %index.next, %n.vec
br i1 %11, label %middle.block, label %vector.body, !llvm.loop !1
middle.block: ; preds = %vector.body
%cmp.n = icmp eq i32 %7, %n.vec
br i1 %cmp.n, label %bb4, label %bb5.preheader19
bb4.loopexit: ; preds = %bb5
br label %bb4
bb4: ; preds = %bb4.loopexit, %middle.block, %entry-block
ret void
bb5: ; preds = %bb5.preheader19, %bb5
%iter.sroa.0.0.in12 = phi i32* [ %12, %bb5 ], [ %iter.sroa.0.0.in12.ph, %bb5.preheader19 ]
%12 = getelementptr inbounds i32, i32* %iter.sroa.0.0.in12, i32 1
%13 = load i32, i32* %iter.sroa.0.0.in12, align 4
%14 = or i32 %13, 10
store i32 %14, i32* %iter.sroa.0.0.in12, align 4
%15 = icmp eq i32* %12, %2
br i1 %15, label %bb4.loopexit, label %bb5, !llvm.loop !4
} |
Oh btw, whenever this gets fixed, we may want to turn vectorization off for asm.js as well, as it's a non-standard extension that turns it into "almost asm", which probably isn't even interpreted as asm.js by any Browser other than Firefox. So vectorization is mostly hurtful for most browsers anyway. |
@CryZe Well there are ways to compile it efficiently even w/o SIMD at least for cases like above, but otherwise agree. |
Pretty weird how setting loop-vectorize to false has no effect then. Update: Uhhhh, they do work?! At least in the code you provided. I don't know how larger code is still vectorized then. |
Oh, I think I may know what the problem is. The standard library. It's built with vectorization! |
@CryZe Ah yes, makes sense. Want to submit a PR that disables vectorization for emscripten targets? |
@CryZe Although I still don't fully understand where this happens. Is standard library built with vectorization and -O3 already or is it link-time issue? |
@CryZe And doesn't explain why issue isn't present when compiling code without such a function that uses vectorization on its own. If issue would be in precompiled standard library, it should be present even on files with just |
Okay, so this is interesting. I just have a BinaryHeap and I'm pushing a struct of 4 usize fields into it. And that gets turned into a vector instruction. However, since this is a generic, this can't be prebuilt in any way and yet there's still vector instructions. |
Alright, this still breaks it, even with the two no-vectorize flags: https://gist.github.com/CryZe/eed7f1f47c638f14f92daebe1a1ca17e Update: Looks like this is yet another bug. This affects asm.js too?! |
Okay, so apparently |
Oh yeah, I never use cargo for such precise testing, best is to use rustc directly. |
When targeting Emscripten, rustc emits Vector Instructions by default. However Web Assembly doesn't support Vector Instructions yet, which causes Binaryen to fail converting the intermediate asm.js code to Web Assembly. While asm.js kind of supports Vector Instructions, they aren't supported by any browser other than Firefox, often meaning that they need to be emulated very slowly. So it should just be turned off for all Emscripten targets. Fixes rust-lang#38558
Turn off Vectorization for Emscripten When targeting Emscripten, rustc emits Vector Instructions by default. However Web Assembly doesn't support Vector Instructions yet, which causes Binaryen to fail converting the intermediate asm.js code to Web Assembly. While asm.js kind of supports Vector Instructions, they aren't supported by any browser other than Firefox, often meaning that they need to be emulated very slowly. So it should just be turned off for all Emscripten targets. Fixes #38558
With the release of Rust 1.14.0, I wanted to try out the emscripten support. I've never used emscripten before, so here's the steps I took:
At this point,
emcc
spewed a bunch of link errors:This is on macOS 10.12.2, Rust 1.14.0, and emscripten 1.36.14.
The text was updated successfully, but these errors were encountered: