cfallin edited issue #3217:
For the below
.clif
code Cranelift appears to pass unsolvable input to regalloc. This was previously investigated as an issue with regalloc, but after some investigation @cfallin suggested moving it here.This has been observed to cause failures when using regalloc and the upcoming regalloc2.
.clif
Test Casefunction u0:0() -> r64 system_v { sig0 = (i64) -> r64 system_v sig1 = (r64, r64, r64) -> r64 system_v sig2 = (i64) -> r64 system_v sig3 = (i64) -> r64 system_v sig4 = (r64, r64, r64) -> r64 system_v sig5 = (r64, r64, r64) -> r64 system_v fn0 = colocated u0:2 sig0 fn1 = colocated u0:5 sig1 fn2 = colocated u0:2 sig2 fn3 = colocated u0:2 sig3 block0: v0 = iconst.i64 8 v1 = call fn0(v0) v2 = func_addr.r64 fn1 store v2, v1 v3 = raw_bitcast.i64 v1 v4 = bor_imm v3, 6 v5 = raw_bitcast.r64 v4 v6 = raw_bitcast.i64 v5 v7 = band_imm v6, -8 v8 = raw_bitcast.r64 v7 v9 = load.r64 v8 v10 = iconst.i64 1 v11 = raw_bitcast.r64 v10 v12 = iconst.i64 8 v13 = call fn2(v12) v14 = raw_bitcast.i64 v5 v15 = band_imm v14, -8 v16 = raw_bitcast.r64 v15 v17 = load.r64 v16 v18 = iconst.i64 1 v19 = raw_bitcast.r64 v18 v20 = iconst.i64 8 v21 = call fn3(v20) v22 = iconst.i64 8 v23 = raw_bitcast.r64 v22 store v23, v21 v24 = call_indirect sig4, v17(v16, v19, v21) store v24, v13 v25 = call_indirect sig5, v9(v8, v11, v13) return v25 }
Steps to Reproduce
- Place
.clif
test case above in a filefn.clif
- Run
cargo run -p cranelift-tools -- compile --target x86_64 -D fn.clif
and observe a panic.thread 'main' panicked at 'assertion failed: vlr_env[cand_vlrix].is_ref == is_ref', /Users/zekemedley/.cargo/registry/src/github.com-1ecc6299db9ec823/regalloc-0.0.31/src/bt_spillslot_allocator.rs:298:13
Reproduction with regalloc2
- Place
.clif
test case above in a filefn.clif
- Follow the insutructions here for compiling Cranelift with regalloc2.
- Run
cargo run -p cranelift-tools -- compile --target x86_64 -D fn.clif
and observe a panic.thread 'main' panicked at 'Minimal bundle with conflict!', /Users/zekemedley/Desktop/projects/lust/regalloc-bug/regalloc2/src/ion/process.rs:763:13
cfallin labeled issue #3217:
For the below
.clif
code Cranelift appears to pass unsolvable input to regalloc. This was previously investigated as an issue with regalloc, but after some investigation @cfallin suggested moving it here.This has been observed to cause failures when using regalloc and the upcoming regalloc2.
.clif
Test Casefunction u0:0() -> r64 system_v { sig0 = (i64) -> r64 system_v sig1 = (r64, r64, r64) -> r64 system_v sig2 = (i64) -> r64 system_v sig3 = (i64) -> r64 system_v sig4 = (r64, r64, r64) -> r64 system_v sig5 = (r64, r64, r64) -> r64 system_v fn0 = colocated u0:2 sig0 fn1 = colocated u0:5 sig1 fn2 = colocated u0:2 sig2 fn3 = colocated u0:2 sig3 block0: v0 = iconst.i64 8 v1 = call fn0(v0) v2 = func_addr.r64 fn1 store v2, v1 v3 = raw_bitcast.i64 v1 v4 = bor_imm v3, 6 v5 = raw_bitcast.r64 v4 v6 = raw_bitcast.i64 v5 v7 = band_imm v6, -8 v8 = raw_bitcast.r64 v7 v9 = load.r64 v8 v10 = iconst.i64 1 v11 = raw_bitcast.r64 v10 v12 = iconst.i64 8 v13 = call fn2(v12) v14 = raw_bitcast.i64 v5 v15 = band_imm v14, -8 v16 = raw_bitcast.r64 v15 v17 = load.r64 v16 v18 = iconst.i64 1 v19 = raw_bitcast.r64 v18 v20 = iconst.i64 8 v21 = call fn3(v20) v22 = iconst.i64 8 v23 = raw_bitcast.r64 v22 store v23, v21 v24 = call_indirect sig4, v17(v16, v19, v21) store v24, v13 v25 = call_indirect sig5, v9(v8, v11, v13) return v25 }
Steps to Reproduce
- Place
.clif
test case above in a filefn.clif
- Run
cargo run -p cranelift-tools -- compile --target x86_64 -D fn.clif
and observe a panic.thread 'main' panicked at 'assertion failed: vlr_env[cand_vlrix].is_ref == is_ref', /Users/zekemedley/.cargo/registry/src/github.com-1ecc6299db9ec823/regalloc-0.0.31/src/bt_spillslot_allocator.rs:298:13
Reproduction with regalloc2
- Place
.clif
test case above in a filefn.clif
- Follow the insutructions here for compiling Cranelift with regalloc2.
- Run
cargo run -p cranelift-tools -- compile --target x86_64 -D fn.clif
and observe a panic.thread 'main' panicked at 'Minimal bundle with conflict!', /Users/zekemedley/Desktop/projects/lust/regalloc-bug/regalloc2/src/ion/process.rs:763:13
wrbs commented on issue #3217:
I ran in to this too for my projeect which similarly used bitcasting to turn r64 <-> i64`. I ended up vendoring regalloc and commenting out the assert to not be there. I did not attempt to understand why this worked.
It was a JIT backend to OCaml which has a precise GC which needs to know every root's location otherwise things will very quickly break (as I encountered many times).
Thanks to implementing all of OCaml I had a very large 20-year-old test suite to check against. I also had long-running benchmarks doing lots of garbage collections and no odd breakages due to miscompiles.
wrbs edited a comment on issue #3217:
I ran in to this too for my project which similarly used bitcasting to turn r64 <-> i64`. I ended up vendoring regalloc and commenting out the assert to not be there. I did not attempt to understand why this worked.
It was a JIT backend to OCaml which has a precise GC which needs to know every root's location otherwise things will very quickly break (as I encountered many times).
Thanks to implementing all of OCaml I had a very large 20-year-old test suite to check against. I also had long-running benchmarks doing lots of garbage collections and no odd breakages due to miscompiles.
wrbs edited a comment on issue #3217:
I ran in to this too for my project which similarly used bitcasting to turn r64 <-> i64`. I ended up vendoring regalloc and commenting out the assert to not be there. I did not attempt to understand why this worked (or rather, I did and very quickly realised I would not have the week required to get my head around how everything worked.) When I brought it up I think I remember @cfallin saying to wait for the rewrite of regalloc which seems to have happened now?
It was a JIT backend to OCaml which has a precise GC which needs to know every root's location otherwise things will very quickly break (as I encountered many times).
Thanks to implementing all of OCaml I had a very large 20-year-old test suite to check against. I also had long-running benchmarks doing lots of garbage collections and no odd breakages due to miscompiles.
bjorn3 commented on issue #3217:
I did not attempt to understand why this worked
I am fairly certain it doesn't actually fix the problem, but instead allows a silent miscompilation where the stackmap may be missing entries.
bjorn3 edited a comment on issue #3217:
I did not attempt to understand why this worked
I am fairly certain it doesn't actually fix the problem, but instead allows a silent miscompilation where the stackmap may be missing entries or have erroneous entries.
fitzgen commented on issue #3217:
In general, I think we should be adding support for using
r{32,64}
anywhere thati{32,64}
can be used (e.g. in loads/stores/etc) this way we can always generate correct stack maps, and users don't have to do unsafe bitcasts that can result in missing stack map entries, as @bjorn3 points out.
wrbs commented on issue #3217:
I did not attempt to understand why this worked
I am fairly certain it doesn't actually fix the problem, but instead allows a silent miscompilation where the stackmap may be missing entries or have erroneous entries.
Actually thinking back a little bit more this checks out - there was one error I didn't track down, but only for one benchmark just after a GC run. I I suspected at the time it might have been due to this
Last updated: Dec 23 2024 at 13:07 UTC