From 7281cd0c215ef8005adfb83e13ff075df32a0ebd Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Tue, 7 Mar 2023 11:42:34 +0100 Subject: [PATCH] Custom MIR: Support as casts --- .../src/build/custom/parse/instruction.rs | 9 +++- .../as_cast.float_to_int.built.after.mir | 10 +++++ .../custom/as_cast.int_to_int.built.after.mir | 10 +++++ .../custom/as_cast.int_to_ptr.built.after.mir | 10 +++++ tests/mir-opt/building/custom/as_cast.rs | 43 +++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/mir-opt/building/custom/as_cast.float_to_int.built.after.mir create mode 100644 tests/mir-opt/building/custom/as_cast.int_to_int.built.after.mir create mode 100644 tests/mir-opt/building/custom/as_cast.int_to_ptr.built.after.mir create mode 100644 tests/mir-opt/building/custom/as_cast.rs diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index dbba529aef7..09d2eb96d0f 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,5 +1,6 @@ use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::mir::tcx::PlaceTy; +use rustc_middle::ty::cast::mir_cast_kind; use rustc_middle::{mir::*, thir::*, ty}; use rustc_span::Span; use rustc_target::abi::VariantIdx; @@ -142,7 +143,7 @@ fn parse_call( } fn parse_rvalue(&self, expr_id: ExprId) -> PResult> { - parse_by_kind!(self, expr_id, _, "rvalue", + parse_by_kind!(self, expr_id, expr, "rvalue", @call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant), @call("mir_checked", args) => { parse_by_kind!(self, args[0], _, "binary op", @@ -167,6 +168,12 @@ fn parse_rvalue(&self, expr_id: ExprId) -> PResult> { ExprKind::Repeat { value, count } => Ok( Rvalue::Repeat(self.parse_operand(*value)?, *count) ), + ExprKind::Cast { source } => { + let source = self.parse_operand(*source)?; + let source_ty = source.ty(self.body.local_decls(), self.tcx); + let cast_kind = mir_cast_kind(source_ty, expr.ty); + Ok(Rvalue::Cast(cast_kind, source, expr.ty)) + }, _ => self.parse_operand(expr_id).map(Rvalue::Use), ) } diff --git a/tests/mir-opt/building/custom/as_cast.float_to_int.built.after.mir b/tests/mir-opt/building/custom/as_cast.float_to_int.built.after.mir new file mode 100644 index 00000000000..d0b770783c1 --- /dev/null +++ b/tests/mir-opt/building/custom/as_cast.float_to_int.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `float_to_int` after built + +fn float_to_int(_1: f32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/as_cast.rs:+0:28: +0:31 + + bb0: { + _0 = _1 as i32 (FloatToInt); // scope 0 at $DIR/as_cast.rs:+3:13: +3:27 + return; // scope 0 at $DIR/as_cast.rs:+4:13: +4:21 + } +} diff --git a/tests/mir-opt/building/custom/as_cast.int_to_int.built.after.mir b/tests/mir-opt/building/custom/as_cast.int_to_int.built.after.mir new file mode 100644 index 00000000000..aaebff0d767 --- /dev/null +++ b/tests/mir-opt/building/custom/as_cast.int_to_int.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `int_to_int` after built + +fn int_to_int(_1: u32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/as_cast.rs:+0:26: +0:29 + + bb0: { + _0 = _1 as i32 (IntToInt); // scope 0 at $DIR/as_cast.rs:+3:13: +3:27 + return; // scope 0 at $DIR/as_cast.rs:+4:13: +4:21 + } +} diff --git a/tests/mir-opt/building/custom/as_cast.int_to_ptr.built.after.mir b/tests/mir-opt/building/custom/as_cast.int_to_ptr.built.after.mir new file mode 100644 index 00000000000..f040cf53df4 --- /dev/null +++ b/tests/mir-opt/building/custom/as_cast.int_to_ptr.built.after.mir @@ -0,0 +1,10 @@ +// MIR for `int_to_ptr` after built + +fn int_to_ptr(_1: usize) -> *const i32 { + let mut _0: *const i32; // return place in scope 0 at $DIR/as_cast.rs:+0:28: +0:38 + + bb0: { + _0 = _1 as *const i32 (PointerFromExposedAddress); // scope 0 at $DIR/as_cast.rs:+3:13: +3:34 + return; // scope 0 at $DIR/as_cast.rs:+4:13: +4:21 + } +} diff --git a/tests/mir-opt/building/custom/as_cast.rs b/tests/mir-opt/building/custom/as_cast.rs new file mode 100644 index 00000000000..b4b5ac6aa3b --- /dev/null +++ b/tests/mir-opt/building/custom/as_cast.rs @@ -0,0 +1,43 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR as_cast.int_to_int.built.after.mir +#[custom_mir(dialect = "built")] +fn int_to_int(x: u32) -> i32 { + mir!( + { + RET = x as i32; + Return() + } + ) +} + +// EMIT_MIR as_cast.float_to_int.built.after.mir +#[custom_mir(dialect = "built")] +fn float_to_int(x: f32) -> i32 { + mir!( + { + RET = x as i32; + Return() + } + ) +} + +// EMIT_MIR as_cast.int_to_ptr.built.after.mir +#[custom_mir(dialect = "built")] +fn int_to_ptr(x: usize) -> *const i32 { + mir!( + { + RET = x as *const i32; + Return() + } + ) +} + +fn main() { + assert_eq!(int_to_int(5), 5); + assert_eq!(float_to_int(5.), 5); + assert_eq!(int_to_ptr(0), std::ptr::null()); +}