[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