Skip to content

Many new wasm features are enabled if compile wasm32v1-none with -C linker-plugin-lto flag on LLVM 20+ #140174

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

Open
StackOverflowExcept1on opened this issue Apr 22, 2025 · 3 comments
Labels
C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. O-wasm Target: WASM (WebAssembly), http://webassembly.org/

Comments

@StackOverflowExcept1on
Copy link
Contributor

StackOverflowExcept1on commented Apr 22, 2025

Code

@alexcrichton

Code is minimized as much as possible and here is demo repository: https://github.com/StackOverflowExcept1on/wasm-builder-regression/

  • wasm-checker - simple CLI tool that passes wasm to parity-wasm parser (it does not support new wasm features like reference-types, bulk-memory)
  • wasm-program - this is smart contract that just allocates vector
  • wasm-project - some intermediate directory that is generated by our utility
  • check.sh source code
git clone https://github.com/StackOverflowExcept1on/wasm-builder-regression.git
cd wasm-builder-regression/wasm-project
cargo clean
./check.sh
   Compiling wasm-program v0.1.0 (/mnt/tmpfs/wasm-builder-regression/wasm-program)
   Compiling wasm-project v0.1.0 (/mnt/tmpfs/wasm-builder-regression/wasm-project)
    Finished `release` profile [optimized] target(s) in 0.27s
   Compiling gear-wasm v0.45.1
   Compiling wasm-checker v0.1.0 (/mnt/tmpfs/wasm-builder-regression/wasm-checker)
    Finished `release` profile [optimized] target(s) in 1.67s
     Running `/mnt/tmpfs/wasm-builder-regression/wasm-checker/target/release/wasm-checker ./target/wasm32v1-none/release/wasm_program.wasm`
Error: UnknownOpcode(252)

opcode 252 is memory.fill (bulk memory operations)

wasm-dis ./target/wasm32v1-none/release/wasm_program.wasm
(module $wasm_program.wasm
 ...
 ;; custom section "producers", size 75
 ;; features section: mutable-globals, nontrapping-float-to-int, bulk-memory, sign-ext, reference-types, multivalue
)

target was wasm32v1-none, however here we see bunch of wasm features that shouldn't be here.

I've also added LLVM IR output so we can report this bug to LLVM as soon as possible:

ls ./target/wasm32v1-none/release/deps/*.ll

If I remove flag -C linker-plugin-lto, it works as expected

I expected to see this happen: I can use -C linker-plugin-lto to optimize my .wasm programs and it results in generating the correct code for the wasm32v1-none target

Instead, this happened: there is some kind of conflict between compiler flags?

Version it worked on

Problems started after #135763. I don't have time to bisect exact version right now.

Version with regression

rustc +nightly-2025-04-22 --version --verbose:

rustc 1.88.0-nightly (d6c1e454a 2025-04-21)
binary: rustc
commit-hash: d6c1e454aa8af5e7e59fbf5c4e7d3128d2f99582
commit-date: 2025-04-21
host: x86_64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2
@StackOverflowExcept1on StackOverflowExcept1on added the C-bug Category: This is a bug. label Apr 22, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 22, 2025
@alexcrichton
Copy link
Member

Given that you suspect this is an LLD issue due to the usage of linker-plugin-lto, could you minimize this to an invocation of wasm-ld and report to upstream LLVM?

@StackOverflowExcept1on
Copy link
Contributor Author

@alexcrichton I'm having trouble reproducing this in LLVM:

llvm-as --version
wasm-tools --version
LLVM (http://llvm.org/):
  LLVM version 20.1.2
  Optimized build.
wasm-tools 1.229.0 (351f15374 2025-04-17)
llvm-as ./target/wasm32v1-none/release/deps/wasm_program.ll
wasm-ld ./target/wasm32v1-none/release/deps/wasm_program.bc -o ./target/wasm32v1-none/release/deps/wasm_program.wasm --no-entry --import-undefined --export init
wasm-tools validate -f=-bulk-memory ./target/wasm32v1-none/release/deps/wasm_program.wasm # ok
wasm-tools print ./target/wasm32v1-none/release/deps/wasm_program.wasm # prints wrong features
(module $wasm_program.wasm
  ...
  (@custom "target_features" (after code) "\08+\0bbulk-memory+\0fbulk-memory-opt+\16call-indirect-overlong+\0amultivalue+\0fmutable-globals+\13nontrapping-fptoint+\0freference-types+\08sign-ext")
)

@StackOverflowExcept1on
Copy link
Contributor Author

It looks like there is some __wasm_init_memory symbol in the strat section:

  (start $__wasm_init_memory)
  (func $__wasm_init_memory (;1;) (type 1)
    i32.const 1048576
    i32.const 0
    i32.const 1
    memory.fill
  )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. O-wasm Target: WASM (WebAssembly), http://webassembly.org/
Projects
None yet
Development

No branches or pull requests

4 participants