https://issues.dlang.org/show_bug.cgi?id=15538
--- Comment #7 from aneas <[email protected]> --- 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. --
