diff options
Diffstat (limited to 'compiler')
5 files changed, 31 insertions, 20 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 03f2a65fcca..90b36c61114 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -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); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 7af7fc92dbc..1479242f23a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -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); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 814b67b46ec..bfca58a15b3 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -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"); } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index eada75ae391..a77c699c22f 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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])?; diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index c7d3f6c9f04..62b727674c5 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -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, .. }) = |
