Skip to content

Commit f216ef7

Browse files
don't try to remove assignments in SimplifyComparisonIntegral
1 parent 2f68482 commit f216ef7

8 files changed

Lines changed: 35 additions & 43 deletions

compiler/rustc_mir_transform/src/simplify_comparison_integral.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,24 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
7676
_ => unreachable!(),
7777
}
7878

79-
// delete comparison statement if it the value being switched on was moved, which means
80-
// it can not be used later on
81-
if opt.can_remove_bin_op_stmt {
82-
bb.statements[opt.bin_op_stmt_idx].make_nop(true);
83-
} else {
84-
// if the integer being compared to a const integral is being moved into the
85-
// comparison, e.g `_2 = Eq(move _3, const 'x');`
86-
// we want to avoid making a double move later on in the switchInt on _3.
87-
// So to avoid `switchInt(move _3) -> ['x': bb2, otherwise: bb1];`,
88-
// we convert the move in the comparison statement to a copy.
89-
90-
// unwrap is safe as we know this statement is an assign
91-
let (_, rhs) = bb.statements[opt.bin_op_stmt_idx].kind.as_assign_mut().unwrap();
92-
93-
use Operand::*;
94-
match rhs {
95-
Rvalue::BinaryOp(_, box (left @ Move(_), Constant(_))) => {
96-
*left = Copy(opt.to_switch_on);
97-
}
98-
Rvalue::BinaryOp(_, box (Constant(_), right @ Move(_))) => {
99-
*right = Copy(opt.to_switch_on);
100-
}
101-
_ => (),
79+
// if the integer being compared to a const integral is being moved into the
80+
// comparison, e.g `_2 = Eq(move _3, const 'x');`
81+
// we want to avoid making a double move later on in the switchInt on _3.
82+
// So to avoid `switchInt(move _3) -> ['x': bb2, otherwise: bb1];`,
83+
// we convert the move in the comparison statement to a copy.
84+
85+
// unwrap is safe as we know this statement is an assign
86+
let (_, rhs) = bb.statements[opt.bin_op_stmt_idx].kind.as_assign_mut().unwrap();
87+
88+
use Operand::*;
89+
match rhs {
90+
Rvalue::BinaryOp(_, box (left @ Move(_), Constant(_))) => {
91+
*left = Copy(opt.to_switch_on);
92+
}
93+
Rvalue::BinaryOp(_, box (Constant(_), right @ Move(_))) => {
94+
*right = Copy(opt.to_switch_on);
10295
}
96+
_ => (),
10397
}
10498

10599
let terminator = bb.terminator();
@@ -187,7 +181,6 @@ impl<'tcx> OptimizationFinder<'_, 'tcx> {
187181
Some(OptimizationInfo {
188182
bin_op_stmt_idx: stmt_idx,
189183
bb_idx,
190-
can_remove_bin_op_stmt: discr.is_move(),
191184
to_switch_on,
192185
branch_value_scalar,
193186
branch_value_ty,
@@ -238,11 +231,8 @@ fn find_branch_value_info<'tcx>(
238231
struct OptimizationInfo<'tcx> {
239232
/// Basic block to apply the optimization
240233
bb_idx: BasicBlock,
241-
/// Statement index of Eq/Ne assignment that can be removed. None if the assignment can not be
242-
/// removed - i.e the statement is used later on
234+
/// Statement index of Eq/Ne assignment
243235
bin_op_stmt_idx: usize,
244-
/// Can remove Eq/Ne assignment
245-
can_remove_bin_op_stmt: bool,
246236
/// Place that needs to be switched on. This place is of type integral
247237
to_switch_on: Place<'tcx>,
248238
/// Constant to use in switch target value

tests/mir-opt/if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
let mut _4: i32;
99

1010
bb0: {
11-
- _2 = Eq(copy _1, const 17_i8);
12-
+ nop;
11+
_2 = Eq(copy _1, const 17_i8);
1312
_3 = copy _2 as i32 (IntToInt);
1413
- switchInt(move _2) -> [1: bb1, otherwise: bb2];
1514
+ switchInt(copy _1) -> [17: bb1, otherwise: bb2];

tests/mir-opt/if_condition_int.opt_char.SimplifyComparisonIntegral.diff

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
StorageLive(_2);
1212
StorageLive(_3);
1313
_3 = copy _1;
14-
- _2 = Eq(copy _1, const 'x');
14+
_2 = Eq(copy _1, const 'x');
1515
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
16-
+ nop;
1716
+ switchInt(copy _1) -> [120: bb1, otherwise: bb2];
1817
}
1918

tests/mir-opt/if_condition_int.opt_i8.SimplifyComparisonIntegral.diff

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
StorageLive(_2);
1212
StorageLive(_3);
1313
_3 = copy _1;
14-
- _2 = Eq(copy _1, const 42_i8);
14+
_2 = Eq(copy _1, const 42_i8);
1515
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
16-
+ nop;
1716
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
1817
}
1918

tests/mir-opt/if_condition_int.opt_multiple_ifs.SimplifyComparisonIntegral.diff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
StorageLive(_2);
1414
StorageLive(_3);
1515
_3 = copy _1;
16-
- _2 = Eq(copy _1, const 42_u32);
16+
_2 = Eq(copy _1, const 42_u32);
1717
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
18-
+ nop;
1918
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
2019
}
2120

@@ -30,9 +29,8 @@
3029
StorageLive(_4);
3130
StorageLive(_5);
3231
_5 = copy _1;
33-
- _4 = Ne(copy _1, const 21_u32);
32+
_4 = Ne(copy _1, const 21_u32);
3433
- switchInt(move _4) -> [0: bb4, otherwise: bb3];
35-
+ nop;
3634
+ switchInt(copy _1) -> [21: bb4, otherwise: bb3];
3735
}
3836

tests/mir-opt/if_condition_int.opt_negative.SimplifyComparisonIntegral.diff

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
StorageLive(_2);
1212
StorageLive(_3);
1313
_3 = copy _1;
14-
- _2 = Eq(copy _1, const -42_i32);
14+
_2 = Eq(copy _1, const -42_i32);
1515
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
16-
+ nop;
1716
+ switchInt(copy _1) -> [4294967254: bb1, otherwise: bb2];
1817
}
1918

tests/mir-opt/if_condition_int.opt_u32.SimplifyComparisonIntegral.diff

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
StorageLive(_2);
1212
StorageLive(_3);
1313
_3 = copy _1;
14-
- _2 = Eq(copy _1, const 42_u32);
14+
_2 = Eq(copy _1, const 42_u32);
1515
- switchInt(move _2) -> [0: bb2, otherwise: bb1];
16-
+ nop;
1716
+ switchInt(copy _1) -> [42: bb1, otherwise: bb2];
1817
}
1918

tests/mir-opt/if_condition_int.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ fn opt_multiple_ifs(x: u32) -> u32 {
8585
}
8686

8787
// EMIT_MIR if_condition_int.dont_remove_comparison.SimplifyComparisonIntegral.diff
88-
// test that we optimize, but do not remove the b statement, as that is used later on
88+
// the switchInt can be optimized but the b statement can't be removed as it's used later on
8989
fn dont_remove_comparison(a: i8) -> i32 {
9090
// CHECK-LABEL: fn dont_remove_comparison(
9191
// CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8);
@@ -104,8 +104,17 @@ fn dont_remove_comparison(a: i8) -> i32 {
104104
}
105105

106106
// EMIT_MIR if_condition_int.dont_remove_moved_comparison.SimplifyComparisonIntegral.diff
107+
// like dont_remove_comparison above, but with switchInt(move _N) - regression test for #158206
107108
#[custom_mir(dialect = "runtime")]
108109
fn dont_remove_moved_comparison(a: i8) -> i32 {
110+
// CHECK-LABEL: fn dont_remove_moved_comparison(
111+
// CHECK: [[b:_.*]] = Eq(copy _1, const 17_i8);
112+
// CHECK: [[cast:_.*]] = copy [[b]] as i32 (IntToInt);
113+
// CHECK: switchInt(copy _1) -> [17: [[BB1:bb.*]], otherwise: [[BB2:bb.*]]];
114+
// CHECK: [[BB1]]:
115+
// CHECK: _0 = copy [[cast]];
116+
// CHECK: [[BB2]]:
117+
// CHECK: _0 = Add(copy [[cast]], const 1_i32);
109118
mir! {
110119
let b: bool;
111120
let c: i32;

0 commit comments

Comments
 (0)