Skip to content
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

Rust generates guard instructions around match statements #45792

Closed
jrmuizel opened this issue Nov 5, 2017 · 2 comments
Closed

Rust generates guard instructions around match statements #45792

jrmuizel opened this issue Nov 5, 2017 · 2 comments

Comments

@jrmuizel
Copy link
Contributor

jrmuizel commented Nov 5, 2017

trait A {
    fn k(&self, x: i32) -> i32;
}

pub struct O {
}

pub struct P {
}

impl A for O {
    #[inline(never)]
    fn k(&self, x: i32) -> i32 {
        x
    }
}

pub struct M {
}

impl A for M {
    #[inline(never)]
    fn k(&self, x: i32) -> i32 {
        x
    }
}

pub struct N {
}

impl A for N {
    #[inline(never)]
    fn k(&self, x: i32) -> i32 {
        x
    }
}

pub struct Q {
}

impl A for Q {
    #[inline(never)]
    fn k(&self, x: i32) -> i32 {
        x
    }
}

impl A for P {
    #[inline(never)]
    fn k(&self, x: i32) -> i32 {
        x
    }
}

pub enum R {
    P(P),
    O(O),
    M(M),
    N(N),
    Q(Q),
}
impl R {

    pub fn k(&self, x: i32) -> i32 {
        match self {
            &R::P(ref p) => p.k(x),
            &R::O(ref o) => o.k(x),
            &R::M(ref o) => o.k(x),
            &R::N(ref o) => o.k(x),
            &R::Q(ref o) => o.k(x),

        }
    }
}

compiles to:

<example::O as example::A>::k:
        push    rbp
        mov     rbp, rsp
        mov     eax, esi
        pop     rbp
        ret

<example::M as example::A>::k:
        push    rbp
        mov     rbp, rsp
        mov     eax, esi
        pop     rbp
        ret

<example::N as example::A>::k:
        push    rbp
        mov     rbp, rsp
        mov     eax, esi
        pop     rbp
        ret

<example::Q as example::A>::k:
        push    rbp
        mov     rbp, rsp
        mov     eax, esi
        pop     rbp
        ret

<example::P as example::A>::k:
        push    rbp
        mov     rbp, rsp
        mov     eax, esi
        pop     rbp
        ret

example::R::k:
        push    rbp
        mov     rbp, rsp
        movzx   eax, byte ptr [rdi]
        mov     ecx, eax
        shl     cl, 5
        sar     cl, 5
        js      .LBB5_6
        lea     rcx, [rip + .LJTI5_0]
        movsxd  rax, dword ptr [rcx + 4*rax]
        add     rax, rcx
        jmp     rax
.LBB5_2:
        pop     rbp
        jmp     <example::P as example::A>::k@PLT
.LBB5_6:
        pop     rbp
        jmp     <example::Q as example::A>::k@PLT
.LBB5_3:
        pop     rbp
        jmp     <example::O as example::A>::k@PLT
.LBB5_4:
        pop     rbp
        jmp     <example::M as example::A>::k@PLT
.LBB5_5:
        pop     rbp
        jmp     <example::N as example::A>::k@PLT
.LJTI5_0:
        .long   .LBB5_2-.LJTI5_0
        .long   .LBB5_3-.LJTI5_0
        .long   .LBB5_4-.LJTI5_0
        .long   .LBB5_5-.LJTI5_0

Notice this set of instructions:

        shl     cl, 5
        sar     cl, 5
        js      .LBB5_6

It seems like these could be dropped.

The corresponding llvm ir is here:

  %0 = getelementptr inbounds %R, %R* %self, i64 0, i32 0
  %1 = load i8, i8* %0, align 1, !range !0
  %trunc = trunc i8 %1 to i3
  switch i3 %trunc, label %bb5 [
    i3 0, label %bb1
    i3 1, label %bb2
    i3 2, label %bb3
    i3 3, label %bb4
  ]
@nagisa
Copy link
Member

nagisa commented Nov 6, 2017

Duplicate of #36283.

@nagisa nagisa closed this as completed Nov 6, 2017
@nagisa
Copy link
Member

nagisa commented Nov 6, 2017

Most notably, the relevant is this LLVM bug.

Thanks for the report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants