Skip to content

Commit eac1ae7

Browse files
committed
Defer to llvm to deduplicate promote allocations
Between promote temps pass and gvn
1 parent 9fa040e commit eac1ae7

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,15 +1488,6 @@ impl<'tcx> VnState<'_, 'tcx> {
14881488

14891489
let op = self.evaluated[index].as_ref()?;
14901490

1491-
// Ignore promoted arrays. Promoted arrays are already placed in `.rodata`.
1492-
// Which is what we try to archive for running gvn on constant local arrays.
1493-
if let Either::Left(mplace) = op.as_mplace_or_imm()
1494-
&& mplace.layout.ty.is_array()
1495-
&& let Value::Projection(_index, ProjectionElem::Deref) = value
1496-
{
1497-
return None;
1498-
}
1499-
15001491
let value = op_to_prop_const(&mut self.ecx, op)?;
15011492

15021493
// Check that we do not leak a pointer.

tests/codegen/issue-73825-gvn-const-local-array.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// CHECK-NEXT: start:
77
// CHECK-NEXT: %_3 = and i64 %x, 63
88
// CHECK-NEXT: %0 = getelementptr inbounds [64 x i32], ptr @0, i64 0, i64 %_3
9-
// CHECK-NEXT: %_0 = load i32, ptr %0, align 4, !noundef !3
9+
// CHECK-NEXT: %_0 = load i32, ptr %0, align 4
1010
// CHECK-NEXT: ret i32 %_0
1111
#[no_mangle]
1212
#[rustfmt::skip]
@@ -23,3 +23,29 @@ pub fn foo(x: usize) -> i32 {
2323
];
2424
base[x % 64]
2525
}
26+
27+
// This checks whether LLVM de-duplicates `promoted` array and `base` array.
28+
// Because in MIR, `&[..]` is already promoted by promote pass. GVN keeps promoting
29+
// `*&[..]` to `const [..]` again.
30+
//
31+
// CHECK-LABEL: @deduplicability
32+
// CHECK-NEXT: start:
33+
// CHECK-NEXT: %_3 = and i64 %x, 63
34+
// CHECK-NEXT: %0 = getelementptr inbounds [64 x i32], ptr @0, i64 0, i64 %_3
35+
// CHECK-NEXT: %_0 = load i32, ptr %0, align 4
36+
// CHECK-NEXT: ret i32 %_0
37+
#[no_mangle]
38+
#[rustfmt::skip]
39+
pub fn deduplicability(x: usize) -> i32 {
40+
let promoted = *&[
41+
67i32, 754, 860, 559, 368, 870, 548, 972,
42+
141, 731, 351, 664, 32, 4, 996, 741,
43+
203, 292, 237, 480, 151, 940, 777, 540,
44+
143, 587, 747, 65, 152, 517, 882, 880,
45+
712, 595, 370, 901, 237, 53, 789, 785,
46+
912, 650, 896, 367, 316, 392, 62, 473,
47+
675, 691, 281, 192, 445, 970, 225, 425,
48+
628, 324, 322, 206, 912, 867, 462, 92
49+
];
50+
promoted[x % 64]
51+
}

tests/mir-opt/const_array_locals.main.GVN.diff

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
_17 = const main::promoted[0];
6060
_7 = &(*_17);
6161
- _6 = (*_7);
62-
+ _6 = (*_17);
62+
+ _6 = const [254_i32, 42_i32, 15_i32, 39_i32, 62_i32];
6363
StorageDead(_7);
6464
StorageLive(_9);
6565
StorageLive(_10);
@@ -122,6 +122,11 @@
122122
+
123123
+ ALLOC4 (size: 20, align: 4) {
124124
+ 0x00 │ ff 00 00 00 69 00 00 00 0f 00 00 00 27 00 00 00 │ ....i.......'...
125+
+ 0x10 │ 3e 00 00 00 │ >...
126+
+ }
127+
+
128+
+ ALLOC5 (size: 20, align: 4) {
129+
+ 0x00 │ fe 00 00 00 2a 00 00 00 0f 00 00 00 27 00 00 00 │ ....*.......'...
125130
+ 0x10 │ 3e 00 00 00 │ >...
126131
}
127132

tests/mir-opt/const_array_locals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn main() {
2121
// CHECK: [[_foo]] = [move [[subarray1]], move [[subarray2]]];
2222
let _foo = [[178, 9, 4, 56, 221], [193, 164, 194, 197, 6]];
2323
// CHECK: [[PROMOTED:_[0-9]+]] = const main::promoted[0];
24-
// CHECK: [[_darr]] = (*[[PROMOTED]]);
24+
// CHECK: [[_darr]] = const [254_i32, 42_i32, 15_i32, 39_i32, 62_i32];
2525
let _darr = *&[254, 42, 15, 39, 62];
2626

2727
// CHECK: [[ARG:_[0-9]+]] = const [31_u32, 96_u32, 173_u32, 50_u32, 1_u32];

0 commit comments

Comments
 (0)