about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-07-27 23:39:06 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2025-07-28 23:19:06 -0700
commit8ef9233339c09d80e12b31c523082b94d9e09b44 (patch)
treede4b892690452f1491ae5ec32dd5f2d7d0c96fa6
parent185b0745180e6f6f3a4c9c7a41ec8725749cf5bd (diff)
downloadrust-8ef9233339c09d80e12b31c523082b94d9e09b44.tar.gz
rust-8ef9233339c09d80e12b31c523082b94d9e09b44.zip
Simplify `align_of_val::<[T]>(…)` → `align_of::<T>()`
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs31
-rw-r--r--tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff4
-rw-r--r--tests/mir-opt/instsimplify/align_of_slice.rs3
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir19
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir19
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir19
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir19
-rw-r--r--tests/mir-opt/pre-codegen/drop_boxed_slice.rs2
8 files changed, 68 insertions, 48 deletions
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index dbcaed20953..c83bd25c663 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -55,6 +55,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
 
             let terminator = block.terminator.as_mut().unwrap();
             ctx.simplify_primitive_clone(terminator, &mut block.statements);
+            ctx.simplify_align_of_slice_val(terminator, &mut block.statements);
             ctx.simplify_intrinsic_assert(terminator);
             ctx.simplify_nounwind_call(terminator);
             simplify_duplicate_switch_targets(terminator);
@@ -252,6 +253,36 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
         terminator.kind = TerminatorKind::Goto { target: *destination_block };
     }
 
