[Issue 15538] wrong code with switch

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Tue Apr 25 02:38:41 PDT 2017


https://issues.dlang.org/show_bug.cgi?id=15538

--- Comment #7 from aneas <alexander.breckel at gmail.com> ---
Further reduced:

----

struct S
{
    int a = 0;
    int b = 1;
}

int f1(S s)
{
    switch (s.a)
    {
        case 0: return 10;
        case 1: return 20;
        case 2: return 30;
        case 3: return 40;
        default: return 99;
    }
}

void main()
{
    S s;
    assert(f1(s) == 10); /* fails */
}



The generates assembly for f1 is this:
----

00000000004271a8 <_D3app2f1FS3app1SZi>:
  4271a8:    55                       push   %rbp
  4271a9:    48 8b ec                 mov    %rsp,%rbp
  4271ac:    48 83 ec 10              sub    $0x10,%rsp
  4271b0:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
  4271b4:    48 83 ff 03              cmp    $0x3,%rdi
  4271b8:    77 2d                    ja     4271e7 <_D3app2f1FS3app1SZi+0x3f>
  4271ba:    48 8d 05 a7 3f 02 00     lea    0x23fa7(%rip),%rax        # 44b168
<_D3app1S6__initZ+0x8>
  4271c1:    48 63 0c b8              movslq (%rax,%rdi,4),%rcx
  4271c5:    48 8d 04 01              lea    (%rcx,%rax,1),%rax
  4271c9:    ff e0                    jmpq   *%rax
  4271cb:    b8 0a 00 00 00           mov    $0xa,%eax
  4271d0:    c9                       leaveq 
  4271d1:    c3                       retq   
  4271d2:    b8 14 00 00 00           mov    $0x14,%eax
  4271d7:    c9                       leaveq 
  4271d8:    c3                       retq   
  4271d9:    b8 1e 00 00 00           mov    $0x1e,%eax
  4271de:    c9                       leaveq 
  4271df:    c3                       retq   
  4271e0:    b8 28 00 00 00           mov    $0x28,%eax
  4271e5:    c9                       leaveq 
  4271e6:    c3                       retq   
  4271e7:    b8 63 00 00 00           mov    $0x63,%eax
  4271ec:    c9                       leaveq 
  4271ed:    c3                       retq   
    ...


Dmd packs the whole struct into a single register (%rdi). Since the switch
statement contains consecutive cases, Dmd rightfully tries to skip as many of
them as possible by doing a single comparison (cmp $0x3,%rdi). However, this
comparison is performed on the whole register, which also contains the second
field of the Struct.

--


More information about the Digitalmars-d-bugs mailing list