From 845e4b5962aa84fcfc0b8a6b1e4b9e32725547ef Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 23 Jan 2021 02:28:08 +0000 Subject: [PATCH] Change CopyNonOverlapping::codegen_ssa Fixes copy_non_overlapping codegen_ssa to properly handle pointees, and use bytes instead of elem count --- .../rustc_codegen_ssa/src/mir/statement.rs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 054273262f79..e11539c14760 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -122,19 +122,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) => { let dst_val = self.codegen_operand(&mut bx, dst); let src_val = self.codegen_operand(&mut bx, src); - let count_val = self.codegen_operand(&mut bx, count); - let count = count_val.immediate_or_packed_pair(&mut bx); - let dst = dst_val.immediate_or_packed_pair(&mut bx); - let src = src_val.immediate_or_packed_pair(&mut bx); - let flags = crate::MemFlags::empty(); - bx.memcpy( - dst, - dst_val.layout.layout.align.pref, - src, - src_val.layout.layout.align.pref, - count, - flags, - ); + let count = self.codegen_operand(&mut bx, count).immediate(); + let get_val_align = |oper_ref: crate::mir::OperandRef<'_, _>| match oper_ref.val { + OperandValue::Ref(val, _, align) => (val, align), + _ => unreachable!(), + }; + let pointee_layout = dst_val + .layout + .pointee_info_at(&mut bx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); + let elem_size = bx.const_u64(pointee_layout.size.bytes()); + let byte_count = bx.mul(count, elem_size); + + let (dst, dst_align) = get_val_align(dst_val); + let (src, src_align) = get_val_align(src_val); + bx.memcpy(dst, dst_align, src, src_align, byte_count, crate::MemFlags::empty()); bx } mir::StatementKind::FakeRead(..)