Auto merge of #138634 - saethlin:repeated-uninit, r=scottmcm,oli-obk
Lower to a memset(undef) when Rvalue::Repeat repeats uninit Fixes https://github.com/rust-lang/rust/issues/138625. It is technically correct to just do nothing. But if we actually do nothing, we may miss that this is de-initializing something, so instead we just lower to a single memset that writes undef. This is still superior to the memcpy loop, in both quality of code we hand to the backend and LLVM's final output.
This commit is contained in:
commit
e61403aa4c
3 changed files with 66 additions and 4 deletions
|
@ -9,7 +9,9 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
|
|||
use rustc_type_ir::TypeVisitableExt;
|
||||
|
||||
use super::interpret::ReportedErrorInfo;
|
||||
use crate::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, Scalar, alloc_range};
|
||||
use crate::mir::interpret::{
|
||||
AllocId, AllocRange, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar, alloc_range,
|
||||
};
|
||||
use crate::mir::{Promoted, pretty_print_const_value};
|
||||
use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
|
||||
use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};
|
||||
|
@ -192,9 +194,31 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
.unwrap_memory()
|
||||
.inner()
|
||||
.provenance()
|
||||
.range_empty(super::AllocRange::from(offset..offset + size), &tcx),
|
||||
.range_empty(AllocRange::from(offset..offset + size), &tcx),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a constant only contains uninitialized bytes.
|
||||
pub fn all_bytes_uninit(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
let ConstValue::Indirect { alloc_id, .. } = self else {
|
||||
return false;
|
||||
};
|
||||
let alloc = tcx.global_alloc(*alloc_id);
|
||||
let GlobalAlloc::Memory(alloc) = alloc else {
|
||||
return false;
|
||||
};
|
||||
let init_mask = alloc.0.init_mask();
|
||||
let init_range = init_mask.is_range_initialized(AllocRange {
|
||||
start: Size::ZERO,
|
||||
size: Size::from_bytes(alloc.0.len()),
|
||||
});
|
||||
if let Err(range) = init_range {
|
||||
if range.size == alloc.0.size() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue