Skip to content

Commit 1c6030f

Browse files
Rollup merge of #162998 - saethlin:dse-ret-is-arg, r=oli-obk
Avoid generating overlapping assignments in DSE This is a fix for #162997. Considering we also had #155680, I really wonder if this pass should be using LivenessTransferFunction at all.
2 parents 1d7ce9f + c973b50 commit 1c6030f

6 files changed

Lines changed: 62 additions & 10 deletions

‎compiler/rustc_mir_transform/src/dead_store_elimination.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
6363
loc,
6464
);
6565

66+
// The logic in LivenessTransferFunction isn't quite what we need; it ignores call
67+
// destinations that are just locals because they are killed by the call, which makes
68+
// it eligible to be moved-from in the argument list. That's backwards.
69+
if !destination.is_indirect() {
70+
state.insert(destination.local);
71+
}
72+
6673
for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() {
6774
if let Operand::Copy(place) = *arg
6875
&& !place.is_indirect()

‎tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-abort.diff‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
let mut _0: ();
66

77
bb0: {
8-
_1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind unreachable];
8+
_1[_2] = identity::<usize>(copy _2) -> [return: bb1, unwind unreachable];
99
}
1010

1111
bb1: {

‎tests/mir-opt/dead-store-elimination/call_arg_copy.move_index.DeadStoreElimination-final.panic-unwind.diff‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
let mut _0: ();
66

77
bb0: {
8-
_1[_2] = passthrough_usize(copy _2) -> [return: bb1, unwind continue];
8+
_1[_2] = identity::<usize>(copy _2) -> [return: bb1, unwind continue];
99
}
1010

1111
bb1: {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
- // MIR for `ret_is_arg` before DeadStoreElimination-final
2+
+ // MIR for `ret_is_arg` after DeadStoreElimination-final
3+
4+
fn ret_is_arg(_1: [u64; 5]) -> [u64; 5] {
5+
let mut _0: [u64; 5];
6+
7+
bb0: {
8+
_1 = identity::<[u64; 5]>(copy _1) -> [return: bb1, unwind unreachable];
9+
}
10+
11+
bb1: {
12+
_0 = copy _1;
13+
return;
14+
}
15+
}
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
- // MIR for `ret_is_arg` before DeadStoreElimination-final
2+
+ // MIR for `ret_is_arg` after DeadStoreElimination-final
3+
4+
fn ret_is_arg(_1: [u64; 5]) -> [u64; 5] {
5+
let mut _0: [u64; 5];
6+
7+
bb0: {
8+
_1 = identity::<[u64; 5]>(copy _1) -> [return: bb1, unwind unreachable];
9+
}
10+
11+
bb1: {
12+
_0 = copy _1;
13+
return;
14+
}
15+
}
16+

‎tests/mir-opt/dead-store-elimination/call_arg_copy.rs‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#![feature(custom_mir)]
77
#![allow(internal_features)]
88

9+
use std::convert::identity;
910
use std::intrinsics::mir::*;
1011

1112
#[inline(never)]
@@ -40,31 +41,43 @@ fn move_packed(packed: Packed) {
4041
}
4142
}
4243

43-
#[inline(never)]
44-
fn passthrough_usize(a: usize) -> usize {
45-
a
46-
}
47-
4844
// EMIT_MIR call_arg_copy.move_index.DeadStoreElimination-final.diff
4945
#[custom_mir(dialect = "analysis")]
5046
fn move_index(a: [usize; 10], b: usize) {
5147
// CHECK-LABEL: fn move_index(
52-
// CHECK: = passthrough_usize(copy _2)
48+
// CHECK: = identity::<usize>(copy _2)
5349
mir! {
5450
{
5551
// The index is used again after the operand is evaluated to
56-
// evaluate the destionation place, so the argument cannot be turned
52+
// evaluate the destination place, so the argument cannot be turned
5753
// into a move.
58-
Call(a[b] = passthrough_usize(b), ReturnTo(ret), UnwindContinue())
54+
Call(a[b] = identity(b), ReturnTo(ret), UnwindContinue())
5955
}
6056
ret = {
6157
Return()
6258
}
6359
}
6460
}
6561

62+
// EMIT_MIR call_arg_copy.ret_is_arg.DeadStoreElimination-final.diff
63+
#[custom_mir(dialect = "runtime")]
64+
fn ret_is_arg(x: [u64; 5]) -> [u64; 5] {
65+
// CHECK-LABEL: fn ret_is_arg(_1
66+
// CHECK: _1 = identity::<[u64; 5]>(copy _1) ->
67+
mir! {
68+
{
69+
Call(x = identity(x), ReturnTo(bb1), UnwindUnreachable())
70+
}
71+
bb1 = {
72+
RET = x;
73+
Return()
74+
}
75+
}
76+
}
77+
6678
fn main() {
6779
move_simple(1);
6880
move_packed(Packed { x: 0, y: 1 });
6981
move_index([0; _], 1);
82+
ret_is_arg([0; 5]);
7083
}

0 commit comments

Comments
 (0)