From 23a1ebb3fca8dc77340dd94400255722260991e9 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 19 Jun 2019 15:58:51 +0200 Subject: [PATCH] Remove the `AllocId` from `ByRef` values `ByRef` const values have no identity beyond their value, we should not treat them as having identity. The `AllocId` often differed between equal constants, because of the way that the miri-engine evaluates constants. --- src/librustc/mir/interpret/value.rs | 5 ++--- src/librustc/ty/structural_impls.rs | 2 +- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_ssa/mir/operand.rs | 4 ++-- src/librustc_codegen_ssa/mir/place.rs | 4 ++-- src/librustc_mir/const_eval.rs | 6 +++--- src/librustc_mir/hair/pattern/_match.rs | 9 +++++---- src/librustc_mir/interpret/operand.rs | 5 +++-- src/test/incremental/simd_intrinsic_ice.rs | 17 +++++++++++++++++ 9 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 src/test/incremental/simd_intrinsic_ice.rs diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 40e8111997361..0f08c40bff1b2 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -43,14 +43,13 @@ pub enum ConstValue<'tcx> { end: usize, }, - /// An allocation together with a pointer into the allocation. - /// Invariant: the pointer's `AllocId` resolves to the allocation. + /// An allocation together with an offset into the allocation. /// The alignment exists to allow `const_field` to have `ByRef` access to nonprimitive fields /// of `repr(packed)` structs. The alignment may be lower than the type of this constant. /// This permits reads with lower alignment than what the type would normally require. /// FIXME(RalfJ,oli-obk): The alignment checks are part of miri, but const eval doesn't really /// need them. Disabling them may be too hard though. - ByRef(Pointer, Align, &'tcx Allocation), + ByRef(Size, Align, &'tcx Allocation), /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 4cd0fd3e824f5..22c178b9cb04d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1335,7 +1335,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { - ConstValue::ByRef(ptr, align, alloc) => ConstValue::ByRef(ptr, align, alloc), + ConstValue::ByRef(offset, align, alloc) => ConstValue::ByRef(offset, align, alloc), ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)), ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)), ConstValue::Placeholder(p) => ConstValue::Placeholder(p), diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 4bf91bbed60ea..3f10773f85b41 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -71,7 +71,7 @@ pub fn codegen_static_initializer( let static_ = cx.tcx.const_eval(param_env.and(cid))?; let alloc = match static_.val { - ConstValue::ByRef(ptr, align, alloc) if ptr.offset.bytes() == 0 && align == alloc.align => { + ConstValue::ByRef(offset, align, alloc) if offset.bytes() == 0 && align == alloc.align => { alloc }, _ => bug!("static const eval returned {:#?}", static_), diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index c1626d31c7801..dc288c2f0f343 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -109,8 +109,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) }, - ConstValue::ByRef(ptr, align, alloc) => { - return bx.load_operand(bx.from_const_alloc(layout, align, alloc, ptr.offset)); + ConstValue::ByRef(offset, align, alloc) => { + return bx.load_operand(bx.from_const_alloc(layout, align, alloc, offset)); }, }; diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 72aedb4812a21..4993f4559f777 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -424,8 +424,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = cx.layout_of(self.monomorphize(&ty)); match bx.tcx().const_eval(param_env.and(cid)) { Ok(val) => match val.val { - mir::interpret::ConstValue::ByRef(ptr, align, alloc) => { - bx.cx().from_const_alloc(layout, align, alloc, ptr.offset) + mir::interpret::ConstValue::ByRef(offset, align, alloc) => { + bx.cx().from_const_alloc(layout, align, alloc, offset) } _ => bug!("promoteds should have an allocation: {:?}", val), }, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 284a8f40e1f35..126f1a12f399c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -99,7 +99,7 @@ fn op_to_const<'tcx>( Ok(mplace) => { let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr, mplace.align, alloc) + ConstValue::ByRef(ptr.offset, mplace.align, alloc) }, // see comment on `let try_as_immediate` above Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { @@ -113,7 +113,7 @@ fn op_to_const<'tcx>( let mplace = op.to_mem_place(); let ptr = mplace.ptr.to_ptr().unwrap(); let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); - ConstValue::ByRef(ptr, mplace.align, alloc) + ConstValue::ByRef(ptr.offset, mplace.align, alloc) }, }, Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { @@ -542,7 +542,7 @@ fn validate_and_turn_into_const<'tcx>( let ptr = mplace.ptr.to_ptr()?; Ok(tcx.mk_const(ty::Const { val: ConstValue::ByRef( - ptr, + ptr.offset, mplace.align, ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ), diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 974c863792eed..6e3f8da4807a1 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -218,7 +218,7 @@ impl LiteralExpander<'tcx> { (ConstValue::Scalar(Scalar::Ptr(p)), x, y) if x == y => { let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id); ConstValue::ByRef( - p, + p.offset, // FIXME(oli-obk): this should be the type's layout alloc.align, alloc, @@ -1436,9 +1436,10 @@ fn slice_pat_covered_by_const<'tcx>( suffix: &[Pattern<'tcx>], ) -> Result { let data: &[u8] = match (const_val.val, &const_val.ty.sty) { - (ConstValue::ByRef(ptr, _, alloc), ty::Array(t, n)) => { + (ConstValue::ByRef(offset, _, alloc), ty::Array(t, n)) => { assert_eq!(*t, tcx.types.u8); let n = n.assert_usize(tcx).unwrap(); + let ptr = Pointer::new(AllocId(0), offset); alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap() }, (ConstValue::Slice { data, start, end }, ty::Slice(t)) => { @@ -1758,9 +1759,9 @@ fn specialize<'p, 'a: 'p, 'tcx>( let (alloc, offset, n, ty) = match value.ty.sty { ty::Array(t, n) => { match value.val { - ConstValue::ByRef(ptr, _, alloc) => ( + ConstValue::ByRef(offset, _, alloc) => ( alloc, - ptr.offset, + offset, n.unwrap_usize(cx.tcx), t, ), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 1b451e0b8f18f..96e9a416a72c7 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -538,10 +538,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> { self.layout_of(self.monomorphize(val.ty)?) })?; let op = match val.val { - ConstValue::ByRef(ptr, align, _alloc) => { + ConstValue::ByRef(offset, align, alloc) => { + let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. - let ptr = self.tag_static_base_pointer(ptr); + let ptr = self.tag_static_base_pointer(Pointer::new(id, offset)); Operand::Indirect(MemPlace::from_ptr(ptr, align)) }, ConstValue::Scalar(x) => diff --git a/src/test/incremental/simd_intrinsic_ice.rs b/src/test/incremental/simd_intrinsic_ice.rs new file mode 100644 index 0000000000000..06b2957ac62c9 --- /dev/null +++ b/src/test/incremental/simd_intrinsic_ice.rs @@ -0,0 +1,17 @@ +#![feature(repr_simd, platform_intrinsics)] + +// revisions:rpass1 rpass2 + +#[repr(simd)] +struct I32x2(i32, i32); + +extern "platform-intrinsic" { + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; +} + +fn main() { + unsafe { + let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]); + let _: I32x2 = simd_shuffle2(I32x2(1, 2), I32x2(3, 4), [0, 0]); + } +}