about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-07-19 15:23:20 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2021-07-19 15:23:20 +0200
commitc151bb4ac5b00ac57be421e7968be6b3a6c6e505 (patch)
tree829dbef30ac96767d8b5fe3c1069ac936d339858
parentbd2f72f398fa6b609a005cea8ebe16e093937936 (diff)
parentd7c3c45d685403e090d84956da9e4d1a82ca6666 (diff)
downloadrust-c151bb4ac5b00ac57be421e7968be6b3a6c6e505.tar.gz
rust-c151bb4ac5b00ac57be421e7968be6b3a6c6e505.zip
Sync from rust 8df945c4717ffaf923b57bf30c473df6fc98bc85
-rw-r--r--src/constant.rs21
-rw-r--r--src/intrinsics/mod.rs34
-rw-r--r--src/value_and_place.rs4
3 files changed, 49 insertions, 10 deletions
diff --git a/src/constant.rs b/src/constant.rs
index 481ba38f74d..37ba55d8ef5 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -193,20 +193,21 @@ pub(crate) fn codegen_const_value<'tcx>(
                     place.to_cvalue(fx)
                 }
             }
-            Scalar::Ptr(ptr) => {
-                let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
+            Scalar::Ptr(ptr, _size) => {
+                let (alloc_id, offset) = ptr.into_parts(); // we know the `offset` is relative
+                let alloc_kind = fx.tcx.get_global_alloc(alloc_id);
                 let base_addr = match alloc_kind {
                     Some(GlobalAlloc::Memory(alloc)) => {
                         let data_id = data_id_for_alloc_id(
                             &mut fx.constants_cx,
                             fx.module,
-                            ptr.alloc_id,
+                            alloc_id,
                             alloc.mutability,
                         );
                         let local_data_id =
                             fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
                         if fx.clif_comments.enabled() {
-                            fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
+                            fx.add_comment(local_data_id, format!("{:?}", alloc_id));
                         }
                         fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
                     }
@@ -226,10 +227,10 @@ pub(crate) fn codegen_const_value<'tcx>(
                         }
                         fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
                     }
-                    None => bug!("missing allocation {:?}", ptr.alloc_id),
+                    None => bug!("missing allocation {:?}", alloc_id),
                 };
-                let val = if ptr.offset.bytes() != 0 {
-                    fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
+                let val = if offset.bytes() != 0 {
+                    fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap())
                 } else {
                     base_addr
                 };
@@ -406,7 +407,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
         let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
         data_ctx.define(bytes.into_boxed_slice());
 
-        for &(offset, (_tag, reloc)) in alloc.relocations().iter() {
+        for &(offset, alloc_id) in alloc.relocations().iter() {
             let addend = {
                 let endianness = tcx.data_layout.endian;
                 let offset = offset.bytes() as usize;
@@ -417,7 +418,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                 read_target_uint(endianness, bytes).unwrap()
             };
 
-            let reloc_target_alloc = tcx.get_global_alloc(reloc).unwrap();
+            let reloc_target_alloc = tcx.get_global_alloc(alloc_id).unwrap();
             let data_id = match reloc_target_alloc {
                 GlobalAlloc::Function(instance) => {
                     assert_eq!(addend, 0);
@@ -427,7 +428,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                     continue;
                 }
                 GlobalAlloc::Memory(target_alloc) => {
-                    data_id_for_alloc_id(cx, module, reloc, target_alloc.mutability)
+                    data_id_for_alloc_id(cx, module, alloc_id, target_alloc.mutability)
                 }
                 GlobalAlloc::Static(def_id) => {
                     if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs
index 52896fc7127..3979886e10c 100644
--- a/src/intrinsics/mod.rs
+++ b/src/intrinsics/mod.rs
@@ -1115,6 +1115,40 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
             );
             ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
         };
+
+        raw_eq, <T>(v lhs_ref, v rhs_ref) {
+            fn type_by_size(size: Size) -> Option<Type> {
+                Type::int(size.bits().try_into().ok()?)
+            }
+
+            let size = fx.layout_of(T).layout.size;
+            let is_eq_value =
+                if size == Size::ZERO {
+                    // No bytes means they're trivially equal
+                    fx.bcx.ins().iconst(types::I8, 1)
+                } else if let Some(clty) = type_by_size(size) {
+                    // Can't use `trusted` for these loads; they could be unaligned.
+                    let mut flags = MemFlags::new();
+                    flags.set_notrap();
+                    let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
+                    let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
+                    let eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val);
+                    fx.bcx.ins().bint(types::I8, eq)
+                } else {
+                    // Just call `memcmp` (like slices do in core) when the
+                    // size is too large or it's not a power-of-two.
+                    let ptr_ty = pointer_ty(fx.tcx);
+                    let signed_bytes = i64::try_from(size.bytes()).unwrap();
+                    let bytes_val = fx.bcx.ins().iconst(ptr_ty, signed_bytes);
+                    let params = vec![AbiParam::new(ptr_ty); 3];
+                    let returns = vec![AbiParam::new(types::I32)];
+                    let args = &[lhs_ref, rhs_ref, bytes_val];
+                    let cmp = fx.lib_call("memcmp", params, returns, args)[0];
+                    let eq = fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0);
+                    fx.bcx.ins().bint(types::I8, eq)
+                };
+            ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
+        };
     }
 
     if let Some((_, dest)) = destination {
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 171f39805f8..ae8ccc626b4 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -453,6 +453,10 @@ impl<'tcx> CPlace<'tcx> {
                     ptr.store(fx, data, MemFlags::trusted());
                     ptr.load(fx, dst_ty, MemFlags::trusted())
                 }
+
+                // `CValue`s should never contain SSA-only types, so if you ended
+                // up here having seen an error like `B1 -> I8`, then before
+                // calling `write_cvalue` you need to add a `bint` instruction.
                 _ => unreachable!("write_cvalue_transmute: {:?} -> {:?}", src_ty, dst_ty),
             };
             //fx.bcx.set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index()));