Auto merge of #76659 - simonvandel:76432, r=oli-obk
SimplifyComparisonIntegral: fix miscompilation Fixes #76432 Only insert StorageDeads if we actually removed one. Fixes an issue where we added StorageDead to a place with no StorageLive r? `@oli-obk`
This commit is contained in:
commit
feca2c229e
3 changed files with 154 additions and 21 deletions
|
@ -61,26 +61,6 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let terminator = bb.terminator_mut();
|
|
||||||
|
|
||||||
// add StorageDead for the place switched on at the top of each target
|
|
||||||
for bb_idx in new_targets.iter() {
|
|
||||||
storage_deads_to_insert.push((
|
|
||||||
*bb_idx,
|
|
||||||
Statement {
|
|
||||||
source_info: terminator.source_info,
|
|
||||||
kind: StatementKind::StorageDead(opt.to_switch_on.local),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
terminator.kind = TerminatorKind::SwitchInt {
|
|
||||||
discr: Operand::Move(opt.to_switch_on),
|
|
||||||
switch_ty: opt.branch_value_ty,
|
|
||||||
values: vec![new_value].into(),
|
|
||||||
targets: new_targets,
|
|
||||||
};
|
|
||||||
|
|
||||||
// delete comparison statement if it the value being switched on was moved, which means it can not be user later on
|
// delete comparison statement if it the value being switched on was moved, which means it can not be user later on
|
||||||
if opt.can_remove_bin_op_stmt {
|
if opt.can_remove_bin_op_stmt {
|
||||||
bb.statements[opt.bin_op_stmt_idx].make_nop();
|
bb.statements[opt.bin_op_stmt_idx].make_nop();
|
||||||
|
@ -106,14 +86,35 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let terminator = bb.terminator();
|
||||||
|
|
||||||
// remove StorageDead (if it exists) being used in the assign of the comparison
|
// remove StorageDead (if it exists) being used in the assign of the comparison
|
||||||
for (stmt_idx, stmt) in bb.statements.iter().enumerate() {
|
for (stmt_idx, stmt) in bb.statements.iter().enumerate() {
|
||||||
if !matches!(stmt.kind, StatementKind::StorageDead(local) if local == opt.to_switch_on.local)
|
if !matches!(stmt.kind, StatementKind::StorageDead(local) if local == opt.to_switch_on.local)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
storage_deads_to_remove.push((stmt_idx, opt.bb_idx))
|
storage_deads_to_remove.push((stmt_idx, opt.bb_idx));
|
||||||
|
// if we have StorageDeads to remove then make sure to insert them at the top of each target
|
||||||
|
for bb_idx in new_targets.iter() {
|
||||||
|
storage_deads_to_insert.push((
|
||||||
|
*bb_idx,
|
||||||
|
Statement {
|
||||||
|
source_info: terminator.source_info,
|
||||||
|
kind: StatementKind::StorageDead(opt.to_switch_on.local),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let terminator = bb.terminator_mut();
|
||||||
|
|
||||||
|
terminator.kind = TerminatorKind::SwitchInt {
|
||||||
|
discr: Operand::Move(opt.to_switch_on),
|
||||||
|
switch_ty: opt.branch_value_ty,
|
||||||
|
values: vec![new_value].into(),
|
||||||
|
targets: new_targets,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx, bb_idx) in storage_deads_to_remove {
|
for (idx, bb_idx) in storage_deads_to_remove {
|
||||||
|
|
16
src/test/mir-opt/issue_76432.rs
Normal file
16
src/test/mir-opt/issue_76432.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that we do not insert StorageDead at each target if StorageDead was never seen
|
||||||
|
|
||||||
|
// EMIT_MIR issue_76432.test.SimplifyComparisonIntegral.diff
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
fn test<T: Copy + Debug + PartialEq>(x: T) {
|
||||||
|
let v: &[T] = &[x, x, x];
|
||||||
|
match v {
|
||||||
|
[ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(0u32);
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
- // MIR for `test` before SimplifyComparisonIntegral
|
||||||
|
+ // MIR for `test` after SimplifyComparisonIntegral
|
||||||
|
|
||||||
|
fn test(_1: T) -> () {
|
||||||
|
debug x => _1; // in scope 0 at $DIR/issue_76432.rs:6:38: 6:39
|
||||||
|
let mut _0: (); // return place in scope 0 at $DIR/issue_76432.rs:6:44: 6:44
|
||||||
|
let _2: &[T]; // in scope 0 at $DIR/issue_76432.rs:7:9: 7:10
|
||||||
|
let mut _3: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
let _4: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
let _5: [T; 3]; // in scope 0 at $DIR/issue_76432.rs:7:20: 7:29
|
||||||
|
let mut _6: T; // in scope 0 at $DIR/issue_76432.rs:7:21: 7:22
|
||||||
|
let mut _7: T; // in scope 0 at $DIR/issue_76432.rs:7:24: 7:25
|
||||||
|
let mut _8: T; // in scope 0 at $DIR/issue_76432.rs:7:27: 7:28
|
||||||
|
let _9: [*const T; 3]; // in scope 0 at $DIR/issue_76432.rs:8:5: 11:6
|
||||||
|
let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
let mut _11: usize; // in scope 0 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
let mut _12: bool; // in scope 0 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
let mut _16: *const T; // in scope 0 at $DIR/issue_76432.rs:9:38: 9:52
|
||||||
|
let mut _17: *const T; // in scope 0 at $DIR/issue_76432.rs:9:38: 9:52
|
||||||
|
let mut _18: *const T; // in scope 0 at $DIR/issue_76432.rs:9:54: 9:68
|
||||||
|
let mut _19: *const T; // in scope 0 at $DIR/issue_76432.rs:9:54: 9:68
|
||||||
|
let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84
|
||||||
|
let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84
|
||||||
|
let mut _22: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||||
|
scope 1 {
|
||||||
|
debug v => _2; // in scope 1 at $DIR/issue_76432.rs:7:9: 7:10
|
||||||
|
let _13: &T; // in scope 1 at $DIR/issue_76432.rs:9:10: 9:16
|
||||||
|
let _14: &T; // in scope 1 at $DIR/issue_76432.rs:9:18: 9:24
|
||||||
|
let _15: &T; // in scope 1 at $DIR/issue_76432.rs:9:26: 9:32
|
||||||
|
scope 2 {
|
||||||
|
debug v1 => _13; // in scope 2 at $DIR/issue_76432.rs:9:10: 9:16
|
||||||
|
debug v2 => _14; // in scope 2 at $DIR/issue_76432.rs:9:18: 9:24
|
||||||
|
debug v3 => _15; // in scope 2 at $DIR/issue_76432.rs:9:26: 9:32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_2); // scope 0 at $DIR/issue_76432.rs:7:9: 7:10
|
||||||
|
StorageLive(_3); // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
StorageLive(_4); // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
StorageLive(_5); // scope 0 at $DIR/issue_76432.rs:7:20: 7:29
|
||||||
|
StorageLive(_6); // scope 0 at $DIR/issue_76432.rs:7:21: 7:22
|
||||||
|
_6 = _1; // scope 0 at $DIR/issue_76432.rs:7:21: 7:22
|
||||||
|
StorageLive(_7); // scope 0 at $DIR/issue_76432.rs:7:24: 7:25
|
||||||
|
_7 = _1; // scope 0 at $DIR/issue_76432.rs:7:24: 7:25
|
||||||
|
StorageLive(_8); // scope 0 at $DIR/issue_76432.rs:7:27: 7:28
|
||||||
|
_8 = _1; // scope 0 at $DIR/issue_76432.rs:7:27: 7:28
|
||||||
|
_5 = [move _6, move _7, move _8]; // scope 0 at $DIR/issue_76432.rs:7:20: 7:29
|
||||||
|
StorageDead(_8); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
|
||||||
|
StorageDead(_7); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
|
||||||
|
StorageDead(_6); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
|
||||||
|
_4 = &_5; // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
_3 = _4; // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
_2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:7:19: 7:29
|
||||||
|
StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:7:28: 7:29
|
||||||
|
StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:7:29: 7:30
|
||||||
|
StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:8:5: 11:6
|
||||||
|
_10 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
_11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
- _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
- switchInt(move _12) -> [false: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
+ nop; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
+ switchInt(move _10) -> [3_usize: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:9:9: 9:33
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_22); // scope 1 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||||
|
begin_panic::<&str>(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/std/src/macros.rs:LL:COL
|
||||||
|
// mir::Constant
|
||||||
|
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
|
||||||
|
// + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar(<ZST>)) }
|
||||||
|
// ty::Const
|
||||||
|
// + ty: &str
|
||||||
|
// + val: Value(Slice { data: Allocation { bytes: [105, 110, 116, 101, 114, 110, 97, 108, 32, 101, 114, 114, 111, 114, 58, 32, 101, 110, 116, 101, 114, 101, 100, 32, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 32, 99, 111, 100, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1099511627775], len: Size { raw: 40 } }, size: Size { raw: 40 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 40 })
|
||||||
|
// mir::Constant
|
||||||
|
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
// + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [105, 110, 116, 101, 114, 110, 97, 108, 32, 101, 114, 114, 111, 114, 58, 32, 101, 110, 116, 101, 114, 101, 100, 32, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 32, 99, 111, 100, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1099511627775], len: Size { raw: 40 } }, size: Size { raw: 40 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 40 }) }
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:9:10: 9:16
|
||||||
|
_13 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:9:10: 9:16
|
||||||
|
StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:9:18: 9:24
|
||||||
|
_14 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:9:18: 9:24
|
||||||
|
StorageLive(_15); // scope 1 at $DIR/issue_76432.rs:9:26: 9:32
|
||||||
|
_15 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:9:26: 9:32
|
||||||
|
StorageLive(_16); // scope 2 at $DIR/issue_76432.rs:9:38: 9:52
|
||||||
|
StorageLive(_17); // scope 2 at $DIR/issue_76432.rs:9:38: 9:52
|
||||||
|
_17 = &raw const (*_13); // scope 2 at $DIR/issue_76432.rs:9:38: 9:40
|
||||||
|
_16 = _17; // scope 2 at $DIR/issue_76432.rs:9:38: 9:52
|
||||||
|
StorageLive(_18); // scope 2 at $DIR/issue_76432.rs:9:54: 9:68
|
||||||
|
StorageLive(_19); // scope 2 at $DIR/issue_76432.rs:9:54: 9:68
|
||||||
|
_19 = &raw const (*_14); // scope 2 at $DIR/issue_76432.rs:9:54: 9:56
|
||||||
|
_18 = _19; // scope 2 at $DIR/issue_76432.rs:9:54: 9:68
|
||||||
|
StorageLive(_20); // scope 2 at $DIR/issue_76432.rs:9:70: 9:84
|
||||||
|
StorageLive(_21); // scope 2 at $DIR/issue_76432.rs:9:70: 9:84
|
||||||
|
_21 = &raw const (*_15); // scope 2 at $DIR/issue_76432.rs:9:70: 9:72
|
||||||
|
_20 = _21; // scope 2 at $DIR/issue_76432.rs:9:70: 9:84
|
||||||
|
_9 = [move _16, move _18, move _20]; // scope 2 at $DIR/issue_76432.rs:9:37: 9:85
|
||||||
|
StorageDead(_21); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_20); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_19); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_18); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_17); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_16); // scope 2 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_15); // scope 1 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:9:84: 9:85
|
||||||
|
StorageDead(_9); // scope 1 at $DIR/issue_76432.rs:11:6: 11:7
|
||||||
|
_0 = const (); // scope 0 at $DIR/issue_76432.rs:6:44: 12:2
|
||||||
|
StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:12:1: 12:2
|
||||||
|
StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:12:1: 12:2
|
||||||
|
return; // scope 0 at $DIR/issue_76432.rs:12:2: 12:2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue