<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Fail to generate indirect jmp with memory operand (for tail call)"
   href="http://llvm.org/bugs/show_bug.cgi?id=16010">16010</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Fail to generate indirect jmp with memory operand (for tail call)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Backend: X86
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>silvas@purdue.edu
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>We could fold a load + indirect jump through reg into just an indirect jump
through memory.

typedef void fn(int reg, int *pc);
fn *dispatch_tab[0xFF];
void test_no_mem_indirect_jmp_tail(int reg, int *pc) {
  (*dispatch_tab[pc[0] & 0xFF])(reg, pc);
}

0000000000000000 <test_no_mem_indirect_jmp_tail>:
   0:   8b 06                   mov    eax,DWORD PTR [rsi]
   2:   0f b6 c0                movzx  eax,al
   5:   48 8b 04 c5 00 00 00 00 mov    rax,QWORD PTR [rax*8+0x0]
   d:   ff e0                   jmp    rax


We could replace:
   5:   48 8b 04 c5 00 00 00 00 mov    rax,QWORD PTR [rax*8+0x0]
   d:   ff e0                   jmp    rax

With:
        ff 24 c5 00 00 00 00    jmp    QWORD PTR [rax*8+0x0]

Interestingly enough, GCC (4.7.3) fails to form the indirect-through-memory jmp
as well.


Also, we form an indirect-through-memory call in the same situation when there
is no tail call (GCC does too):

extern void use(int*);
typedef void fn(int reg, int *pc);
fn *dispatch_tab[0xFF];
void test_no_mem_indirect_jmp_notail(int reg, int *pc) {
  (*dispatch_tab[pc[0] & 0xFF])(reg, pc);
  use(pc);
}


0000000000000000 <test_no_mem_indirect_jmp_notail>:
   0:   53                      push   rbx
   1:   48 89 f3                mov    rbx,rsi
   4:   8b 03                   mov    eax,DWORD PTR [rbx]
   6:   0f b6 c0                movzx  eax,al
   9:   ff 14 c5 00 00 00 00    call   QWORD PTR [rax*8+0x0]       <----
  10:   48 89 df                mov    rdi,rbx
  13:   5b                      pop    rbx
  14:   e9 00 00 00 00          jmp    19
<test_no_mem_indirect_jmp_notail+0x19>

Tested with clang built from trunk on Apr 20, 2013. (this is all with -O2
and -O3)</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>