+    // Convert `align_of_val::<[T]>(ptr)` to `align_of::<T>()`, since the
+    // alignment of a slice doesn't actually depend on metadata at all
+    // and the element type is always `Sized`.
+    //
+    // This is here so it can run after inlining, where it's more useful.
+    // (LowerIntrinsics is done in cleanup, before the optimization passes.)
+    fn simplify_align_of_slice_val(
+        &self,
+        terminator: &mut Terminator<'tcx>,
+        statements: &mut Vec<Statement<'tcx>>,
+    ) {
+        if let TerminatorKind::Call {
+            func, args, destination, target: Some(destination_block), ..
+        } = &terminator.kind
+            && args.len() == 1
+            && let Some((fn_def_id, generics)) = func.const_fn_def()
+            && self.tcx.is_intrinsic(fn_def_id, sym::align_of_val)
+            && let ty::Slice(elem_ty) = *generics.type_at(0).kind()
+        {
+            statements.push(Statement::new(
+                terminator.source_info,
+                StatementKind::Assign(Box::new((
+                    *destination,
+                    Rvalue::NullaryOp(NullOp::AlignOf, elem_ty),
+                ))),
+            ));
+            terminator.kind = TerminatorKind::Goto { target: *destination_block };
+        }
+    }
+
     fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) {
         let TerminatorKind::Call { ref func, ref mut unwind, .. } = terminator.kind else {
             return;
diff --git a/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff b/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff
index 21ba2e25056..042e19bf2aa 100644
--- a/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff
+++ b/tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff
@@ -9,7 +9,9 @@
       bb0: {
           StorageLive(_2);
           _2 = &raw const (*_1);
-          _0 = std::intrinsics::align_of_val::<[T]>(move _2) -> [return: bb1, unwind unreachable];
+-         _0 = std::intrinsics::align_of_val::<[T]>(move _2) -> [return: bb1, unwind unreachable];
++         _0 = AlignOf(T);
++         goto -> bb1;
       }
   
       bb1: {
diff --git a/tests/mir-opt/instsimplify/align_of_slice.rs b/tests/mir-opt/instsimplify/align_of_slice.rs
index 900a05c2a8b..0af05cb6b0b 100644
--- a/tests/mir-opt/instsimplify/align_of_slice.rs
+++ b/tests/mir-opt/instsimplify/align_of_slice.rs
@@ -7,7 +7,6 @@
 // EMIT_MIR align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff
 pub fn of_val_slice<T>(slice: &[T]) -> usize {
     // CHECK-LABEL: fn of_val_slice(_1: &[T])
-    // CHECK: _2 = &raw const (*_1);
-    // CHECK: _0 = std::intrinsics::align_of_val::<[T]>(move _2)
+    // CHECK: _0 = AlignOf(T);
     unsafe { core::intrinsics::align_of_val(slice) }
 }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
index 587e69154ea..2777bba893b 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir
@@ -70,24 +70,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _3 = copy _2 as *mut [T] (Transmute);
         _4 = copy _2 as *const [T] (Transmute);
         StorageLive(_6);
-        _5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
+        _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        _6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
-    }
-
-    bb2: {
+        _6 = AlignOf(T);
         StorageLive(_7);
         _7 = copy _6 as std::ptr::Alignment (Transmute);
         _8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
-        switchInt(copy _5) -> [0: bb5, otherwise: bb3];
+        switchInt(copy _5) -> [0: bb4, otherwise: bb2];
     }
 
-    bb3: {
+    bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
         StorageLive(_11);
@@ -95,16 +92,16 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _10 = discriminant(_8);
         _11 = move _10 as usize (IntToInt);
         StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
+        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_11);
         StorageDead(_9);
-        goto -> bb5;
+        goto -> bb4;
     }
 
-    bb5: {
+    bb4: {
         StorageDead(_2);
         return;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
index 587e69154ea..2777bba893b 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir
@@ -70,24 +70,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _3 = copy _2 as *mut [T] (Transmute);
         _4 = copy _2 as *const [T] (Transmute);
         StorageLive(_6);
-        _5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
+        _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        _6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
-    }
-
-    bb2: {
+        _6 = AlignOf(T);
         StorageLive(_7);
         _7 = copy _6 as std::ptr::Alignment (Transmute);
         _8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
-        switchInt(copy _5) -> [0: bb5, otherwise: bb3];
+        switchInt(copy _5) -> [0: bb4, otherwise: bb2];
     }
 
-    bb3: {
+    bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
         StorageLive(_11);
@@ -95,16 +92,16 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _10 = discriminant(_8);
         _11 = move _10 as usize (IntToInt);
         StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
+        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_11);
         StorageDead(_9);
-        goto -> bb5;
+        goto -> bb4;
     }
 
-    bb5: {
+    bb4: {
         StorageDead(_2);
         return;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
index e88f6b394fa..2be0a478c85 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir
@@ -70,24 +70,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _3 = copy _2 as *mut [T] (Transmute);
         _4 = copy _2 as *const [T] (Transmute);
         StorageLive(_6);
-        _5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
+        _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        _6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
-    }
-
-    bb2: {
+        _6 = AlignOf(T);
         StorageLive(_7);
         _7 = copy _6 as std::ptr::Alignment (Transmute);
         _8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
-        switchInt(copy _5) -> [0: bb5, otherwise: bb3];
+        switchInt(copy _5) -> [0: bb4, otherwise: bb2];
     }
 
-    bb3: {
+    bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
         StorageLive(_11);
@@ -95,16 +92,16 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _10 = discriminant(_8);
         _11 = move _10 as usize (IntToInt);
         StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
+        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_11);
         StorageDead(_9);
-        goto -> bb5;
+        goto -> bb4;
     }
 
-    bb5: {
+    bb4: {
         StorageDead(_2);
         return;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
index e88f6b394fa..2be0a478c85 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir
@@ -70,24 +70,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _3 = copy _2 as *mut [T] (Transmute);
         _4 = copy _2 as *const [T] (Transmute);
         StorageLive(_6);
-        _5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
+        _5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
     }
 
     bb1: {
-        _6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
-    }
-
-    bb2: {
+        _6 = AlignOf(T);
         StorageLive(_7);
         _7 = copy _6 as std::ptr::Alignment (Transmute);
         _8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_4);
-        switchInt(copy _5) -> [0: bb5, otherwise: bb3];
+        switchInt(copy _5) -> [0: bb4, otherwise: bb2];
     }
 
-    bb3: {
+    bb2: {
         StorageLive(_9);
         _9 = copy _3 as *mut u8 (PtrToPtr);
         StorageLive(_11);
@@ -95,16 +92,16 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
         _10 = discriminant(_8);
         _11 = move _10 as usize (IntToInt);
         StorageDead(_10);
-        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
+        _12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_11);
         StorageDead(_9);
-        goto -> bb5;
+        goto -> bb4;
     }
 
-    bb5: {
+    bb4: {
         StorageDead(_2);
         return;
     }
diff --git a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
index e625a440d20..11fb7afef0f 100644
--- a/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
+++ b/tests/mir-opt/pre-codegen/drop_boxed_slice.rs
@@ -9,7 +9,7 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) {
     // CHECK-LABEL: fn generic_in_place(_1: *mut Box<[T]>)
     // CHECK: (inlined <Box<[T]> as Drop>::drop)
     // CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]>
-    // CHECK: [[ALIGN:_.+]] = std::intrinsics::align_of_val::<[T]>
+    // CHECK: [[ALIGN:_.+]] = AlignOf(T);
     // CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute);
     // CHECK: [[C:_.+]] = move ([[B]].0: std::ptr::alignment::AlignmentEnum);
     // CHECK: [[D:_.+]] = discriminant([[C]]);