-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MIR: Don't generate 3-armed boolean switch from match. #33583
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
.chain(Some(otherwise)) | ||
.collect(); | ||
let targets: Vec<_> = match switch_ty.sty { | ||
ty::TyBool if options.len() == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems...ok to me :) might be nice to be a touch more general (e.g., if there is an exhaustive u8
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, this commit alone is not enough, in that it invalidates the SwitchInt
terminator's invariants. e.g. this comment on targets
says:
/// Possible branch sites. The length of this vector should be
/// equal to the length of the `values` vector plus 1 -- the
/// extra item is the block to branch to if none of the values
/// fit.
targets: Vec<BasicBlock>,
but here you are not generating the otherwise block. It'd be better to change terminator in that case I imagine?
Ok, changed SwitchInt to explicitly separate out the otherwise block and put it behind an |
I think we want to generate an |
Or else change |
While not necessarily incorrect, that would result in a weird branch in trans since LLVM wants a |
We could definitely just take |
I'd be happier with that... |
...though I imagine we could make |
As in, SwitchInt during |
@luqmana I think I meant in the trans code. But I'm happy either with using a distinct |
@luqmana do you plan to update this PR to one of those two strategies? :) |
☔ The latest upstream changes (presumably #33667) made this pull request unmergeable. Please resolve the merge conflicts. |
@nikomatsakis Yup sorry, just got occupied with some other work. Anyways, updated the patch to just generate an If terminator for boolean types. |
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
fn foo(x: bool, y: bool) -> u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this test should have #[rustc_mir]
? And a comment explaining what it's all about?
Added attribute and comment to test. |
@bors r+ |
📌 Commit a97f6b3 has been approved by |
MIR: Don't generate 3-armed boolean switch from match. Fixes #33540. Snippet from issue: ```Rust fn foo(x: bool, y: bool) -> u32 { match (x, y) { (false, _) => 0, (_, false) => 1, (true, true) => 2, } } ``` Generated MIR: ``` fn foo(arg0: bool, arg1: bool) -> u32 { let var0: bool; // "x" in scope 1 at 3bbm.rs:17:8: 17:9 let var1: bool; // "y" in scope 1 at 3bbm.rs:17:17: 17:18 let mut tmp0: (bool, bool); let mut tmp1: bool; let mut tmp2: bool; let mut tmp3: (&'static str, &'static str, u32); let mut tmp4: &'static (&'static str, &'static str, u32); bb0: { var0 = arg0; // scope 1 at 3bbm.rs:17:8: 17:9 var1 = arg1; // scope 1 at 3bbm.rs:17:17: 17:18 tmp1 = var0; // scope 5 at 3bbm.rs:18:12: 18:13 tmp2 = var1; // scope 6 at 3bbm.rs:18:15: 18:16 tmp0 = (tmp1, tmp2); // scope 4 at 3bbm.rs:18:11: 18:17 if((tmp0.0: bool)) -> [true: bb4, false: bb1]; // scope 3 at 3bbm.rs:19:10: 19:15 } bb1: { return = const 0u32; // scope 10 at 3bbm.rs:19:23: 19:24 goto -> bb7; // scope 3 at 3bbm.rs:18:5: 22:6 } bb2: { return = const 1u32; // scope 11 at 3bbm.rs:20:23: 20:24 goto -> bb7; // scope 3 at 3bbm.rs:18:5: 22:6 } bb3: { return = const 2u32; // scope 12 at 3bbm.rs:21:25: 21:26 goto -> bb7; // scope 3 at 3bbm.rs:18:5: 22:6 } bb4: { if((tmp0.1: bool)) -> [true: bb5, false: bb2]; // scope 3 at 3bbm.rs:20:13: 20:18 } bb5: { if((tmp0.0: bool)) -> [true: bb3, false: bb6]; // scope 3 at 3bbm.rs:21:10: 21:14 } bb6: { tmp4 = promoted0; // scope 3 at 3bbm.rs:18:5: 22:6 core::panicking::panic(tmp4); // scope 3 at 3bbm.rs:18:5: 22:6 } bb7: { return; // scope 0 at 3bbm.rs:17:1: 23:2 } } ``` Not sure about this approach. I was also thinking maybe just a standalone pass? cc @arielb1, @nagisa
Fixes #33540.
Snippet from issue:
Generated MIR:
Not sure about this approach. I was also thinking maybe just a standalone pass?
cc @arielb1, @nagisa