Skip to content

Commit 38b55dc

Browse files
committed
Add tests.
1 parent 6ed9f8f commit 38b55dc

15 files changed

+453
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
- // MIR for `foo` before CopyProp
2+
+ // MIR for `foo` after CopyProp
3+
4+
fn foo() -> i32 {
5+
let mut _0: i32; // return place in scope 0 at $DIR/branch.rs:+0:13: +0:16
6+
let _1: i32; // in scope 0 at $DIR/branch.rs:+1:9: +1:10
7+
let mut _3: bool; // in scope 0 at $DIR/branch.rs:+3:16: +3:22
8+
let _4: i32; // in scope 0 at $DIR/branch.rs:+6:9: +6:14
9+
scope 1 {
10+
debug x => _1; // in scope 1 at $DIR/branch.rs:+1:9: +1:10
11+
let _2: i32; // in scope 1 at $DIR/branch.rs:+3:9: +3:10
12+
scope 2 {
13+
debug y => _2; // in scope 2 at $DIR/branch.rs:+3:9: +3:10
14+
}
15+
}
16+
17+
bb0: {
18+
StorageLive(_1); // scope 0 at $DIR/branch.rs:+1:9: +1:10
19+
_1 = val() -> bb1; // scope 0 at $DIR/branch.rs:+1:13: +1:18
20+
// mir::Constant
21+
// + span: $DIR/branch.rs:13:13: 13:16
22+
// + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
23+
}
24+
25+
bb1: {
26+
StorageLive(_2); // scope 1 at $DIR/branch.rs:+3:9: +3:10
27+
StorageLive(_3); // scope 1 at $DIR/branch.rs:+3:16: +3:22
28+
_3 = cond() -> bb2; // scope 1 at $DIR/branch.rs:+3:16: +3:22
29+
// mir::Constant
30+
// + span: $DIR/branch.rs:15:16: 15:20
31+
// + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) }
32+
}
33+
34+
bb2: {
35+
switchInt(move _3) -> [0: bb4, otherwise: bb3]; // scope 1 at $DIR/branch.rs:+3:16: +3:22
36+
}
37+
38+
bb3: {
39+
_2 = _1; // scope 1 at $DIR/branch.rs:+4:9: +4:10
40+
goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
41+
}
42+
43+
bb4: {
44+
StorageLive(_4); // scope 1 at $DIR/branch.rs:+6:9: +6:14
45+
_4 = val() -> bb5; // scope 1 at $DIR/branch.rs:+6:9: +6:14
46+
// mir::Constant
47+
// + span: $DIR/branch.rs:18:9: 18:12
48+
// + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
49+
}
50+
51+
bb5: {
52+
StorageDead(_4); // scope 1 at $DIR/branch.rs:+6:14: +6:15
53+
_2 = _1; // scope 1 at $DIR/branch.rs:+7:9: +7:10
54+
goto -> bb6; // scope 1 at $DIR/branch.rs:+3:13: +8:6
55+
}
56+
57+
bb6: {
58+
StorageDead(_3); // scope 1 at $DIR/branch.rs:+8:5: +8:6
59+
_0 = _2; // scope 2 at $DIR/branch.rs:+10:5: +10:6
60+
StorageDead(_2); // scope 1 at $DIR/branch.rs:+11:1: +11:2
61+
StorageDead(_1); // scope 0 at $DIR/branch.rs:+11:1: +11:2
62+
return; // scope 0 at $DIR/branch.rs:+11:2: +11:2
63+
}
64+
}
65+

