-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Intptrcast model #61668
Intptrcast model #61668
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
@@ -314,13 +314,23 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> | |||
right.to_scalar_ptr()?.is_ptr() || | |||
bin_op == mir::BinOp::Offset | |||
{ | |||
return M::ptr_op(self, bin_op, left, right); | |||
if left.layout.ty.is_integral() && right.layout.ty.is_integral() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this change done? It seems good, but unrelated to this PR right now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was done per @RalfJung suggestions. Here are his comments on the matter:
basically, if we have integer addresses, we have two cases:
either left.layout.ty.is_integral() && right.layout.ty.is_integral(). then both sides should be ptr-to-int-cast, and we proceed with binary_int_op.
or bin_op == mir::BinOp::Offset, then call M::ptr_op.
if we dont have integer addresses, behavior should be unchanged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this is then indeed where your test output changes come from: force_bits
is guaranteed to fail, since we already know that either left
or right
is a Scalar::Ptr
(as per the if
condition in line 313 and 314)
I don't think we should do this here, but instead miri can do this in ptr_op
once it actually supports intptr. If we merged this, there would be no way for miri to do a change that will fix its test suite other than implementing intptr.
It's also useless for const eval, so I think it should not be in the engine.
@RalfJung or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well now I can't look any more because the diff is broken. :/
But I somehow didn't like going through Miri and back when we have ptr-int-casts available. The code flow would be somewhat weird: Miri would do force_bits
and then call back to here, and endless recursion would be prevented because things would then not be pointers any more.
Notice that I specifically said "if we dont have integer addresses, behavior should be unchanged" in my plan; the idea was that we would have some way to detect that (maybe check the force
functions return value for Err
?). But maybe you are right and it makes more sense to do all of that in Miri.
I just really don't like seeing any value-based dispatching in the code here. Dispatching should be purely type-based...
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops forgot to send off my review. why can't github tell me aggressively I have written reviews but not sent them?
src/librustc_mir/interpret/memory.rs
Outdated
) -> EvalResult<'tcx, Pointer<M::PointerTag>> { | ||
match scalar { | ||
Scalar::Ptr(ptr) => Ok(ptr), | ||
_ => M::int_to_ptr(scalar.to_u64()?, &self.extra) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise you'll get a "read undef bytes" error when interpreting 32 bit code
_ => M::int_to_ptr(scalar.to_u64()?, &self.extra) | |
_ => M::int_to_ptr(scalar.to_usize(self)?, &self.extra) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked about this on zulip and I thought I've done it, I'll fix it
@@ -314,13 +314,23 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> | |||
right.to_scalar_ptr()?.is_ptr() || | |||
bin_op == mir::BinOp::Offset | |||
{ | |||
return M::ptr_op(self, bin_op, left, right); | |||
if left.layout.ty.is_integral() && right.layout.ty.is_integral() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, this is then indeed where your test output changes come from: force_bits
is guaranteed to fail, since we already know that either left
or right
is a Scalar::Ptr
(as per the if
condition in line 313 and 314)
I don't think we should do this here, but instead miri can do this in ptr_op
once it actually supports intptr. If we merged this, there would be no way for miri to do a change that will fix its test suite other than implementing intptr.
It's also useless for const eval, so I think it should not be in the engine.
@RalfJung or am I missing something?
This uses a well-known branchless implementation of `signum`. Its `const`-ness is unstable and requires `#![feature(const_int_sign)]`.
I messed up solving the conflicts, I'll redo the changes on a fresh branch and do another PR |
…=oli-obk prepare for Intptrcast model rust-lang#61668 done right (I hope so). r? @RalfJung @oli-obk
…=oli-obk prepare for Intptrcast model rust-lang#61668 done right (I hope so). r? @RalfJung @oli-obk
…=oli-obk prepare for Intptrcast model rust-lang#61668 done right (I hope so). r? @RalfJung @oli-obk
rust-lang/miri#224