Skip to content

Commit 9d266bf

Browse files
committed
Enable GVN for AggregateKind::RawPtr
1 parent ee97564 commit 9d266bf

File tree

4 files changed

+117
-2
lines changed

4 files changed

+117
-2
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ enum AggregateTy<'tcx> {
176176
Array,
177177
Tuple,
178178
Def(DefId, ty::GenericArgsRef<'tcx>),
179+
/// The type of the pointer can't be determined from the operands,
180+
/// so we have to keep the full thing here.
181+
RawPtr(Ty<'tcx>),
179182
}
180183

181184
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -385,6 +388,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
385388
AggregateTy::Def(def_id, args) => {
386389
self.tcx.type_of(def_id).instantiate(self.tcx, args)
387390
}
391+
AggregateTy::RawPtr(ty) => ty,
388392
};
389393
let variant = if ty.is_enum() { Some(variant) } else { None };
390394
let ty = self.ecx.layout_of(ty).ok()?;
@@ -927,8 +931,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
927931
}
928932
// Do not track unions.
929933
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
930-
// FIXME: Do the extra work to GVN `from_raw_parts`
931-
AggregateKind::RawPtr(..) => return None,
934+
AggregateKind::RawPtr(pty, mtbl) => {
935+
assert_eq!(fields.len(), 2);
936+
let ty = Ty::new_ptr(self.tcx, pty, mtbl);
937+
(AggregateTy::RawPtr(ty), FIRST_VARIANT)
938+
}
932939
};
933940

934941
let fields: Option<Vec<_>> = fields

tests/mir-opt/gvn.rs

+12
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,16 @@ fn non_freeze<T: Copy>(x: T) {
781781
)
782782
}
783783

784+
// Check that we can const-prop into `from_raw_parts`
785+
fn slice_index(x: &[i32]) -> *const [i32] {
786+
// CHECK-LABEL: fn slice_index(
787+
// CHECK: _0 = *const [i32] from
788+
// CHECK-SAME: const 123_usize);
789+
let ptr = x.as_ptr();
790+
let len = 123;
791+
std::intrinsics::aggregate_raw_ptr(ptr, len)
792+
}
793+
784794
fn main() {
785795
subexpression_elimination(2, 4, 5);
786796
wrap_unwrap(5);
@@ -805,6 +815,7 @@ fn main() {
805815
wide_ptr_integer();
806816
borrowed(5);
807817
non_freeze(5);
818+
slice_index(&[1]);
808819
}
809820

810821
#[inline(never)]
@@ -838,3 +849,4 @@ fn identity<T>(x: T) -> T {
838849
// EMIT_MIR gvn.wide_ptr_integer.GVN.diff
839850
// EMIT_MIR gvn.borrowed.GVN.diff
840851
// EMIT_MIR gvn.non_freeze.GVN.diff
852+
// EMIT_MIR gvn.slice_index.GVN.diff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
- // MIR for `slice_index` before GVN
2+
+ // MIR for `slice_index` after GVN
3+
4+
fn slice_index(_1: &[i32]) -> *const [i32] {
5+
debug x => _1;
6+
let mut _0: *const [i32];
7+
let _2: *const i32;
8+
let mut _3: &[i32];
9+
let mut _5: *const i32;
10+
let mut _6: usize;
11+
scope 1 {
12+
debug ptr => _2;
13+
let _4: usize;
14+
scope 2 {
15+
debug len => _4;
16+
}
17+
}
18+
19+
bb0: {
20+
- StorageLive(_2);
21+
+ nop;
22+
StorageLive(_3);
23+
_3 = &(*_1);
24+
_2 = core::slice::<impl [i32]>::as_ptr(move _3) -> [return: bb1, unwind unreachable];
25+
}
26+
27+
bb1: {
28+
StorageDead(_3);
29+
- StorageLive(_4);
30+
+ nop;
31+
_4 = const 123_usize;
32+
StorageLive(_5);
33+
_5 = _2;
34+
StorageLive(_6);
35+
- _6 = _4;
36+
- _0 = *const [i32] from (move _5, move _6);
37+
+ _6 = const 123_usize;
38+
+ _0 = *const [i32] from (_2, const 123_usize);
39+
StorageDead(_6);
40+
StorageDead(_5);
41+
- StorageDead(_4);
42+
- StorageDead(_2);
43+
+ nop;
44+
+ nop;
45+
return;
46+
}
47+
}
48+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
- // MIR for `slice_index` before GVN
2+
+ // MIR for `slice_index` after GVN
3+
4+
fn slice_index(_1: &[i32]) -> *const [i32] {
5+
debug x => _1;
6+
let mut _0: *const [i32];
7+
let _2: *const i32;
8+
let mut _3: &[i32];
9+
let mut _5: *const i32;
10+
let mut _6: usize;
11+
scope 1 {
12+
debug ptr => _2;
13+
let _4: usize;
14+
scope 2 {
15+
debug len => _4;
16+
}
17+
}
18+
19+
bb0: {
20+
- StorageLive(_2);
21+
+ nop;
22+
StorageLive(_3);
23+
_3 = &(*_1);
24+
_2 = core::slice::<impl [i32]>::as_ptr(move _3) -> [return: bb1, unwind continue];
25+
}
26+
27+
bb1: {
28+
StorageDead(_3);
29+
- StorageLive(_4);
30+
+ nop;
31+
_4 = const 123_usize;
32+
StorageLive(_5);
33+
_5 = _2;
34+
StorageLive(_6);
35+
- _6 = _4;
36+
- _0 = *const [i32] from (move _5, move _6);
37+
+ _6 = const 123_usize;
38+
+ _0 = *const [i32] from (_2, const 123_usize);
39+
StorageDead(_6);
40+
StorageDead(_5);
41+
- StorageDead(_4);
42+
- StorageDead(_2);
43+
+ nop;
44+
+ nop;
45+
return;
46+
}
47+
}
48+

0 commit comments

Comments
 (0)