tests/mir-opt/copy-prop/branch.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! Tests that we bail out when there are multiple assignments to the same local.
2+
// unit-test: CopyProp
3+
fn val() -> i32 {
4+
1
5+
}
6+
7+
fn cond() -> bool {
8+
true
9+
}
10+
11+
// EMIT_MIR branch.foo.CopyProp.diff
12+
fn foo() -> i32 {
13+
let x = val();
14+
15+
let y = if cond() {
16+
x
17+
} else {
18+
val();
19+
x
20+
};
21+
22+
y
23+
}
24+
25+
fn main() {
26+
foo();
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
- // MIR for `arg_src` before CopyProp
2+
+ // MIR for `arg_src` after CopyProp
3+
4+
fn arg_src(_1: i32) -> i32 {
5+
debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:12: +0:17
6+
let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
7+
let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
8+
scope 1 {
9+
debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
10+
}
11+
12+
bb0: {
13+
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
14+
_2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
15+
_1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
16+
_0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
17+
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
18+
return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
19+
}
20+
}
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
- // MIR for `bar` before CopyProp
2+
+ // MIR for `bar` after CopyProp
3+
4+
fn bar(_1: u8) -> () {
5+
debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
6+
let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
7+
let _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
8+
let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
9+
10+
bb0: {
11+
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
12+
StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
13+
_3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:11: +1:12
14+
_2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:5: +1:13
15+
// mir::Constant
16+
// + span: $DIR/copy_propagation_arg.rs:16:5: 16:10
17+
// + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
18+
}
19+
20+
bb1: {
21+
StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+1:12: +1:13
22+
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
23+
_1 = const 5_u8; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
24+
_0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
25+
return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
26+
}
27+
}
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
- // MIR for `baz` before CopyProp
2+
+ // MIR for `baz` after CopyProp
3+
4+
fn baz(_1: i32) -> i32 {
5+
debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
6+
let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:23: +0:26
7+
let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
8+
9+
bb0: {
10+
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
11+
_2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
12+
_1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:10
13+
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:10
14+
_0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
15+
return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
16+
}
17+
}
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
- // MIR for `foo` before CopyProp
2+
+ // MIR for `foo` after CopyProp
3+
4+
fn foo(_1: u8) -> () {
5+
debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:+0:8: +0:13
6+
let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +0:19
7+
let mut _2: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
8+
let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
9+
10+
bb0: {
11+
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
12+
StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
13+
_3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:15: +2:16
14+
_2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:+2:9: +2:17
15+
// mir::Constant
16+
// + span: $DIR/copy_propagation_arg.rs:11:9: 11:14
17+
// + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(<ZST>) }
18+
}
19+
20+
bb1: {
21+
StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
22+
_1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:+2:5: +2:17
23+
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+2:16: +2:17
24+
_0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:+0:19: +3:2
25+
return; // scope 0 at $DIR/copy_propagation_arg.rs:+3:2: +3:2
26+
}
27+
}
28+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Check that CopyProp does not propagate an assignment to a function argument
2+
// (doing so can break usages of the original argument value)
3+
// unit-test: CopyProp
4+
fn dummy(x: u8) -> u8 {
5+
x
6+
}
7+
8+
// EMIT_MIR copy_propagation_arg.foo.CopyProp.diff
9+
fn foo(mut x: u8) {
10+
// calling `dummy` to make a use of `x` that copyprop cannot eliminate
11+
x = dummy(x); // this will assign a local to `x`
12+
}
13+
14+
// EMIT_MIR copy_propagation_arg.bar.CopyProp.diff
15+
fn bar(mut x: u8) {
16+
dummy(x);
17+
x = 5;
18+
}
19+
20+
// EMIT_MIR copy_propagation_arg.baz.CopyProp.diff
21+
fn baz(mut x: i32) -> i32 {
22+
// self-assignment to a function argument should be eliminated
23+
x = x;
24+
x
25+
}
26+
27+
// EMIT_MIR copy_propagation_arg.arg_src.CopyProp.diff
28+
fn arg_src(mut x: i32) -> i32 {
29+
let y = x;
30+
x = 123; // Don't propagate this assignment to `y`
31+
y
32+
}
33+
34+
fn main() {
35+
// Make sure the function actually gets instantiated.
36+
foo(0);
37+
bar(0);
38+
baz(0);
39+
arg_src(0);
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
- // MIR for `main` before CopyProp
2+
+ // MIR for `main` after CopyProp
3+
4+
fn main() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/cycle.rs:+0:11: +0:11
6+
let mut _1: i32; // in scope 0 at $DIR/cycle.rs:+1:9: +1:14
7+
let mut _4: i32; // in scope 0 at $DIR/cycle.rs:+4:9: +4:10
8+
let _5: (); // in scope 0 at $DIR/cycle.rs:+6:5: +6:12
9+
let mut _6: i32; // in scope 0 at $DIR/cycle.rs:+6:10: +6:11
10+
scope 1 {
11+
debug x => _1; // in scope 1 at $DIR/cycle.rs:+1:9: +1:14
12+
let _2: i32; // in scope 1 at $DIR/cycle.rs:+2:9: +2:10
13+
scope 2 {
14+
debug y => _2; // in scope 2 at $DIR/cycle.rs:+2:9: +2:10
15+
let _3: i32; // in scope 2 at $DIR/cycle.rs:+3:9: +3:10
16+
scope 3 {
17+
- debug z => _3; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
18+
+ debug z => _2; // in scope 3 at $DIR/cycle.rs:+3:9: +3:10
19+
}
20+
}
21+
}
22+
23+
bb0: {
24+
StorageLive(_1); // scope 0 at $DIR/cycle.rs:+1:9: +1:14
25+
_1 = val() -> bb1; // scope 0 at $DIR/cycle.rs:+1:17: +1:22
26+
// mir::Constant
27+
// + span: $DIR/cycle.rs:9:17: 9:20
28+
// + literal: Const { ty: fn() -> i32 {val}, val: Value(<ZST>) }
29+
}
30+
31+
bb1: {
32+
- StorageLive(_2); // scope 1 at $DIR/cycle.rs:+2:9: +2:10
33+
_2 = _1; // scope 1 at $DIR/cycle.rs:+2:13: +2:14
34+
- StorageLive(_3); // scope 2 at $DIR/cycle.rs:+3:9: +3:10
35+
- _3 = _2; // scope 2 at $DIR/cycle.rs:+3:13: +3:14
36+
- StorageLive(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
37+
- _4 = _3; // scope 3 at $DIR/cycle.rs:+4:9: +4:10
38+
- _1 = move _4; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
39+
- StorageDead(_4); // scope 3 at $DIR/cycle.rs:+4:9: +4:10
40+
+ _1 = _2; // scope 3 at $DIR/cycle.rs:+4:5: +4:10
41+
StorageLive(_5); // scope 3 at $DIR/cycle.rs:+6:5: +6:12
42+
StorageLive(_6); // scope 3 at $DIR/cycle.rs:+6:10: +6:11
43+
_6 = _1; // scope 3 at $DIR/cycle.rs:+6:10: +6:11
44+
_5 = std::mem::drop::<i32>(move _6) -> bb2; // scope 3 at $DIR/cycle.rs:+6:5: +6:12
45+
// mir::Constant
46+
// + span: $DIR/cycle.rs:14:5: 14:9
47+
// + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(<ZST>) }
48+
}
49+
50+
bb2: {
51+
StorageDead(_6); // scope 3 at $DIR/cycle.rs:+6:11: +6:12
52+
StorageDead(_5); // scope 3 at $DIR/cycle.rs:+6:12: +6:13
53+
_0 = const (); // scope 0 at $DIR/cycle.rs:+0:11: +7:2
54+
- StorageDead(_3); // scope 2 at $DIR/cycle.rs:+7:1: +7:2
55+
- StorageDead(_2); // scope 1 at $DIR/cycle.rs:+7:1: +7:2
56+
StorageDead(_1); // scope 0 at $DIR/cycle.rs:+7:1: +7:2
57+
return; // scope 0 at $DIR/cycle.rs:+7:2: +7:2
58+
}
59+
}
60+

tests/mir-opt/copy-prop/cycle.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//! Tests that cyclic assignments don't hang CopyProp, and result in reasonable code.
2+
// unit-test: CopyProp
3+
fn val() -> i32 {
4+
1
5+
}
6+
7+
// EMIT_MIR cycle.main.CopyProp.diff
8+
fn main() {
9+
let mut x = val();
10+
let y = x;
11+
let z = y;
12+
x = z;
13+
14+
drop(x);
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// MIR for `f` after CopyProp
2+
3+
fn f(_1: usize) -> usize {
4+
debug a => _1; // in scope 0 at $DIR/dead_stores_79191.rs:+0:6: +0:11
5+
let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_79191.rs:+0:23: +0:28
6+
let _2: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+1:9: +1:10
7+
let mut _3: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+3:9: +3:10
8+
let mut _4: usize; // in scope 0 at $DIR/dead_stores_79191.rs:+4:8: +4:9
9+
scope 1 {
10+
debug b => _2; // in scope 1 at $DIR/dead_stores_79191.rs:+1:9: +1:10
11+
}
12+
13+
bb0: {
14+
_2 = _1; // scope 0 at $DIR/dead_stores_79191.rs:+1:13: +1:14
15+
_1 = const 5_usize; // scope 1 at $DIR/dead_stores_79191.rs:+2:5: +2:10
16+
_1 = _2; // scope 1 at $DIR/dead_stores_79191.rs:+3:5: +3:10
17+
StorageLive(_4); // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
18+
_4 = _1; // scope 1 at $DIR/dead_stores_79191.rs:+4:8: +4:9
19+
_0 = id::<usize>(move _4) -> bb1; // scope 1 at $DIR/dead_stores_79191.rs:+4:5: +4:10
20+
// mir::Constant
21+
// + span: $DIR/dead_stores_79191.rs:12:5: 12:7
22+
// + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
23+
}
24+
25+
bb1: {
26+
StorageDead(_4); // scope 1 at $DIR/dead_stores_79191.rs:+4:9: +4:10
27+
return; // scope 0 at $DIR/dead_stores_79191.rs:+5:2: +5:2
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// unit-test: CopyProp
2+
3+
fn id<T>(x: T) -> T {
4+
x
5+
}
6+
7+
// EMIT_MIR dead_stores_79191.f.CopyProp.after.mir
8+
fn f(mut a: usize) -> usize {
9+
let b = a;
10+
a = 5;
11+
a = b;
12+
id(a)
13+
}
14+
15+
fn main() {
16+
f(0);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// MIR for `f` after CopyProp
2+
3+
fn f(_1: usize) -> usize {
4+
debug a => _1; // in scope 0 at $DIR/dead_stores_better.rs:+0:10: +0:15
5+
let mut _0: usize; // return place in scope 0 at $DIR/dead_stores_better.rs:+0:27: +0:32
6+
let _2: usize; // in scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10
7+
let mut _3: usize; // in scope 0 at $DIR/dead_stores_better.rs:+3:9: +3:10
8+
let mut _4: usize; // in scope 0 at $DIR/dead_stores_better.rs:+4:8: +4:9
9+
scope 1 {
10+
debug b => _2; // in scope 1 at $DIR/dead_stores_better.rs:+1:9: +1:10
11+
}
12+
13+
bb0: {
14+
_2 = _1; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14
15+
_1 = const 5_usize; // scope 1 at $DIR/dead_stores_better.rs:+2:5: +2:10
16+
_1 = _2; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10
17+
StorageLive(_4); // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
18+
_4 = _1; // scope 1 at $DIR/dead_stores_better.rs:+4:8: +4:9
19+
_0 = id::<usize>(move _4) -> bb1; // scope 1 at $DIR/dead_stores_better.rs:+4:5: +4:10
20+
// mir::Constant
21+
// + span: $DIR/dead_stores_better.rs:16:5: 16:7
22+
// + literal: Const { ty: fn(usize) -> usize {id::<usize>}, val: Value(<ZST>) }
23+
}
24+
25+
bb1: {
26+
StorageDead(_4); // scope 1 at $DIR/dead_stores_better.rs:+4:9: +4:10
27+
return; // scope 0 at $DIR/dead_stores_better.rs:+5:2: +5:2
28+
}
29+
}

0 commit comments

Comments
 (0)