bjorn3 opened PR #10593 from bjorn3:fix_try_call to bytecodealliance:main:
Together with a change to allow the system_v call conv, this is enough to pass as much of cg_clif's test suite as is expected given how much I wired up on the cg_clif side.
The second commit is not strictly necessary for correctness, but does make the optimizer work better with try_call.
bjorn3 requested fitzgen for a review on PR #10593.
bjorn3 requested wasmtime-compiler-reviewers for a review on PR #10593.
bjorn3 edited PR #10593:
Together with a change to allow the system_v call conv, this is enough to pass as much of cg_clif's test suite as is expected given how much I wired up on the cg_clif side.Edit: Seems like rust's bootstrap executable still gets miscompiled, will fix in a later PR.
The second commit is not strictly necessary for correctness, but does make the optimizer work better with try_call.
bjorn3 edited PR #10593:
Together with a change to allow the system_v call conv, this is enough to pass as much of cg_clif's test suite as is expected given how much I wired up on the cg_clif side.The second commit is not strictly necessary for correctness, but does make the optimizer work better with try_call.
bjorn3 commented on PR #10593:
The following gets miscompiled even with this PR (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Box<[u8]>, } impl MyCString { #[inline(never)] pub fn new(bytes: &[u8]) -> MyCString { let buffer = bytes.to_vec(); let mut buffer = buffer; buffer.push(0); Self { inner: buffer.into_boxed_slice() } } } fn main() { let s = MyCString::new(b"ar"); panic!("{:?}", s.inner); // nul-terminator gets lost }
bjorn3 edited a comment on PR #10593:
The following gets miscompiled even with this PR (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } impl MyCString { #[inline(never)] pub fn new(bytes: &[u8]) -> MyCString { let buffer = bytes.to_vec(); let mut buffer = buffer; buffer.push(0); Self { inner: buffer } } } fn main() { let s = MyCString::new(b"ar"); panic!("{:?}", s.inner); // nul-terminator gets lost }
bjorn3 edited a comment on PR #10593:
The following gets miscompiled even with this PR in release mode (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } impl MyCString { #[inline(never)] pub fn new(bytes: &[u8]) -> MyCString { let buffer = bytes.to_vec(); let mut buffer = buffer; buffer.push(0); Self { inner: buffer } } } fn main() { let s = MyCString::new(b"ar"); panic!("{:?}", s.inner); // nul-terminator gets lost }
fitzgen submitted PR review:
LGTM, but we should have a test for the first commit before this merges. Thanks!
fitzgen created PR review comment:
Mind adding a simple test for a
try_callwhere the same successor appears multiple times?
fitzgen created PR review comment:
This pass is used by
cg_clif, I assume? We should probably have filetests for these changes, but I see that we don't have the infrastructure to run this pass on filetests at the moment, and I don't want to necessarily block on that. But longer term, we should either gain that functionality, so that we can hold it to our usual code standards, or else this pass should move intocg_clif(since I don't believe it relies on anything that isn't publicly exported).
bjorn3 submitted PR review.
bjorn3 created PR review comment:
This pass is part of the normal optimization pipeline of Cranelift and runs unconditionally.
fitzgen submitted PR review.
fitzgen created PR review comment:
Huh.
rust-analyzerwasn't finding uses of it for me.Do we exercise it under the
test optimizefiletest mode? If so, can you add a filetest for it?
bjorn3 edited a comment on PR #10593:
The following gets miscompiled even with this PR in release mode (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } #[inline(never)] fn push(v: &mut Vec<u8>) { v.push(0); } impl MyCString { #[inline(never)] pub fn new() -> MyCString { let buffer = Vec::new(); let mut buffer = buffer; push(&mut buffer); Self { inner: buffer } } } fn main() { let s = MyCString::new(); panic!("{:?}", s.inner); // nul-terminator gets lost }
bjorn3 edited a comment on PR #10593:
The following gets miscompiled even with this PR in release mode (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } #[inline(never)] fn push(v: &mut Vec<u8>) { v.push(0); } impl MyCString { #[inline(never)] pub fn new() -> MyCString { let mut buffer = const { Vec::new() }; push(&mut buffer); Self { inner: buffer } } } fn main() { let s = MyCString::new(); panic!("{:?}", s.inner); // nul-terminator gets lost }
bjorn3 edited a comment on PR #10593:
The following gets miscompiled even with this PR in release mode (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } #[inline(never)] fn push(v: &mut Vec<u8>) { v.push(0); } impl MyCString { #[inline(never)] pub fn new() -> MyCString { let mut buffer = const { MyCString { inner: Vec::new() } }; push(&mut buffer.inner); buffer } } fn main() { let s = MyCString::new(); panic!("{:?}", s.inner); // nul-terminator gets lost }
bjorn3 updated PR #10593.
bjorn3 edited a comment on PR #10593:
<details><summary>Fixed miscompilation</summary>
The following gets miscompiled even with this PR in release mode (will fix in a future PR, but leaving my debugging notes here):
use std::ffi::CString; fn main() { let s = CString::new(b"ar"); panic!("{s:?}"); }Reduced so far to:
pub struct MyCString { inner: Vec<u8>, } #[inline(never)] fn push(v: &mut Vec<u8>) { v.push(0); } impl MyCString { #[inline(never)] pub fn new() -> MyCString { let mut buffer = const { MyCString { inner: Vec::new() } }; push(&mut buffer.inner); buffer } } fn main() { let s = MyCString::new(); panic!("{:?}", s.inner); // nul-terminator gets lost }</details>
Edit: Pushed a commit to fix this miscompilation.
bjorn3 submitted PR review.
bjorn3 created PR review comment:
Context::optimizecontains an unconditional call toself.eliminate_unreachable_code(isa)?;which in turn calls this function.
bjorn3 updated PR #10593.
bjorn3 edited PR #10593:
Together with a change to allow the system_v call conv, this is enough to pass most of cg_clif's test suite (including panicking tests). In addition rustc's compiletest now works just fine in panic=unwind mode. Not all rustc tests pass yet, but the test failures seem to be caused by either cg_clif or bugs in the tests themself.
The second commit is not strictly necessary for correctness, but does make the optimizer work better with try_call.
bjorn3 updated PR #10593.
bjorn3 updated PR #10593.
bjorn3 updated PR #10593.
bjorn3 submitted PR review.
bjorn3 created PR review comment:
Added a test. Also saw that there was a debug assertion that would have caused it. I've upgraded it to a regular assertion as it should be cheap.
bjorn3 edited PR review comment.
bjorn3 updated PR #10593.
bjorn3 submitted PR review.
bjorn3 created PR review comment:
As for testing, I'm not sure how to do that given that the clif ir printing doesn't show a list of all exception tables, but rather only shows them as part of a
try_callinstruction.
bjorn3 updated PR #10593.
cfallin submitted PR review:
LGTM on the additional commits -- just one thought on the verifier change below. I'm excited that you found the memory-fence issue and have things working with
cg_clifnow!
cfallin created PR review comment:
Perhaps we could
continuehere so we still check the remaining args?
bjorn3 submitted PR review.
bjorn3 created PR review comment:
Right, will fix.
bjorn3 updated PR #10593.
bjorn3 submitted PR review.
bjorn3 created PR review comment:
Done
cfallin submitted PR review.
cfallin created PR review comment:
I think that's correct -- I can't see a way to test for dangling exception tables either unless we change the print format. I think this is probably fine to merge as-is -- the other direction (avoiding false-removals of actually used exception tables) is the more important one and is implicitly tested.
cfallin commented on PR #10593:
Looked over all commits and this looks good -- I'm going to do a short followup based on @bjorn3's
cg_clifunwinding enabling work, so I'll go ahead and merge this now.
cfallin merged PR #10593.
Last updated: Dec 06 2025 at 07:03 UTC