diff options
| author | bors <bors@rust-lang.org> | 2025-03-25 02:09:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-03-25 02:09:15 +0000 |
| commit | e61403aa4cfbce34b34d78efb52b300a76ac5a62 (patch) | |
| tree | 00c842650ecbefb713decfd25d5612a4f747c6c0 /compiler/rustc_codegen_ssa/src | |
| parent | 1df5affacad5583b98e13b6f1617b8c781f57aa1 (diff) | |
| parent | 8e7d8ddffe802180b504e0ecaaa40b10b28b291e (diff) | |
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.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index a969ce7878a..5c14fe5cd10 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -86,13 +86,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Repeat(ref elem, count) => { - let cg_elem = self.codegen_operand(bx, elem); - // Do not generate the loop for zero-sized elements or empty arrays. if dest.layout.is_zst() { return; } + // When the element is a const with all bytes uninit, emit a single memset that + // writes undef to the entire destination. + if let mir::Operand::Constant(const_op) = elem { + let val = self.eval_mir_constant(const_op); + if val.all_bytes_uninit(self.cx.tcx()) { + let size = bx.const_usize(dest.layout.size.bytes()); + bx.memset( + dest.val.llval, + bx.const_undef(bx.type_i8()), + size, + dest.val.align, + MemFlags::empty(), + ); + return; + } + } + + let cg_elem = self.codegen_operand(bx, elem); + let try_init_all_same = |bx: &mut Bx, v| { let start = dest.val.llval; let size = bx.const_usize(dest.layout.size.bytes()); |
