about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Wang <cbeuw.andy@gmail.com>2023-03-07 11:42:34 +0100
committerAndy Wang <cbeuw.andy@gmail.com>2023-03-07 11:42:34 +0100
commit7281cd0c215ef8005adfb83e13ff075df32a0ebd (patch)
treeb4565aefc74d8243635d50585c94eeab31e03012
parent5157d938c49af1248a21e7ed2fbc5c6f71963276 (diff)
downloadrust-7281cd0c215ef8005adfb83e13ff075df32a0ebd.tar.gz
rust-7281cd0c215ef8005adfb83e13ff075df32a0ebd.zip
Custom MIR: Support as casts
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs9
-rw-r--r--tests/mir-opt/building/custom/as_cast.float_to_int.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/as_cast.int_to_int.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/as_cast.int_to_ptr.built.after.mir10
-rw-r--r--tests/mir-opt/building/custom/as_cast.rs43
5 files changed, 81 insertions, 1 deletions
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 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
     }
 
     fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
-        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 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
             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());
+}