Skip to content

Commit 8ef9233

Browse files
committed
Simplify align_of_val::<[T]>(…)align_of::<T>()
1 parent 185b074 commit 8ef9233

8 files changed

+68
-48
lines changed

compiler/rustc_mir_transform/src/instsimplify.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
5555

5656
let terminator = block.terminator.as_mut().unwrap();
5757
ctx.simplify_primitive_clone(terminator, &mut block.statements);
58+
ctx.simplify_align_of_slice_val(terminator, &mut block.statements);
5859
ctx.simplify_intrinsic_assert(terminator);
5960
ctx.simplify_nounwind_call(terminator);
6061
simplify_duplicate_switch_targets(terminator);
@@ -252,6 +253,36 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
252253
terminator.kind = TerminatorKind::Goto { target: *destination_block };
253254
}
254255

256+
// Convert `align_of_val::<[T]>(ptr)` to `align_of::<T>()`, since the
257+
// alignment of a slice doesn't actually depend on metadata at all
258+
// and the element type is always `Sized`.
259+
//
260+
// This is here so it can run after inlining, where it's more useful.
261+
// (LowerIntrinsics is done in cleanup, before the optimization passes.)
262+
fn simplify_align_of_slice_val(
263+
&self,
264+
terminator: &mut Terminator<'tcx>,
265+
statements: &mut Vec<Statement<'tcx>>,
266+
) {
267+
if let TerminatorKind::Call {
268+
func, args, destination, target: Some(destination_block), ..
269+
} = &terminator.kind
270+
&& args.len() == 1
271+
&& let Some((fn_def_id, generics)) = func.const_fn_def()
272+
&& self.tcx.is_intrinsic(fn_def_id, sym::align_of_val)
273+
&& let ty::Slice(elem_ty) = *generics.type_at(0).kind()
274+
{
275+
statements.push(Statement::new(
276+
terminator.source_info,
277+
StatementKind::Assign(Box::new((
278+
*destination,
279+
Rvalue::NullaryOp(NullOp::AlignOf, elem_ty),
280+
))),
281+
));
282+
terminator.kind = TerminatorKind::Goto { target: *destination_block };
283+
}
284+
}
285+
255286
fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) {
256287
let TerminatorKind::Call { ref func, ref mut unwind, .. } = terminator.kind else {
257288
return;

tests/mir-opt/instsimplify/align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
bb0: {
1010
StorageLive(_2);
1111
_2 = &raw const (*_1);
12-
_0 = std::intrinsics::align_of_val::<[T]>(move _2) -> [return: bb1, unwind unreachable];
12+
- _0 = std::intrinsics::align_of_val::<[T]>(move _2) -> [return: bb1, unwind unreachable];
13+
+ _0 = AlignOf(T);
14+
+ goto -> bb1;
1315
}
1416

1517
bb1: {

tests/mir-opt/instsimplify/align_of_slice.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// EMIT_MIR align_of_slice.of_val_slice.InstSimplify-after-simplifycfg.diff
88
pub fn of_val_slice<T>(slice: &[T]) -> usize {
99
// CHECK-LABEL: fn of_val_slice(_1: &[T])
10-
// CHECK: _2 = &raw const (*_1);
11-
// CHECK: _0 = std::intrinsics::align_of_val::<[T]>(move _2)
10+
// CHECK: _0 = AlignOf(T);
1211
unsafe { core::intrinsics::align_of_val(slice) }
1312
}

tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-abort.mir

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,41 +70,38 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
7070
_3 = copy _2 as *mut [T] (Transmute);
7171
_4 = copy _2 as *const [T] (Transmute);
7272
StorageLive(_6);
73-
_5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
73+
_5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
7474
}
7575

7676
bb1: {
77-
_6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
78-
}
79-
80-
bb2: {
77+
_6 = AlignOf(T);
8178
StorageLive(_7);
8279
_7 = copy _6 as std::ptr::Alignment (Transmute);
8380
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
8481
StorageDead(_7);
8582
StorageDead(_6);
8683
StorageDead(_4);
87-
switchInt(copy _5) -> [0: bb5, otherwise: bb3];
84+
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
8885
}
8986

90-
bb3: {
87+
bb2: {
9188
StorageLive(_9);
9289
_9 = copy _3 as *mut u8 (PtrToPtr);
9390
StorageLive(_11);
9491
StorageLive(_10);
9592
_10 = discriminant(_8);
9693
_11 = move _10 as usize (IntToInt);
9794
StorageDead(_10);
98-
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
95+
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
9996
}
10097

101-
bb4: {
98+
bb3: {
10299
StorageDead(_11);
103100
StorageDead(_9);
104-
goto -> bb5;
101+
goto -> bb4;
105102
}
106103

107-
bb5: {
104+
bb4: {
108105
StorageDead(_2);
109106
return;
110107
}

tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.32bit.panic-unwind.mir

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,41 +70,38 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
7070
_3 = copy _2 as *mut [T] (Transmute);
7171
_4 = copy _2 as *const [T] (Transmute);
7272
StorageLive(_6);
73-
_5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
73+
_5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
7474
}
7575

7676
bb1: {
77-
_6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
78-
}
79-
80-
bb2: {
77+
_6 = AlignOf(T);
8178
StorageLive(_7);
8279
_7 = copy _6 as std::ptr::Alignment (Transmute);
8380
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
8481
StorageDead(_7);
8582
StorageDead(_6);
8683
StorageDead(_4);
87-
switchInt(copy _5) -> [0: bb5, otherwise: bb3];
84+
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
8885
}
8986

90-
bb3: {
87+
bb2: {
9188
StorageLive(_9);
9289
_9 = copy _3 as *mut u8 (PtrToPtr);
9390
StorageLive(_11);
9491
StorageLive(_10);
9592
_10 = discriminant(_8);
9693
_11 = move _10 as usize (IntToInt);
9794
StorageDead(_10);
98-
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
95+
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
9996
}
10097

101-
bb4: {
98+
bb3: {
10299
StorageDead(_11);
103100
StorageDead(_9);
104-
goto -> bb5;
101+
goto -> bb4;
105102
}
106103

107-
bb5: {
104+
bb4: {
108105
StorageDead(_2);
109106
return;
110107
}

tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-abort.mir

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,41 +70,38 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
7070
_3 = copy _2 as *mut [T] (Transmute);
7171
_4 = copy _2 as *const [T] (Transmute);
7272
StorageLive(_6);
73-
_5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
73+
_5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
7474
}
7575

7676
bb1: {
77-
_6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
78-
}
79-
80-
bb2: {
77+
_6 = AlignOf(T);
8178
StorageLive(_7);
8279
_7 = copy _6 as std::ptr::Alignment (Transmute);
8380
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
8481
StorageDead(_7);
8582
StorageDead(_6);
8683
StorageDead(_4);
87-
switchInt(copy _5) -> [0: bb5, otherwise: bb3];
84+
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
8885
}
8986

90-
bb3: {
87+
bb2: {
9188
StorageLive(_9);
9289
_9 = copy _3 as *mut u8 (PtrToPtr);
9390
StorageLive(_11);
9491
StorageLive(_10);
9592
_10 = discriminant(_8);
9693
_11 = move _10 as usize (IntToInt);
9794
StorageDead(_10);
98-
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
95+
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
9996
}
10097

101-
bb4: {
98+
bb3: {
10299
StorageDead(_11);
103100
StorageDead(_9);
104-
goto -> bb5;
101+
goto -> bb4;
105102
}
106103

107-
bb5: {
104+
bb4: {
108105
StorageDead(_2);
109106
return;
110107
}

tests/mir-opt/pre-codegen/drop_boxed_slice.generic_in_place.PreCodegen.after.64bit.panic-unwind.mir

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,41 +70,38 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
7070
_3 = copy _2 as *mut [T] (Transmute);
7171
_4 = copy _2 as *const [T] (Transmute);
7272
StorageLive(_6);
73-
_5 = std::intrinsics::size_of_val::<[T]>(copy _4) -> [return: bb1, unwind unreachable];
73+
_5 = std::intrinsics::size_of_val::<[T]>(move _4) -> [return: bb1, unwind unreachable];
7474
}
7575

7676
bb1: {
77-
_6 = std::intrinsics::align_of_val::<[T]>(move _4) -> [return: bb2, unwind unreachable];
78-
}
79-
80-
bb2: {
77+
_6 = AlignOf(T);
8178
StorageLive(_7);
8279
_7 = copy _6 as std::ptr::Alignment (Transmute);
8380
_8 = move (_7.0: std::ptr::alignment::AlignmentEnum);
8481
StorageDead(_7);
8582
StorageDead(_6);
8683
StorageDead(_4);
87-
switchInt(copy _5) -> [0: bb5, otherwise: bb3];
84+
switchInt(copy _5) -> [0: bb4, otherwise: bb2];
8885
}
8986

90-
bb3: {
87+
bb2: {
9188
StorageLive(_9);
9289
_9 = copy _3 as *mut u8 (PtrToPtr);
9390
StorageLive(_11);
9491
StorageLive(_10);
9592
_10 = discriminant(_8);
9693
_11 = move _10 as usize (IntToInt);
9794
StorageDead(_10);
98-
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb4, unwind unreachable];
95+
_12 = alloc::alloc::__rust_dealloc(move _9, move _5, move _11) -> [return: bb3, unwind unreachable];
9996
}
10097

101-
bb4: {
98+
bb3: {
10299
StorageDead(_11);
103100
StorageDead(_9);
104-
goto -> bb5;
101+
goto -> bb4;
105102
}
106103

107-
bb5: {
104+
bb4: {
108105
StorageDead(_2);
109106
return;
110107
}

tests/mir-opt/pre-codegen/drop_boxed_slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub unsafe fn generic_in_place<T: Copy>(ptr: *mut Box<[T]>) {
99
// CHECK-LABEL: fn generic_in_place(_1: *mut Box<[T]>)
1010
// CHECK: (inlined <Box<[T]> as Drop>::drop)
1111
// CHECK: [[SIZE:_.+]] = std::intrinsics::size_of_val::<[T]>
12-
// CHECK: [[ALIGN:_.+]] = std::intrinsics::align_of_val::<[T]>
12+
// CHECK: [[ALIGN:_.+]] = AlignOf(T);
1313
// CHECK: [[B:_.+]] = copy [[ALIGN]] as std::ptr::Alignment (Transmute);
1414
// CHECK: [[C:_.+]] = move ([[B]].0: std::ptr::alignment::AlignmentEnum);
1515
// CHECK: [[D:_.+]] = discriminant([[C]]);

0 commit comments

Comments
 (0)