mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-12 09:57:43 +00:00
Auto merge of #110822 - scottmcm:lower-offset-to-mir, r=compiler-errors
Lower `intrinsics::offset` to `mir::BinOp::Offset` They're [semantically the same](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.Rvalue.html#variant.BinaryOp), so this means the backends don't need to handle the intrinsic and means fewer MIR basic blocks in pointer arithmetic code.
This commit is contained in:
commit
9c044d77a3
@ -534,7 +534,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
|
||||
// The only difference between offset and arith_offset is regarding UB. Because Cranelift
|
||||
// doesn't have UB both are codegen'ed the same way
|
||||
sym::offset | sym::arith_offset => {
|
||||
sym::arith_offset => {
|
||||
intrinsic_args!(fx, args => (base, offset); intrinsic);
|
||||
let offset = offset.load_scalar(fx);
|
||||
|
||||
|
@ -135,13 +135,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
.unwrap();
|
||||
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
|
||||
}
|
||||
sym::offset => {
|
||||
let ty = substs.type_at(0);
|
||||
let layout = bx.layout_of(ty);
|
||||
let ptr = args[0].immediate();
|
||||
let offset = args[1].immediate();
|
||||
bx.inbounds_gep(bx.backend_type(layout), ptr, &[offset])
|
||||
}
|
||||
sym::arith_offset => {
|
||||
let ty = substs.type_at(0);
|
||||
let layout = bx.layout_of(ty);
|
||||
|
@ -559,11 +559,20 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
}
|
||||
|
||||
fn binary_ptr_op(
|
||||
_ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
_bin_op: mir::BinOp,
|
||||
_left: &ImmTy<'tcx>,
|
||||
_right: &ImmTy<'tcx>,
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
|
||||
if bin_op == mir::BinOp::Offset {
|
||||
let ptr = left.to_scalar().to_pointer(ecx)?;
|
||||
let offset_count = right.to_scalar().to_target_isize(ecx)?;
|
||||
let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
|
||||
let offset_ptr = ecx.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
|
||||
return Ok((Scalar::from_maybe_pointer(offset_ptr, ecx), false, left.layout.ty));
|
||||
}
|
||||
|
||||
throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
|
||||
}
|
||||
|
||||
|
@ -286,14 +286,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::write_bytes => {
|
||||
self.write_bytes_intrinsic(&args[0], &args[1], &args[2])?;
|
||||
}
|
||||
sym::offset => {
|
||||
let ptr = self.read_pointer(&args[0])?;
|
||||
let offset_count = self.read_target_isize(&args[1])?;
|
||||
let pointee_ty = substs.type_at(0);
|
||||
|
||||
let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
|
||||
self.write_pointer(offset_ptr, dest)?;
|
||||
}
|
||||
sym::arith_offset => {
|
||||
let ptr = self.read_pointer(&args[0])?;
|
||||
let offset_count = self.read_target_isize(&args[1])?;
|
||||
|
@ -192,6 +192,23 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
}
|
||||
sym::offset => {
|
||||
let target = target.unwrap();
|
||||
let Ok([ptr, delta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
|
||||
span_bug!(
|
||||
terminator.source_info.span,
|
||||
"Wrong number of arguments for offset intrinsic",
|
||||
);
|
||||
};
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, delta))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::option_payload_ptr => {
|
||||
if let (Some(target), Some(arg)) = (*target, args[0].place()) {
|
||||
let ty::RawPtr(ty::TypeAndMut { ty: dest_ty, .. }) =
|
||||
|
@ -0,0 +1,30 @@
|
||||
- // MIR for `ptr_offset` before LowerIntrinsics
|
||||
+ // MIR for `ptr_offset` after LowerIntrinsics
|
||||
|
||||
fn ptr_offset(_1: *const i32, _2: isize) -> *const i32 {
|
||||
debug p => _1; // in scope 0 at $DIR/lower_intrinsics.rs:+0:26: +0:27
|
||||
debug d => _2; // in scope 0 at $DIR/lower_intrinsics.rs:+0:41: +0:42
|
||||
let mut _0: *const i32; // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:54: +0:64
|
||||
let mut _3: *const i32; // in scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
|
||||
let mut _4: isize; // in scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
|
||||
_3 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
|
||||
StorageLive(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34
|
||||
_4 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:33: +1:34
|
||||
- _0 = offset::<i32>(move _3, move _4) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/lower_intrinsics.rs:140:5: 140:29
|
||||
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(*const i32, isize) -> *const i32 {offset::<i32>}, val: Value(<ZST>) }
|
||||
+ _0 = Offset(move _3, move _4); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35
|
||||
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:35
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35
|
||||
StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:+1:34: +1:35
|
||||
return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
|
||||
}
|
||||
}
|
||||
|
@ -134,3 +134,8 @@ pub fn option_payload(o: &Option<usize>, p: &Option<String>) {
|
||||
let _y = core::intrinsics::option_payload_ptr(p);
|
||||
}
|
||||
}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.ptr_offset.LowerIntrinsics.diff
|
||||
pub unsafe fn ptr_offset(p: *const i32, d: isize) -> *const i32 {
|
||||
core::intrinsics::offset(p, d)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user