darioush opened issue #13270:
Hello! I found that a certain form of wasm with many chained
i32.trunc_f64_s/f64.convert_i32_sops can trigger a panic during compilation on aarc64, but compiles fine on x86_64.I can confirm the issue reproduces, and it is somewhat sad that I could not find a smaller reproduction. The specifics of the code involved here seems quite detailed and beyond my expertise. As such, I will include the LLM's analysis in case it is helpful:
.clifTest CaseOne
fcvt_to_sint.i32 f64(which emits aLdr19constant-pool fixup on aarch64) followed by ~29,200 chainedsdivops (which pile up deferred traps until the constant pool is forced past the 1 MBLdr19range):function u0:0(f64, i32) -> i32 fast { block0(v0: f64, v1: i32): v2 = fcvt_to_sint.i32 v0 ;; emits Ldr19 fixup at prologue offset ~20 v3 = sdiv v2, v1 ;; } v4 = sdiv v3, v1 ;; } ~29,200 sdivs pile up deferred traps ;; ... 29,196 more sdivs ... ;; } v29202 = sdiv v29201, v1 return v29202 }Generator (
gen_clif.py N, default N=29200 panics reliably; threshold ~29,130):import sys N = int(sys.argv[1]) if len(sys.argv) > 1 else 29200 print('function u0:0(f64, i32) -> i32 fast {') print('block0(v0: f64, v1: i32):') print(' v2 = fcvt_to_sint.i32 v0') prev = 'v2' ssa = 3 for k in range(N): iv = ssa; ssa += 1 print(f' v{iv} = sdiv {prev}, v1') prev = f'v{iv}' print(f' return {prev}') print('}')Steps to Reproduce
- Generate the wasm with gen.py:
python3 gen.py 16000 > repro.wat wasm-tools parse repro.wat -o repro.wasm wasmtime compile repro.wasm
or the clif with
gen_clif.py N.Compile it against the aarch64 cranelift backend using
clif-util compileor the minimal harness below:
```rust
// Cargo.toml: cranelift-codegen = { version = "0.131", features = ["all-arch"] }
// cranelift-reader = "0.131"
use cranelift_codegen::{isa, settings, Context};
use cranelift_codegen::settings::Configurable;
use cranelift_reader::parse_functions;fn main() {
let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
let mut flag_builder = settings::builder();
flag_builder.set("opt_level", "speed").unwrap();
let isa = isa::lookup_by_name("aarch64-unknown-unknown").unwrap()
.finish(settings::Flags::new(flag_builder)).unwrap();
for f in parse_functions(&src).unwrap() {
Context::for_function(f).compile(&*isa, &mut Default::default()).unwrap();
}
}
```
sh cargo run --release -- repro.clifExpected Results
Compiles successfully. (Verified: x86_64 with
wasmtime compile repro.wasmexits 0 in 0.135s on a c2-standard-16 GCE instance with wasmtime 44.0.1.)Actual Results
Release-mode panic on aarch64:
thread 'main' panicked at cranelift-codegen-0.131.1/src/machinst/buffer.rs:1496:17: assertion failed: (label_offset - offset) <= kind.max_pos_range()cranelift_codegen::machinst::buffer::MachBuffer<I>::handle_fixup cranelift_codegen::machinst::buffer::MachBuffer<I>::emit_island_maybe_forced cranelift_codegen::machinst::vcode::VCode<I>::emit <cranelift_codegen::isa::aarch64::AArch64Backend as TargetIsa>::compile_functionVersions and Environment
Cranelift version: 0.131.0 and 0.131.1
wasmtime cranelift panic line 36.0.7 0.123.7 buffer.rs:139544.0.0 0.131.0 buffer.rs:149644.0.1 0.131.1 buffer.rs:1496Operating system: macOS (Apple Silicon M-series).
Architecture: aarch64 panics; x86_64 unaffected.
Note on specificity. Only
fcvt_to_sint.i32 f64triggers;fcvt_to_uint,fcvt_to_sint.i64, andsdivalone do not (the first two emit noLdr19on this backend, the last has no constant-pool load).
darioush added the bug label to Issue #13270.
darioush added the cranelift label to Issue #13270.
cfallin closed issue #13270:
Hello! I found that a certain form of wasm with many chained
i32.trunc_f64_s/f64.convert_i32_sops can trigger a panic during compilation on aarc64, but compiles fine on x86_64.I can confirm the issue reproduces, and it is somewhat sad that I could not find a smaller reproduction. The specifics of the code involved here seems quite detailed and beyond my expertise. As such, I will include the LLM's analysis in case it is helpful:
.clifTest CaseOne
fcvt_to_sint.i32 f64(which emits aLdr19constant-pool fixup on aarch64) followed by ~29,200 chainedsdivops (which pile up deferred traps until the constant pool is forced past the 1 MBLdr19range):function u0:0(f64, i32) -> i32 fast { block0(v0: f64, v1: i32): v2 = fcvt_to_sint.i32 v0 ;; emits Ldr19 fixup at prologue offset ~20 v3 = sdiv v2, v1 ;; } v4 = sdiv v3, v1 ;; } ~29,200 sdivs pile up deferred traps ;; ... 29,196 more sdivs ... ;; } v29202 = sdiv v29201, v1 return v29202 }Generator (
gen_clif.py N, default N=29200 panics reliably; threshold ~29,130):import sys N = int(sys.argv[1]) if len(sys.argv) > 1 else 29200 print('function u0:0(f64, i32) -> i32 fast {') print('block0(v0: f64, v1: i32):') print(' v2 = fcvt_to_sint.i32 v0') prev = 'v2' ssa = 3 for k in range(N): iv = ssa; ssa += 1 print(f' v{iv} = sdiv {prev}, v1') prev = f'v{iv}' print(f' return {prev}') print('}')Steps to Reproduce
- Generate the wasm with gen.py:
python3 gen.py 16000 > repro.wat wasm-tools parse repro.wat -o repro.wasm wasmtime compile repro.wasm
or the clif with
gen_clif.py N.Compile it against the aarch64 cranelift backend using
clif-util compileor the minimal harness below:
```rust
// Cargo.toml: cranelift-codegen = { version = "0.131", features = ["all-arch"] }
// cranelift-reader = "0.131"
use cranelift_codegen::{isa, settings, Context};
use cranelift_codegen::settings::Configurable;
use cranelift_reader::parse_functions;fn main() {
let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
let mut flag_builder = settings::builder();
flag_builder.set("opt_level", "speed").unwrap();
let isa = isa::lookup_by_name("aarch64-unknown-unknown").unwrap()
.finish(settings::Flags::new(flag_builder)).unwrap();
for f in parse_functions(&src).unwrap() {
Context::for_function(f).compile(&*isa, &mut Default::default()).unwrap();
}
}
```
sh cargo run --release -- repro.clifExpected Results
Compiles successfully. (Verified: x86_64 with
wasmtime compile repro.wasmexits 0 in 0.135s on a c2-standard-16 GCE instance with wasmtime 44.0.1.)Actual Results
Release-mode panic on aarch64:
thread 'main' panicked at cranelift-codegen-0.131.1/src/machinst/buffer.rs:1496:17: assertion failed: (label_offset - offset) <= kind.max_pos_range()cranelift_codegen::machinst::buffer::MachBuffer<I>::handle_fixup cranelift_codegen::machinst::buffer::MachBuffer<I>::emit_island_maybe_forced cranelift_codegen::machinst::vcode::VCode<I>::emit <cranelift_codegen::isa::aarch64::AArch64Backend as TargetIsa>::compile_functionVersions and Environment
Cranelift version: 0.131.0 and 0.131.1
wasmtime cranelift panic line 36.0.7 0.123.7 buffer.rs:139544.0.0 0.131.0 buffer.rs:149644.0.1 0.131.1 buffer.rs:1496Operating system: macOS (Apple Silicon M-series).
Architecture: aarch64 panics; x86_64 unaffected.
Note on specificity. Only
fcvt_to_sint.i32 f64triggers;fcvt_to_uint,fcvt_to_sint.i64, andsdivalone do not (the first two emit noLdr19on this backend, the last has no constant-pool load).
cfallin commented on issue #13270:
Hi -- this is a duplicate of #12968; we know about the issue and have a tentative plan to fix it (I just need to find the time). Thanks! I'll go ahead and close-as-duplicate.
Last updated: Jun 01 2026 at 09:49 UTC