-
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
don't allow ZST in ScalarInt #98957
don't allow ZST in ScalarInt #98957
Conversation
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Some changes occurred in const_evaluatable.rs cc @lcnr Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
@@ -449,6 +449,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { | |||
} | |||
|
|||
let fmt_val = |val: &ConstValue<'tcx>| match val { | |||
ConstValue::ZST => format!("ZST"), |
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.
nit: the value isn't really a zero sized type 😁 idk what else I would want to print here though
probably <ZST>
which is what we've done for zero sized scalars before?
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.
Yeah, it's a ZSV, a zero-sized value. But we have called the value a ZST for a while now... (there's some red diff in this PR removing a <ZST>
elsewhere; I think this will have to cause some test failure somewhere)
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.
If they're not too long, ConstValue::ZeroSized
or ConstValue::UnitLike
both seem fine to me.
What's up with CI? I checked this locally... |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
3fa1a07
to
97b345b
Compare
This comment has been minimized.
This comment has been minimized.
97b345b
to
943041a
Compare
@@ -167,6 +167,7 @@ pub(crate) fn codegen_const_value<'tcx>( | |||
} | |||
|
|||
match const_val { | |||
ConstValue::ZST => unreachable!(), // we already handles ZST above |
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.
Does layout.is_zst()
always imply ConstValue::ZST
? If so moving CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout)
into this branch will be a tiny bit faster at runtime and reduce compile time of cg_clif itself a bit too.
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.
Does layout.is_zst() always imply ConstValue::ZST?
I don't know. There might be by-ref ZST ConstValues.
src/test/mir-opt/array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.32bit.mir
Outdated
Show resolved
Hide resolved
943041a
to
c5f27a9
Compare
src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
Outdated
Show resolved
Hide resolved
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32 | ||
} | ||
} | ||
|
||
bb0: { | ||
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:34:16: 34:18 | ||
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17 | ||
_2 = f_zst::<()>(const ()) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17 | ||
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:46:15: 46:16 | ||
_2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17 |
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.
No idea why this is not const-propped any more.
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.
no idea either, but this could have happened with more complex logic before, too, so it's fine to regress and we'll just have to fix const prop
c5f27a9
to
6ec9abe
Compare
☔ The latest upstream changes (presumably #98970) made this pull request unmergeable. Please resolve the merge conflicts. |
6ec9abe
to
d1dd487
Compare
Conflicts resolved and all ready. @oli-obk is that const-prop change a problem or expected and fine? If it even is a const-prop change, the pass name says "lower-intrinsics", so maybe const-prop will fix this up again later? |
@bors r=lcnr,oli-obk |
📌 Commit d1dd4879125325c6730f7f40f75e0b28851e9649 has been approved by |
Oh, that test is |
9864f36
to
4e7aaf1
Compare
@bors r=lcnr,oli-obk rollup=never |
☀️ Test successful - checks-actions |
Finished benchmarking commit (f893495): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Footnotes |
Oh, that's pretty surprising. It's "only" a secondary benchmark so maybe it's okay...? We get some nice RSS reductions in secondary benchmarks in exchange, it seems. ;) |
FWIW that benchmark has a "large amount of extern functions". I am not quite sure where our Scalar types even come to bear here, but it's probably values of Supposedly, previously there were some I'll wait for the regular perf triage to come visit this PR and tell me whether this is okay or whether we should dig a bit deeper into what is going on. |
looks like inliner noise to me |
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value { | ||
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; | ||
match cv { | ||
Scalar::Int(ScalarInt::ZST) => { | ||
assert_eq!(0, layout.size(self).bytes()); |
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.
So I'm looking at this (in the context of Rust-GPU updating the nightly version of Rust we use).
How could this ever pass? abi::Scalar
just can't encode sizes other than 1, 2, 4, 8, 16:
rust/compiler/rustc_target/src/abi/mod.rs
Lines 605 to 611 in 3c72788
pub enum Integer { | |
I8, | |
I16, | |
I32, | |
I64, | |
I128, | |
} |
rust/compiler/rustc_target/src/abi/mod.rs
Lines 703 to 715 in 3c72788
pub enum Primitive { | |
/// The `bool` is the signedness of the `Integer` type. | |
/// | |
/// One would think we would not care about such details this low down, | |
/// but some ABIs are described in terms of C types and ISAs where the | |
/// integer arithmetic is done on {sign,zero}-extended registers, e.g. | |
/// a negative integer passed by zero-extension will appear positive in | |
/// the callee, and most operations on it will produce the wrong values. | |
Int(Integer, bool), | |
F32, | |
F64, | |
Pointer, | |
} |
rust/compiler/rustc_target/src/abi/mod.rs
Lines 827 to 844 in 3c72788
pub enum Scalar { | |
Initialized { | |
value: Primitive, | |
// FIXME(eddyb) always use the shortest range, e.g., by finding | |
// the largest space between two consecutive valid values and | |
// taking everything else as the (shortest) valid range. | |
valid_range: WrappingRange, | |
}, | |
Union { | |
/// Even for unions, we need to use the correct registers for the kind of | |
/// values inside the union, so we keep the `Primitive` type around. We | |
/// also use it to compute the size of the scalar. | |
/// However, unions never have niches and even allow undef, | |
/// so there is no `valid_range`. | |
value: Primitive, | |
}, | |
} |
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.
This is the const eval Scalar, not abi Scalar.
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.
layout
is abi::Scalar
though.
If you scroll up through this PR there is a comment of mine somewhere saying that this must have been dead code.
@@ -223,13 +222,13 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { | |||
}) | |||
} | |||
|
|||
fn zst_to_backend(&self, _llty: &'ll Type) -> &'ll Value { | |||
self.const_undef(self.type_ix(0)) |
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.
I don't think i0
is a legal LLVM type? At least not according to https://llvm.org/docs/LangRef.html#integer-type
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.
I copied this from elsewhere... 🤷
ConstValue::ZeroSized => { | ||
let llval = bx.zst_to_backend(bx.immediate_backend_type(layout)); | ||
OperandValue::Immediate(llval) | ||
} |
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.
If you expand the diff there's a if layout.is_zst() {
above, that early-returns, so this should've been unreachable!()
without the illegal zst_to_backend
implementations existing, looks like.
(and this is the only callsite of zst_to_backend
AFAICT)
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.
Though I think I see how this happened, scalar_to_backend
had a nonsense Scalar::Int(ScalarInt::ZST) => {
case from many years ago (at least 4? I wasn't able to easily go far back enough in git blame
).
And this PR just refactored it into a more obvious spot.
Remove dead broken code from const zst handling in backends cc `@RalfJung` found by `@eddyb` in rust-lang#98957 (comment)
There are several indications that we should not ZST as a ScalarInt:
Branch
or aLeaf
with a ZST in it.ValTree::zst()
used the former, but the latter could possibly arise as well.Immediate::Uninit
andImmediate::Scalar(Scalar::ZST)
.So I propose we stop using ScalarInt to represent ZST (which are clearly not integers). Instead, we can add new ZST variants to those types that did not have other variants which could be used for this purpose.
Based on #98831. Only the commits starting from "don't allow ZST in ScalarInt" are new.
r? @oli-obk