rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.47k stars 12.73k forks source link

Can not disable `reference-types` feature for wasm32 target with `-C linker-plugin-lto` flag #130604

Open StackOverflowExcept1on opened 1 month ago

StackOverflowExcept1on commented 1 month ago

Code

@alexcrichton

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

git clone https://github.com/StackOverflowExcept1on/wasm-builder-regression.git
cd wasm-builder-regression/wasm-project
./check.sh
    Finished `release` profile [optimized] target(s) in 8.30s

   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.68s
     Running `/mnt/tmpfs/wasm-builder-regression/wasm-checker/target/release/wasm-checker ./target/wasm32-unknown-unknown/release/wasm_program.wasm`

Error: InvalidTableReference(128)

If I remove flag -C linker-plugin-lto, it works as described in #128511

I expected to see this happen: I can disable reference-types via -Ctarget-cpu=mvp and -Zbuild-std

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

Version it worked on

It most recently worked on: nightly-2024-07-31

Version with regression

rustc +nightly-2024-08-01 --version --verbose:

rustc 1.82.0-nightly (28a58f2fa 2024-07-31)
binary: rustc
commit-hash: 28a58f2fa7f0c46b8fab8237c02471a915924fe5
commit-date: 2024-07-31
host: x86_64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0
alexcrichton commented 1 month ago

Thanks for the report! I'm not actually sure what's going on here. My best guess though is that wasm-ld is performing codegen on behalf of -Clinker-plugin-lto and it's not configured the same way as rustc. For example -Ctarget-cpu is a Rust compiler flag which it translates to LLVM, but this isn't passed to wasm-ld. (AFAIK there's no way to pass this flag to wasm-ld).

The LLVM IR going into wasm-ld looks like it's correctly annotated with "target-cpu"="mvp" on functions which also perplexes me...

Put another way, you're doing everything right here, and the bug lies somewhere in the interaction of codegen in wasm-ld and configuring LLVM with features disabled. It might be a bug in wasm-ld itself or it might be a bug in rustc. A reduction of this issue is:

target triple = "wasm32-unknown-unknown"
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"

define void @foo(ptr %a) #0 {
  call void %a()
  ret void
}

attributes #0 = { nounwind "target-cpu"="mvp" }

Locally I see:

$ llvm-as wat.ll
$ wasm-ld wat.bc -o foo.wasm --no-entry --export foo 
$ wasm-tools validate -f=-reference-types foo.wasm
error: func 0 failed to validate

Caused by:
    0: zero byte expected (at offset 0x4b)

I've opened https://github.com/llvm/llvm-project/issues/109443 to see if folks have thoughts there.

apiraino commented 1 month ago

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium