Skip to content

[MIR] match translation sometimes generates 3-armed boolean switches #33540

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

Closed
arielb1 opened this issue May 10, 2016 · 1 comment
Closed

[MIR] match translation sometimes generates 3-armed boolean switches #33540

arielb1 opened this issue May 10, 2016 · 1 comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html

Comments

@arielb1
Copy link
Contributor

arielb1 commented May 10, 2016

STR

fn foo(x: bool, y: bool) -> u32{
    match (x, y) {
         (false, _) => 0,
         (_, false) => 1,
         (true, true) => 2,
    }
}```

## Generated MIR
bb0: {
    var0 = arg0; // Scope(1) at <anon>:1:8: 1:9
    var1 = arg1; // Scope(1) at <anon>:1:17: 1:18
    tmp1 = var0; // Scope(5) at <anon>:2:12: 2:13
    tmp2 = var1; // Scope(6) at <anon>:2:15: 2:16
    tmp0 = (tmp1, tmp2); // Scope(4) at <anon>:2:11: 2:17
    switchInt((tmp0.0: bool)) -> [false: bb5, otherwise: bb4]; // Scope(3) at <anon>:3:11: 3:16
}

bb1: {
    return = const 0u32; // Scope(10) at <anon>:3:25: 3:26
    goto -> bb8; // Scope(3) at <anon>:2:5: 6:6
}

bb2: {
    return = const 1u32; // Scope(11) at <anon>:4:24: 4:25
    goto -> bb8; // Scope(3) at <anon>:2:5: 6:6
}

bb3: {
    return = const 2u32; // Scope(12) at <anon>:5:26: 5:27
    goto -> bb8; // Scope(3) at <anon>:2:5: 6:6
}

bb4: {
    // THREE-ARMED SWITCH HERE:
    switchInt((tmp0.1: bool)) -> [false: bb2, true: bb6, otherwise: bb7]; // Scope(3) at <anon>:4:14: 4:19
}

bb5: {
    var2 = (tmp0.1: bool); // Scope(3) at <anon>:3:18: 3:20
    goto -> bb1; // Scope(3) at <anon>:3:10: 3:21
}

bb6: {
    switchInt((tmp0.0: bool)) -> [true: bb3, otherwise: bb7]; // Scope(3) at <anon>:5:11: 5:15
}

bb7: {
    tmp4 = promoted0; // Scope(3) at <anon>:2:5: 6:6
    core::panicking::panic(tmp4); // Scope(3) at <anon>:2:5: 6:6
}

bb8: {
    return; // Scope(0) at <anon>:1:1: 7:2
}
@arielb1 arielb1 changed the title _match translation sometimes generates 3-armed matches [MIR] match translation sometimes generates 3-armed boolean switches May 10, 2016
@nagisa nagisa added the A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html label May 10, 2016
@nagisa
Copy link
Member

nagisa commented May 10, 2016

See this.

bors added a commit that referenced this issue Jun 2, 2016
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
Projects
None yet
Development

No branches or pull requests

2 participants