diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2021-07-19 15:23:20 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-07-19 15:23:20 +0200 |
| commit | c151bb4ac5b00ac57be421e7968be6b3a6c6e505 (patch) | |
| tree | 829dbef30ac96767d8b5fe3c1069ac936d339858 | |
| parent | bd2f72f398fa6b609a005cea8ebe16e093937936 (diff) | |
| parent | d7c3c45d685403e090d84956da9e4d1a82ca6666 (diff) | |
| download | rust-c151bb4ac5b00ac57be421e7968be6b3a6c6e505.tar.gz rust-c151bb4ac5b00ac57be421e7968be6b3a6c6e505.zip | |
Sync from rust 8df945c4717ffaf923b57bf30c473df6fc98bc85
| -rw-r--r-- | src/constant.rs | 21 | ||||
| -rw-r--r-- | src/intrinsics/mod.rs | 34 | ||||
| -rw-r--r-- | src/value_and_place.rs | 4 |
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())); |
