-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #111752 - dingxiangfei2009:lower-or-pattern, r=cjgillot
Lower `Or` pattern without allocating place cc `@azizghuloum` `@cjgillot` Related to #111583 and #111644 While reviewing #111644, it occurs to me that while we directly lower conjunctive predicates, which are connected with `&&`, into the desirable control flow, today we don't directly lower the disjunctive predicates, which are connected with `||`, in the similar fashion. Instead, we allocate a place for the boolean temporary to hold the result of evaluating the `||` expression. Usually I would expect optimization at later stages to "inline" the evaluation of boolean predicates into simple CFG, but #111583 is an example where `&&` is failing to be optimized away and the assembly shows that both the expensive operands are evaluated. Therefore, I would like to make a small change to make the CFG a bit more straight-forward without invoking the `as_temp` machinery, and plus avoid allocating the place to hold the boolean result as well.
- Loading branch information
Showing
53 changed files
with
1,005 additions
and
628 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// compile-flags: -Z validate-mir | ||
#![feature(let_chains)] | ||
struct Droppy(u8); | ||
impl Drop for Droppy { | ||
fn drop(&mut self) { | ||
println!("drop {}", self.0); | ||
} | ||
} | ||
|
||
enum E { | ||
A(u8), | ||
B, | ||
} | ||
|
||
impl E { | ||
fn f() -> Self { | ||
Self::A(1) | ||
} | ||
} | ||
|
||
fn always_true() -> bool { | ||
true | ||
} | ||
|
||
// EMIT_MIR logical_or_in_conditional.test_or.built.after.mir | ||
fn test_or() { | ||
if Droppy(0).0 > 0 || Droppy(1).0 > 1 {} | ||
} | ||
|
||
// EMIT_MIR logical_or_in_conditional.test_complex.built.after.mir | ||
fn test_complex() { | ||
if let E::A(_) = E::f() && ((always_true() && Droppy(0).0 > 0) || Droppy(1).0 > 1) {} | ||
|
||
if !always_true() && let E::B = E::f() {} | ||
} | ||
|
||
fn main() { | ||
test_or(); | ||
} |
Oops, something went wrong.