<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - tail duplication failed to happen when BB's pred (within the same loop) has >1 succ"
   href="https://bugs.llvm.org/show_bug.cgi?id=33270">33270</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>tail duplication failed to happen when BB's pred (within the same loop) has >1 succ
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </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>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>danielcdh@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>For the following testcase, gcc managed to tail-duplicate the loop header to
make the loop more efficient (when the call pattern is foo-bar-foo-bar, the
gcc-generated-code saves 2 taken branches every foo-bar call pair.

The issue is that llvm will not duplicate a BB if any of BB's predecessor
(within the same loop) has multiple successors. As a result, the loop header
will not be duplicated if it contains a "continue" in the loop body.

$cat test.cc
void foo();
void bar();
bool test1();
bool test2();
void func() {
  while (1) {
    if (__builtin_expect(test1(), 0)) {
      foo();
    } else {
      if (test2())
        continue;
      bar();
    }
  }
}


$clang -O2 -fno-unroll-loops -S test.cc  -o - -mllvm
-tail-dup-placement-threshold=50

        .text
        .file   "test.cc"
        .globl  _Z4funcv                # -- Begin function _Z4funcv
        .p2align        4, 0x90
        .type   _Z4funcv,@function
_Z4funcv:                               # @_Z4funcv
        .cfi_startproc
# BB#0:
        pushq   %rax
.Lcfi0:
        .cfi_def_cfa_offset 16
        jmp     .LBB0_1
        .p2align        4, 0x90
.LBB0_4:                                #   in Loop: Header=BB0_1 Depth=1
        callq   _Z3barv
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        callq   _Z5test1v
        testb   %al, %al
        jne     .LBB0_2
# BB#3:                                 #   in Loop: Header=BB0_1 Depth=1
        callq   _Z5test2v
        testb   %al, %al
        jne     .LBB0_1
        jmp     .LBB0_4
.LBB0_2:                                #   in Loop: Header=BB0_1 Depth=1
        callq   _Z3foov
        jmp     .LBB0_1
.Lfunc_end0:
        .size   _Z4funcv, .Lfunc_end0-_Z4funcv
        .cfi_endproc
                                        # -- End function

        .ident  "clang version 5.0.0 (trunk 304371)"
        .section        ".note.GNU-stack","",@progbits


$g++ -O2 -fno-unroll-loops -S test.cc -o -
        .file   "test.cc"
        .text
        .p2align 4,,15
        .globl  _Z4funcv
        .type   _Z4funcv, @function
_Z4funcv:
.LFB0:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        .p2align 5,,20
        .p2align 3
.L2:
        call    _Z5test1v
        testb   %al, %al
        jne     .L7
.L3:
        call    _Z5test2v
        testb   %al, %al
        jne     .L2
        call    _Z3barv
        call    _Z5test1v
        testb   %al, %al
        je      .L3
.L7:
        call    _Z3foov
        jmp     .L2
        .cfi_endproc
.LFE0:
        .size   _Z4funcv, .-_Z4funcv
        .ident  "GCC: (GNU) 4.9.x-google 20150123 (prerelease)"
        .section        .note.GNU-stack,"",@progbits</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>