File tree 2 files changed +104
-0
lines changed
2 files changed +104
-0
lines changed Original file line number Diff line number Diff line change
1
+ - // MIR for `foo` before GVN
2
+ + // MIR for `foo` after GVN
3
+
4
+ fn foo(_1: &mut Option<i32>) -> Option<i32> {
5
+ debug v => _1;
6
+ let mut _0: std::option::Option<i32>;
7
+ let mut _2: &std::option::Option<i32>;
8
+ let mut _3: &std::option::Option<i32>;
9
+ let _4: &&mut std::option::Option<i32>;
10
+ let mut _5: isize;
11
+ let mut _7: !;
12
+ let mut _8: std::option::Option<i32>;
13
+ let mut _9: i32;
14
+ let mut _10: !;
15
+ let mut _11: &mut std::option::Option<i32>;
16
+ scope 1 {
17
+ debug col => _6;
18
+ let _6: i32;
19
+ }
20
+
21
+ bb0: {
22
+ - StorageLive(_2);
23
+ + nop;
24
+ StorageLive(_3);
25
+ StorageLive(_4);
26
+ _4 = &_1;
27
+ - _11 = deref_copy (*_4);
28
+ - _3 = &(*_11);
29
+ + _11 = copy _1;
30
+ + _3 = &(*_1);
31
+ _2 = get(move _3) -> [return: bb1, unwind unreachable];
32
+ }
33
+
34
+ bb1: {
35
+ StorageDead(_3);
36
+ _5 = discriminant((*_2));
37
+ switchInt(move _5) -> [1: bb2, otherwise: bb3];
38
+ }
39
+
40
+ bb2: {
41
+ - StorageLive(_6);
42
+ + nop;
43
+ _6 = copy (((*_2) as Some).0: i32);
44
+ StorageLive(_8);
45
+ - _8 = Option::<i32>::None;
46
+ - (*_1) = move _8;
47
+ + _8 = const Option::<i32>::None;
48
+ + (*_1) = const Option::<i32>::None;
49
+ StorageDead(_8);
50
+ StorageLive(_9);
51
+ _9 = copy _6;
52
+ - _0 = Option::<i32>::Some(move _9);
53
+ + _0 = copy (*_2);
54
+ StorageDead(_9);
55
+ - StorageDead(_6);
56
+ + nop;
57
+ StorageDead(_4);
58
+ - StorageDead(_2);
59
+ + nop;
60
+ return;
61
+ }
62
+
63
+ bb3: {
64
+ StorageLive(_10);
65
+ unreachable;
66
+ }
67
+ + }
68
+ +
69
+ + ALLOC0 (size: 8, align: 4) {
70
+ + 00 00 00 00 __ __ __ __ │ ....░░░░
71
+ }
72
+
Original file line number Diff line number Diff line change
1
+ //! The `simplify_aggregate_to_copy` mir-opt introduced in
2
+ //! <https://github.com/rust-lang/rust/pull/128299> caused a miscompile because the initial
3
+ //! implementation
4
+ //!
5
+ //! > introduce[d] new dereferences without checking for aliasing
6
+ //!
7
+ //! This test demonstrates the behavior, and should be adjusted or removed when fixing and relanding
8
+ //! the mir-opt.
9
+ #![ crate_type = "lib" ]
10
+ // skip-filecheck
11
+ //@ compile-flags: -O -Zunsound-mir-opts
12
+ //@ test-mir-pass: GVN
13
+ #![ allow( internal_features) ]
14
+ #![ feature( rustc_attrs, core_intrinsics) ]
15
+
16
+ // EMIT_MIR simplify_aggregate_to_copy_miscompile.foo.GVN.diff
17
+ #[ no_mangle]
18
+ fn foo ( v : & mut Option < i32 > ) -> Option < i32 > {
19
+ if let & Some ( col) = get ( & v) {
20
+ * v = None ;
21
+ return Some ( col) ;
22
+ } else {
23
+ unsafe { std:: intrinsics:: unreachable ( ) }
24
+ }
25
+ }
26
+
27
+ #[ no_mangle]
28
+ #[ inline( never) ]
29
+ #[ rustc_nounwind]
30
+ fn get ( v : & Option < i32 > ) -> & Option < i32 > {
31
+ v
32
+ }
You can’t perform that action at this time.
0 commit comments