From 304b4ad8b9899584c7b981dee3b72017ca101a3e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 17 Dec 2023 22:30:20 +0000 Subject: [PATCH] Compute unsizing casts in GVN. --- compiler/rustc_const_eval/src/interpret/cast.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 10 ++++++++++ .../slice_len.main.GVN.32bit.panic-abort.diff | 9 +++++---- .../slice_len.main.GVN.32bit.panic-unwind.diff | 9 +++++---- .../slice_len.main.GVN.64bit.panic-abort.diff | 9 +++++---- .../slice_len.main.GVN.64bit.panic-unwind.diff | 9 +++++---- tests/mir-opt/const_prop/slice_len.rs | 6 ++---- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 0cb5c634b22..6d470ff162e 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -415,7 +415,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - fn unsize_into( + pub fn unsize_into( &mut self, src: &OpTy<'tcx, M::Provenance>, cast_ty: TyAndLayout<'tcx>, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 3e8e454fcaa..0ef3cdbb337 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -551,6 +551,16 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } value.offset(Size::ZERO, to, &self.ecx).ok()? } + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) => { + let src = self.evaluated[value].as_ref()?; + let to = self.ecx.layout_of(to).ok()?; + let dest = self.ecx.allocate(to, MemoryKind::Stack).ok()?; + self.ecx.unsize_into(src, to, &dest.clone().into()).ok()?; + self.ecx + .alloc_mark_immutable(dest.ptr().provenance.unwrap().alloc_id()) + .ok()?; + dest.into() + } _ => return None, }, }; diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff index 803be994d9a..5c21c628f85 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff @@ -31,16 +31,17 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; - _7 = Len((*_2)); +- _7 = Len((*_2)); - _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; -+ _8 = Lt(const 1_usize, _7); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _1 = (*_2)[_6]; -+ _1 = (*_2)[1 of 2]; ++ _1 = const 2_u32; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff index 2a20e3eca59..470cd9c9d8f 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff @@ -31,16 +31,17 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; - _7 = Len((*_2)); +- _7 = Len((*_2)); - _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue]; -+ _8 = Lt(const 1_usize, _7); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { - _1 = (*_2)[_6]; -+ _1 = (*_2)[1 of 2]; ++ _1 = const 2_u32; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff index 803be994d9a..5c21c628f85 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff @@ -31,16 +31,17 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; - _7 = Len((*_2)); +- _7 = Len((*_2)); - _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind unreachable]; -+ _8 = Lt(const 1_usize, _7); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; } bb1: { - _1 = (*_2)[_6]; -+ _1 = (*_2)[1 of 2]; ++ _1 = const 2_u32; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff index 2a20e3eca59..470cd9c9d8f 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff @@ -31,16 +31,17 @@ StorageDead(_3); StorageLive(_6); _6 = const 1_usize; - _7 = Len((*_2)); +- _7 = Len((*_2)); - _8 = Lt(_6, _7); - assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> [success: bb1, unwind continue]; -+ _8 = Lt(const 1_usize, _7); -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; } bb1: { - _1 = (*_2)[_6]; -+ _1 = (*_2)[1 of 2]; ++ _1 = const 2_u32; StorageDead(_6); StorageDead(_4); StorageDead(_2); diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs index 79cd926df21..a4973c099cd 100644 --- a/tests/mir-opt/const_prop/slice_len.rs +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -8,9 +8,7 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: debug a => [[a:_.*]]; // CHECK: [[slice:_.*]] = const {{.*}} as &[u32] (PointerCoercion(Unsize)); - // FIXME(cjgillot) simplify Len and projection into unsized slice. - // CHECK-NOT: assert(const true, - // CHECK: [[a]] = (*[[slice]])[1 of 2]; - // CHECK-NOT: [[a]] = const 2_u32; + // CHECK: assert(const true, + // CHECK: [[a]] = const 2_u32; let a = (&[1u32, 2, 3] as &[u32])[1]; }