Skip to content

Commit 217ff6b

Browse files
committed
Switch to changing cp_non_overlap in tform
It was suggested to lower this in MIR instead of ssa, so do that instead.
1 parent d4ae9ff commit 217ff6b

File tree

10 files changed

+67
-62
lines changed

10 files changed

+67
-62
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

+2-18
Original file line numberDiff line numberDiff line change
@@ -643,23 +643,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
643643

644644
match intrinsic {
645645
None | Some(sym::drop_in_place) => {}
646-
Some(sym::copy_nonoverlapping) => {
647-
bx = self.codegen_statement(
648-
bx,
649-
&rustc_middle::mir::Statement {
650-
source_info: rustc_middle::mir::SourceInfo::outermost(span),
651-
kind: rustc_middle::mir::StatementKind::CopyNonOverlapping(
652-
box rustc_middle::mir::CopyNonOverlapping {
653-
src: args[0].clone(),
654-
dst: args[1].clone(),
655-
count: args[2].clone(),
656-
},
657-
),
658-
},
659-
);
660-
helper.funclet_br(self, &mut bx, destination.unwrap().1);
661-
return;
662-
}
646+
Some(sym::copy_nonoverlapping) => unreachable!(),
663647
Some(intrinsic) => {
664648
let dest = match ret_dest {
665649
_ if fn_abi.ret.is_indirect() => llargs[0],
@@ -702,7 +686,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
702686
})
703687
.collect();
704688

705-
self.codegen_intrinsic_call(
689+
Self::codegen_intrinsic_call(
706690
&mut bx,
707691
*instance.as_ref().unwrap(),
708692
&fn_abi,

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

-6
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
4949

5050
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
5151
pub fn codegen_intrinsic_call(
52-
&self,
5352
bx: &mut Bx,
5453
instance: ty::Instance<'tcx>,
5554
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
@@ -126,11 +125,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
126125
let offset = args[1].immediate();
127126
bx.gep(ptr, &[offset])
128127
}
129-
130-
sym::copy_nonoverlapping => {
131-
// handled explicitly in compiler/rustc_codegen_ssa/src/mir/block.rs
132-
unreachable!();
133-
}
134128
sym::copy => {
135129
copy_intrinsic(
136130
bx,

compiler/rustc_middle/src/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1682,7 +1682,7 @@ pub struct Coverage {
16821682
pub code_region: Option<CodeRegion>,
16831683
}
16841684

1685-
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1685+
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
16861686
pub struct CopyNonOverlapping<'tcx> {
16871687
pub src: Operand<'tcx>,
16881688
pub dst: Operand<'tcx>,

compiler/rustc_mir/src/borrow_check/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -628,13 +628,19 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
628628
}
629629

630630
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
631+
..
632+
/*
631633
src,
632634
dst,
633635
count,
636+
*/
634637
}) => {
638+
unreachable!()
639+
/*
635640
self.consume_operand(location, (src, span), flow_state);
636641
self.consume_operand(location, (dst, span), flow_state);
637642
self.consume_operand(location, (count, span), flow_state);
643+
*/
638644
}
639645
StatementKind::Nop
640646
| StatementKind::Coverage(..)

compiler/rustc_mir/src/interpret/intrinsics.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
323323
let result = Scalar::from_uint(truncated_bits, layout.size);
324324
self.write_scalar(result, dest)?;
325325
}
326-
sym::copy | sym::copy_nonoverlapping => {
326+
sym::copy_nonoverlapping => {
327+
self.copy_nonoverlapping(args[0], args[1], args[2])?;
328+
}
329+
sym::copy => {
327330
let elem_ty = instance.substs.type_at(0);
328331
let elem_layout = self.layout_of(elem_ty)?;
329332
let count = self.read_scalar(&args[2])?.to_machine_usize(self)?;
@@ -338,12 +341,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
338341
let dest = self.memory.check_ptr_access(dest, size, elem_align)?;
339342

340343
if let (Some(src), Some(dest)) = (src, dest) {
341-
self.memory.copy(
342-
src,
343-
dest,
344-
size,
345-
intrinsic_name == sym::copy_nonoverlapping,
346-
)?;
344+
self.memory.copy(src, dest, size, false)?;
347345
}
348346
}
349347
sym::offset => {

compiler/rustc_mir/src/interpret/step.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//!
33
//! The main entry point is the `step` method.
44
5+
use crate::interpret::OpTy;
56
use rustc_middle::mir;
67
use rustc_middle::mir::interpret::{InterpResult, Scalar};
78
use rustc_target::abi::LayoutOf;
@@ -115,35 +116,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
115116

116117
// Call CopyNonOverlapping
117118
CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
118-
let (src, size) = {
119-
let src = self.eval_operand(src, None)?;
120-
let size = src.layout.layout.size;
121-
let mplace = *src.assert_mem_place(self);
122-
let ptr = match mplace.ptr {
123-
Scalar::Ptr(ptr) => ptr,
124-
_ => panic!(),
125-
};
126-
(ptr, size)
127-
};
128-
129-
let dst = {
130-
let dst = self.eval_operand(dst, None)?;
131-
let mplace = *dst.assert_mem_place(self);
132-
match mplace.ptr {
133-
Scalar::Ptr(ptr) => ptr,
134-
_ => panic!(),
135-
}
136-
};
137-
138119
let count = self.eval_operand(count, None)?;
139-
let count = self.read_immediate(count)?.to_scalar()?;
140-
let count = if let Scalar::Int(i) = count {
141-
core::convert::TryFrom::try_from(i).unwrap()
142-
} else {
143-
panic!();
144-
};
145120

146-
self.memory.copy_repeatedly(src, dst, size, count, /*nonoverlapping*/ true)?;
121+
let src = self.eval_operand(src, None)?;
122+
let dst = self.eval_operand(dst, None)?;
123+
self.copy_nonoverlapping(src, dst, count)?;
147124
}
148125

149126
// Statements we do not track.
@@ -173,6 +150,31 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
173150
Ok(())
174151
}
175152

153+
pub(crate) fn copy_nonoverlapping(
154+
&mut self,
155+
src: OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
156+
dst: OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
157+
count: OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
158+
) -> InterpResult<'tcx> {
159+
let count = self.read_scalar(&count)?.to_machine_usize(self)?;
160+
let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
161+
let (size, align) = (layout.size, layout.align.abi);
162+
let src =
163+
self.memory.check_ptr_access(self.read_scalar(&src)?.check_init()?, size, align)?;
164+
165+
let dst =
166+
self.memory.check_ptr_access(self.read_scalar(&dst)?.check_init()?, size, align)?;
167+
168+
let size = size.checked_mul(count, self).ok_or_else(|| {
169+
err_ub_format!("overflow computing total size of `copy_nonoverlapping`")
170+
})?;
171+
172+
if let (Some(src), Some(dst)) = (src, dst) {
173+
self.memory.copy(src, dst, size, /*nonoverlapping*/ true)?;
174+
}
175+
Ok(())
176+
}
177+
176178
/// Evaluate an assignment statement.
177179
///
178180
/// There is no separate `eval_rvalue` function. Instead, the code for handling each rvalue

