<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 - Suboptimal atomic_fetch_sub"
   href="https://bugs.llvm.org/show_bug.cgi?id=37025">37025</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Suboptimal atomic_fetch_sub
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>6.0
          </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>Backend: X86
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>nruslan_devel@yahoo.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Normally, clang/llvm is capable of recognizing atomic_fetch_sub(obj, 1) == 1
pattern by replacing more general 'lock xadd' instruction with 'lock sub' since
if new result is zero it can be obtained from the ZF flag directly.

However, in the following example (which introduces an extra condition) it does
not optimize it as expected:

test.c:

#include <stdatomic.h>
#include <stdbool.h>

void func2();

void func(_Atomic(unsigned long) * obj, void * obj2)
{
        if (atomic_fetch_sub(obj, 1) == 1 && obj2)
                func2();
}

/opt/llvm/bin/clang -Wall -O2 -S test.c

generates the following code (note that it re-ordered comparisons):

func:                                   # @func
        .cfi_startproc
# %bb.0:
        movq    $-1, %rax
        lock            xaddq   %rax, (%rdi)
        testq   %rsi, %rsi
        je      .LBB0_2
# %bb.1:
        cmpq    $1, %rax
        jne     .LBB0_2
# %bb.3:
        xorl    %eax, %eax
        jmp     func2                   # TAILCALL
.LBB0_2:
        retq</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>