Repository navigation
add core::arch::{x86, x86_64}::x87_f80 - #163992
folkertdev wants to merge 6 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
b4fafc4 to
16b2882
Compare
This comment has been minimized.
This comment has been minimized.
16b2882 to
617db2d
Compare
617db2d to
d582ca8
Compare
|
Some changes occurred in compiler/rustc_attr_ir cc @jdonszelmann, @JonathanBrouwer
cc @bjorn3 Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri Some changes occurred to the CTFE machinery This PR changes rustc_public cc @oli-obk, @celinval, @ouz-a, @makai410
|
|
@bors try jobs=test-various,test-i686-* |
This comment has been minimized.
This comment has been minimized.
add `core::arch::{x86, x86_64}::x87_f80`
try-job: test-various
try-job: test-i686-*
d582ca8 to
a9a37a4
Compare
"f80" is 128 bits large on 64-bit targets...?!?? How does that make any sense?
I'd be surprised if we didn't. That's been pretty much part of the definition of being a scalar -- if a type has padding, it is not a scalar type. The interpreter was built around that assumption. It does not sound to me like this type can be a scalar, then. |
| // For `x87_f80` the primitive is 80 bits, but the field (after rounding up to | ||
| // the alignment) is 12 bytes (on 32-bit systems) or 16 bytes (64-bit). | ||
| // So we can't assert equality of size and layout.size. | ||
| assert_eq!( | ||
| size.align_to(s.default_align(self).abi), | ||
| mplace.layout.size, | ||
| "abi::Scalar is larger than its layout" | ||
| ); |
There was a problem hiding this comment.
The entire logic for dealing with scalars throughout the interpreter assumes that they have no padding. Changing this assertion is not enough, it just means the rest of the interpreter is now more or less silently wrong. Pretty much all codepaths that deal with scalars need to be audited. Same for every other MIR consumer.
I would strongly prefer if we didn't break the fundamental concept of a "scalar".
There was a problem hiding this comment.
To give just one example, here's one place we make that assumption:
rust/compiler/rustc_const_eval/src/interpret/place.rs
Lines 792 to 794 in 6aaabbb
You can't even see it. But if you look at the ScalarPair path you can see that we have to ensure that padding gets reset to uninit, and in the Scalar path we don't have to worry about that.
Also, the basic APIs for reading/writing stuff in an Allocation are read_scalar/write_scalar. This again uses the term "scalar" to refer to something that has no padding. Same for the type Scalar. And so on.
|
It would probably be possible, with a lot of effort, to fix all the places where we assume scalars have no padding. But I think that's a bad idea. It makes life harder for every MIR consumer. (Most likely it'll mean many MIR consumers will stay buggy as nobody will expect something as outlandish as this weird type.) This new type is the weird one here, we should not shape everything around a legacy type that hardly anyone needs and that has no justification to exist in the first place other than "it has always been here". |
|
I think it might make sense to introduce something like |
|
For Rust's purposes could we just pretend it's a |
5b52d2c to
18ceb9e
Compare
|
@rustbot ready |
There was a problem hiding this comment.
One nit, then LGTM (pending a clarification from @RalfJung).
| /// The `x87_f80` wrapper type below corresponds to the alloc size: it applies the target-specific | ||
| /// alignment, raising the total size to 12 or 16. | ||
| /// | ||
| /// NOTE: this type MUST NOT be used anywhere except in the x87_f80 wrapper below. |
There was a problem hiding this comment.
| /// NOTE: this type MUST NOT be used anywhere except in the x87_f80 wrapper below. |
This line can be removed now.
@RalfJung, to clarify are you saying that the current state of the tests is fine from your side, or that you'd like to see some tests that can be run via Miri before this PR merges? |
|
A Miri test would be better to confirm that indeed the interpreter can work with this new "weird" type. |
18ceb9e to
0fd1c88
Compare
|
cc @rust-lang/miri |
There was a problem hiding this comment.
Thanks! Looks good.
There was a problem hiding this comment.
Oh wait I didn't realize there were changes beyond the new test...
| ty::Adt(..) | ||
| if let BackendRepr::Scalar(scalar) = value.layout.backend_repr | ||
| && scalar.primitive() == Primitive::Float(Float::X87F80) => | ||
| { | ||
| // The x87_f80_raw lang item should be treated as a scalar in this context. | ||
| // | ||
| // NOTE: Keep this in sync with the array optimization for int/float | ||
| // types below! | ||
| self.read_scalar(value, ExpectedKind::Float)?; | ||
| if self.reset_provenance_and_padding { | ||
| self.ecx.clear_provenance(value)?; | ||
| self.add_data_range_place(value); | ||
| } | ||
| interp_ok(true) | ||
| } |
There was a problem hiding this comment.
This is needed for accurate tracking of what bytes are initialized, because structurally x87_f80_raw is an ADT with no fields.
That makes it different from ppcf128 and f16b which have an integer inside of them and hit the branch right above this.
There was a problem hiding this comment.
The comment and your text talks about x87_f80_raw but the code does not have "raw" in it? The comment talks about a lang item but the code does not? I am quite confused.
| /// NOTE: this type should not be used anywhere except in the x87_f80 wrapper below. The backend | ||
| /// can handle it fine, but callconv calculation will likely panic. |
There was a problem hiding this comment.
I've kept but weakened the line here. It still does not make sense to use this type, and it will likely panic if you try, but should not otherwise do anything weird.
| ty::Adt(..) | ||
| if let BackendRepr::Scalar(scalar) = value.layout.backend_repr | ||
| && scalar.primitive() == Primitive::Float(Float::X87F80) => |
There was a problem hiding this comment.
This will also kick in for transparent wrappers around the lang item, right?
That's not what we want here, this should only identify the actual primitive type.
There was a problem hiding this comment.
Sure, I've changed it to just check for the lang item instead
There was a problem hiding this comment.
is that acceptable?
There was a problem hiding this comment.
I didn't forget about this, I have other obligations besides reviewing Rust PRs. No reason to push.
There was a problem hiding this comment.
Yes the logic looks good now. I am confused by this comment:
// NOTE: Keep this in sync with the array optimization for int/float
// types below!
The array optimization does not consider X87F80Raw so this comment seems bogus?
There was a problem hiding this comment.
Right, I just copied it from above but that optimization also only looks at the TyKind and would never fire for x87_f80. That's probably fine (for now), we don't expect usage of this type will ever really be a performance problem.
I didn't forget about this, I have other obligations besides reviewing Rust PRs. No reason to push.
Sorry, I was just trying to make the implicit question in my earlier comment explicit. Thanks for taking a look!
16dc967 to
27fa2c7
Compare
| ty::Adt(adt_def, _) | ||
| if self.ecx.tcx.is_lang_item(adt_def.did(), LangItem::X87F80Raw) => | ||
| { | ||
| // The x87_f80_raw lang item should be treated as a scalar in this context. |
There was a problem hiding this comment.
| // The x87_f80_raw lang item should be treated as a scalar in this context. | |
| // The x87_f80_raw lang item is effectively a primitive. |
Without it, reads are reported as UB because the tracking of what bytes are initialized is incorect
27fa2c7 to
d64f2fb
Compare
View all comments
tracking issue: #163982
cc #161787
Add
x87_f80in the same way asf16bandppcf128.It's unclear what to do with this type on softfloat targets. Clang and GCC reject the type when the x87 registers are not available. We should do the same, probably just with a
cfg?I don't think we have a good
cfgfor this though?x87is still set on softfloat targets, whilesoft-floatdoesn't get set (that does not give a warning even, it probably should?). We also don't setcfg_abi.future work
Complex<x87_f80>has not yet been implementedx87_f80does not yet implementVaArgSafe