Bug 49054 - useless cmp+jmp generated for switch when "default:" is unreachable
Summary: useless cmp+jmp generated for switch when "default:" is unreachable
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.6.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2011-05-18 21:44 UTC by Alexandre Duret-Lutz
Modified: 2015-08-20 09:52 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-07-24 20:46:29


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexandre Duret-Lutz 2011-05-18 21:44:18 UTC
gcc (Debian 4.6.0-7) 4.6.1 20110507 (prerelease)

When I compile the following switch, GCC generates code to 
check that id <= 4 and to conditionally jump to... the next instruction.


% cat foo.c
unsigned f(void);
unsigned g(void);
unsigned h(void);
unsigned i(void);
unsigned j(void);

unsigned int baz(unsigned int id)
{
  switch (id)
    {
    case 0:
      return f();
    case 1:
      return g();
    case 2:
      return h();
    case 3:
      return i();
    case 4:
      return j();
    default:
      __builtin_unreachable();
    }
}
% gcc -march=core2 -m64 -O3 foo.c -c -o foo.o
% objdump -DC foo.o | head -23

foo.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <baz>:
   0:   83 ff 05                cmp    $0x4,%edi
   3:   76 03                   jbe    8 <baz+0x8>
   5:   0f 1f 00                nopl   (%rax)
   8:   89 ff                   mov    %edi,%edi
   a:   ff 24 fd 00 00 00 00    jmpq   *0x0(,%rdi,8)
  11:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  18:   e9 00 00 00 00          jmpq   1d <baz+0x1d>
  1d:   0f 1f 00                nopl   (%rax)
  20:   e9 00 00 00 00          jmpq   25 <baz+0x25>
  25:   0f 1f 00                nopl   (%rax)
  28:   e9 00 00 00 00          jmpq   2d <baz+0x2d>
  2d:   0f 1f 00                nopl   (%rax)
  30:   e9 00 00 00 00          jmpq   35 <baz+0x35>
  35:   0f 1f 00                nopl   (%rax)
  38:   e9 00 00 00 00          jmpq   3d <baz+0x3d>


What is the point of the first three instructions?  I would have expected baz to start at adress 8.
Comment 1 Andrew Pinski 2011-05-18 22:09:25 UTC
a mips64-linux-gnu gcc produces wrong code for this testcase, removing the whole jump table.
Comment 2 Richard Biener 2011-05-19 08:56:11 UTC
I think this is just an artifact of how we handle __builtin_unreachable ().
Comment 3 Andrew Pinski 2011-07-24 20:46:29 UTC
Confirmed.
Comment 4 Eric Botcazou 2011-11-22 11:37:38 UTC
The CFG cleanup code should be enhanced to deal with this.
Comment 5 Johannes Pfau 2015-08-20 09:52:10 UTC
This would also be useful for the GDC frontend. There's a `final switch` statement which forces the developer to handle all possible cases. Would be nice if we could get rid of the `cmp` check for these `final switch` statements.