Make the success arms of if lhs || rhs meet up in a separate block

In the previous code, the success block of `lhs` would jump directly to the
success block of `rhs`. However, `rhs_success_block` could already contain
statements that are specific to the RHS, and the direct goto causes them to be
executed in the LHS success path as well.

This patch therefore creates a fresh block that the LHS and RHS success blocks
can both jump to.
This commit is contained in:
Zalathar 2024-02-28 18:21:24 +11:00
parent d3d145ea1c
commit a7832b14b1
3 changed files with 69 additions and 55 deletions

View file

@ -93,8 +93,14 @@ pub(crate) fn then_else_break(
variable_source_info, variable_source_info,
true, true,
)); ));
this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block);
rhs_success_block.unit() // Make the LHS and RHS success arms converge to a common block.
// (We can't just make LHS goto RHS, because `rhs_success_block`
// might contain statements that we don't want on the LHS path.)
let success_block = this.cfg.start_new_block();
this.cfg.goto(lhs_success_block, variable_source_info, success_block);
this.cfg.goto(rhs_success_block, variable_source_info, success_block);
success_block.unit()
} }
ExprKind::Unary { op: UnOp::Not, arg } => { ExprKind::Unary { op: UnOp::Not, arg } => {
let local_scope = this.local_scope(); let local_scope = this.local_scope();

View file

@ -19,7 +19,7 @@ fn test_complex() -> () {
bb0: { bb0: {
StorageLive(_1); StorageLive(_1);
StorageLive(_2); StorageLive(_2);
_2 = E::f() -> [return: bb1, unwind: bb37]; _2 = E::f() -> [return: bb1, unwind: bb38];
} }
bb1: { bb1: {
@ -34,7 +34,7 @@ fn test_complex() -> () {
} }
bb3: { bb3: {
goto -> bb22; goto -> bb23;
} }
bb4: { bb4: {
@ -51,7 +51,7 @@ fn test_complex() -> () {
bb7: { bb7: {
StorageLive(_4); StorageLive(_4);
_4 = always_true() -> [return: bb8, unwind: bb37]; _4 = always_true() -> [return: bb8, unwind: bb38];
} }
bb8: { bb8: {
@ -73,7 +73,7 @@ fn test_complex() -> () {
} }
bb11: { bb11: {
drop(_7) -> [return: bb13, unwind: bb37]; drop(_7) -> [return: bb13, unwind: bb38];
} }
bb12: { bb12: {
@ -83,11 +83,11 @@ fn test_complex() -> () {
bb13: { bb13: {
StorageDead(_7); StorageDead(_7);
StorageDead(_6); StorageDead(_6);
goto -> bb19; goto -> bb20;
} }
bb14: { bb14: {
drop(_7) -> [return: bb15, unwind: bb37]; drop(_7) -> [return: bb15, unwind: bb38];
} }
bb15: { bb15: {
@ -107,106 +107,110 @@ fn test_complex() -> () {
} }
bb17: { bb17: {
drop(_10) -> [return: bb19, unwind: bb37]; drop(_10) -> [return: bb19, unwind: bb38];
} }
bb18: { bb18: {
goto -> bb20; goto -> bb21;
} }
bb19: { bb19: {
StorageDead(_10); StorageDead(_10);
StorageDead(_9); StorageDead(_9);
_1 = const (); goto -> bb20;
goto -> bb23;
} }
bb20: { bb20: {
drop(_10) -> [return: bb21, unwind: bb37]; _1 = const ();
goto -> bb24;
} }
bb21: { bb21: {
StorageDead(_10); drop(_10) -> [return: bb22, unwind: bb38];
StorageDead(_9);
goto -> bb22;
} }
bb22: { bb22: {
_1 = const (); StorageDead(_10);
StorageDead(_9);
goto -> bb23; goto -> bb23;
} }
bb23: { bb23: {
_1 = const ();
goto -> bb24;
}
bb24: {
StorageDead(_8); StorageDead(_8);
StorageDead(_5); StorageDead(_5);
StorageDead(_4); StorageDead(_4);
StorageDead(_2); StorageDead(_2);
StorageDead(_1); StorageDead(_1);
StorageLive(_11); StorageLive(_11);
_11 = always_true() -> [return: bb24, unwind: bb37]; _11 = always_true() -> [return: bb25, unwind: bb38];
}
bb24: {
switchInt(move _11) -> [0: bb26, otherwise: bb25];
} }
bb25: { bb25: {
goto -> bb35; switchInt(move _11) -> [0: bb27, otherwise: bb26];
} }
bb26: { bb26: {
goto -> bb27; goto -> bb36;
} }
bb27: { bb27: {
StorageLive(_12); goto -> bb28;
_12 = E::f() -> [return: bb28, unwind: bb37];
} }
bb28: { bb28: {
PlaceMention(_12); StorageLive(_12);
_13 = discriminant(_12); _12 = E::f() -> [return: bb29, unwind: bb38];
switchInt(move _13) -> [1: bb32, otherwise: bb30];
} }
bb29: { bb29: {
PlaceMention(_12);
_13 = discriminant(_12);
switchInt(move _13) -> [1: bb33, otherwise: bb31];
}
bb30: {
FakeRead(ForMatchedPlace(None), _12); FakeRead(ForMatchedPlace(None), _12);
unreachable; unreachable;
} }
bb30: {
goto -> bb35;
}
bb31: { bb31: {
goto -> bb29; goto -> bb36;
} }
bb32: { bb32: {
falseEdge -> [real: bb34, imaginary: bb30];
}
bb33: {
goto -> bb30; goto -> bb30;
} }
bb33: {
falseEdge -> [real: bb35, imaginary: bb31];
}
bb34: { bb34: {
_0 = const (); goto -> bb31;
goto -> bb36;
} }
bb35: { bb35: {
_0 = const (); _0 = const ();
goto -> bb36; goto -> bb37;
} }
bb36: { bb36: {
_0 = const ();
goto -> bb37;
}
bb37: {
StorageDead(_11); StorageDead(_11);
StorageDead(_12); StorageDead(_12);
return; return;
} }
bb37 (cleanup): { bb38 (cleanup): {
resume; resume;
} }
} }

View file

@ -20,7 +20,7 @@ fn test_or() -> () {
} }
bb1: { bb1: {
drop(_3) -> [return: bb3, unwind: bb12]; drop(_3) -> [return: bb3, unwind: bb13];
} }
bb2: { bb2: {
@ -30,11 +30,11 @@ fn test_or() -> () {
bb3: { bb3: {
StorageDead(_3); StorageDead(_3);
StorageDead(_2); StorageDead(_2);
goto -> bb8; goto -> bb9;
} }
bb4: { bb4: {
drop(_3) -> [return: bb5, unwind: bb12]; drop(_3) -> [return: bb5, unwind: bb13];
} }
bb5: { bb5: {
@ -50,38 +50,42 @@ fn test_or() -> () {
} }
bb6: { bb6: {
drop(_6) -> [return: bb8, unwind: bb12]; drop(_6) -> [return: bb8, unwind: bb13];
} }
bb7: { bb7: {
goto -> bb9; goto -> bb10;
} }
bb8: { bb8: {
StorageDead(_6); StorageDead(_6);
StorageDead(_5); StorageDead(_5);
_0 = const (); goto -> bb9;
goto -> bb11;
} }
bb9: { bb9: {
drop(_6) -> [return: bb10, unwind: bb12]; _0 = const ();
goto -> bb12;
} }
bb10: { bb10: {
StorageDead(_6); drop(_6) -> [return: bb11, unwind: bb13];
StorageDead(_5);
_0 = const ();
goto -> bb11;
} }
bb11: { bb11: {
StorageDead(_6);
StorageDead(_5);
_0 = const ();
goto -> bb12;
}
bb12: {
StorageDead(_4); StorageDead(_4);
StorageDead(_1); StorageDead(_1);
return; return;
} }
bb12 (cleanup): { bb13 (cleanup): {
resume; resume;
} }
} }