Skip to content

Commit 5eb6805

Browse files
Rollup merge of rust-lang#110190 - cbeuw:mir-offset, r=oli-obk
Custom MIR: Support `BinOp::Offset` Since offset doesn't have an infix operator, a new function `Offset` is added which is lowered to `Rvalue::BinaryOp(BinOp::Offset, ..)` r? `@oli-obk` or `@tmiasko` or `@JakobDegen`
2 parents d301576 + cecb901 commit 5eb6805

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+5
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
148148
)),
149149
)
150150
},
151+
@call("mir_offset", args) => {
152+
let ptr = self.parse_operand(args[0])?;
153+
let offset = self.parse_operand(args[1])?;
154+
Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
155+
},
151156
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
152157
ExprKind::Borrow { borrow_kind, arg } => Ok(
153158
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)

library/core/src/intrinsics/mir.rs

+2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@
232232
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
233233
//! - [`Discriminant`] and [`Len`] have associated functions.
234234
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
235+
//! - The binary operation `Offset` can be created via [`Offset`].
235236
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
236237
//! - Array repetition syntax (`[foo; 10]`) creates the associated rvalue.
237238
//!
@@ -289,6 +290,7 @@ define!(
289290
fn Discriminant<T>(place: T) -> <T as ::core::marker::DiscriminantKind>::Discriminant
290291
);
291292
define!("mir_set_discriminant", fn SetDiscriminant<T>(place: T, index: u32));
293+
define!("mir_offset", fn Offset<T, U>(ptr: T, count: U) -> T);
292294
define!(
293295
"mir_field",
294296
/// Access the field with the given index of some place.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// MIR for `raw_pointer_offset` after built
2+
3+
fn raw_pointer_offset(_1: *const i32) -> *const i32 {
4+
let mut _0: *const i32; // return place in scope 0 at $DIR/references.rs:+0:45: +0:55
5+
6+
bb0: {
7+
_0 = Offset(_1, const 1_isize); // scope 0 at $DIR/references.rs:+2:9: +2:33
8+
return; // scope 0 at $DIR/references.rs:+3:9: +3:17
9+
}
10+
}

tests/mir-opt/building/custom/references.rs

+11
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,22 @@ pub fn raw_pointer(x: *const i32) -> *const i32 {
4545
})
4646
}
4747

48+
// EMIT_MIR references.raw_pointer_offset.built.after.mir
49+
#[custom_mir(dialect = "built")]
50+
pub fn raw_pointer_offset(x: *const i32) -> *const i32 {
51+
mir!({
52+
RET = Offset(x, 1_isize);
53+
Return()
54+
})
55+
}
56+
4857
fn main() {
4958
let mut x = 5;
59+
let arr = [1, 2];
5060
assert_eq!(*mut_ref(&mut x), 5);
5161
assert_eq!(*immut_ref(&x), 5);
5262
unsafe {
5363
assert_eq!(*raw_pointer(addr_of!(x)), 5);
64+
assert_eq!(*raw_pointer_offset(addr_of!(arr[0])), 2);
5465
}
5566
}

0 commit comments

Comments
 (0)