compiler/rustc_mir/src/transform/check_unsafety.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
115115
| StatementKind::Retag { .. }
116116
| StatementKind::AscribeUserType(..)
117117
| StatementKind::Coverage(..)
118-
| StatementKind::CopyNonOverlapping(..)
119118
| StatementKind::Nop => {
120119
// safe (at least as emitted during MIR construction)
121120
}
@@ -124,6 +123,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
124123
UnsafetyViolationKind::General,
125124
UnsafetyViolationDetails::UseOfInlineAssembly,
126125
),
126+
StatementKind::CopyNonOverlapping(..) => unreachable!(),
127127
}
128128
self.super_statement(statement, location);
129129
}

compiler/rustc_mir/src/transform/lower_intrinsics.rs

+21
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
4040
terminator.kind = TerminatorKind::Goto { target };
4141
}
4242
}
43+
sym::copy_nonoverlapping => {
44+
let target = destination.unwrap().1;
45+
let mut args = args.drain(..);
46+
block.statements.push(Statement {
47+
source_info: terminator.source_info,
48+
kind: StatementKind::CopyNonOverlapping(
49+
box rustc_middle::mir::CopyNonOverlapping {
50+
src: args.next().unwrap(),
51+
dst: args.next().unwrap(),
52+
count: args.next().unwrap(),
53+
},
54+
),
55+
});
56+
assert_eq!(
57+
args.next(),
58+
None,
59+
"Extra argument for copy_non_overlapping intrinsic"
60+
);
61+
drop(args);
62+
terminator.kind = TerminatorKind::Goto { target };
63+
}
4364
sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
4465
if let Some((destination, target)) = *destination {
4566
let lhs;

compiler/rustc_mir/src/transform/remove_noop_landing_pads.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ impl RemoveNoopLandingPads {
3939
| StatementKind::StorageDead(_)
4040
| StatementKind::AscribeUserType(..)
4141
| StatementKind::Coverage(..)
42-
| StatementKind::CopyNonOverlapping(..)
4342
| StatementKind::Nop => {
4443
// These are all nops in a landing pad
4544
}
@@ -56,6 +55,7 @@ impl RemoveNoopLandingPads {
5655
StatementKind::Assign { .. }
5756
| StatementKind::SetDiscriminant { .. }
5857
| StatementKind::LlvmInlineAsm { .. }
58+
| StatementKind::CopyNonOverlapping(..)
5959
| StatementKind::Retag { .. } => {
6060
return false;
6161
}

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statemen
224224
check_operand(tcx, dst, span, body)?;
225225
check_operand(tcx, src, span, body)?;
226226
check_operand(tcx, count, span, body)
227-
},
227+
}
228228
// These are all NOPs
229229
StatementKind::StorageLive(_)
230230
| StatementKind::StorageDead(_)

0 commit comments

Comments
 (0)