Bug 6767 – Range case statements generate horrific code

Status
RESOLVED
Resolution
WORKSFORME
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2011-10-04T10:43:00Z
Last change time
2015-08-24T05:01:45Z
Assigned to
nobody
Creator
peter.alexander.au

Comments

Comment #0 by peter.alexander.au — 2011-10-04T10:43:04Z
int foo(int n) { switch (n) { case 0: .. case 255: return 0; default: return 1; } } Compiled with all optimisation (-O -inline -release) in DMD 2.055, I get the following code generated (it's the same without optimisation, too): _D4test3fooFiZi: 00001bb4 pushl %ebp 00001bb5 movl %esp,%ebp 00001bb7 pushl %eax 00001bb8 testl %eax,%eax 00001bba je 0x00002571 00001bc0 cmpl $0x01,%eax 00001bc3 je 0x00002571 00001bc9 cmpl $0x02,%eax 00001bcc je 0x00002571 00001bd2 cmpl $0x03,%eax 00001bd5 je 0x00002571 00001bdb cmpl $0x04,%eax 00001bde je 0x00002571 00001be4 cmpl $0x05,%eax 00001be7 je 0x00002571 ... for all 256 values ... 0000255a cmpl $0x000000fd,%eax 0000255f je 0x00002571 00002561 cmpl $0x000000fe,%eax 00002566 je 0x00002571 00002568 cmpl $0x000000ff,%eax 0000256d je 0x00002571 0000256f jmp 0x00002577 00002571 movl %ebp,%esp 00002573 xorl %eax,%eax 00002575 popl %ebp 00002576 ret 00002577 movl %ebp,%esp 00002579 movl $0x00000001,%eax 0000257e popl %ebp 0000257f ret Essentially, it has generated a massive O(n) function for what should be a couple of compares if not better.
Comment #1 by hsteoh — 2015-08-24T05:01:45Z
This seems to have been fixed in git HEAD. Tested on Linux/64-bit, compile with dmd -O. The function compiles to: ------ 0000000000000000 <_D4test3fooFiZi>: 0: 55 push %rbp 1: 48 8b ec mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: 48 81 ff ff 00 00 00 cmp $0xff,%rdi f: 77 0e ja 1f <_D4test3fooFiZi+0x1f> 11: ff 24 fd 00 00 00 00 jmpq *0x0(,%rdi,8) 18: 31 c0 xor %eax,%eax 1a: 48 8b e5 mov %rbp,%rsp 1d: 5d pop %rbp 1e: c3 retq 1f: b8 01 00 00 00 mov $0x1,%eax 24: 48 8b e5 mov %rbp,%rsp 27: 5d pop %rbp 28: c3 retq 29: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) ------ Which is probably close to optimal. At least, it no longer produces the O(n) nastiness. :-)