https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70821

            Bug ID: 70821
           Summary: x86_64: __atomic_fetch_add/sub() uses XADD rather than
                    DECL in some cases
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dhowells at redhat dot com
  Target Milestone: ---

Created attachment 38346
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38346&action=edit
Test program

__atomic_fetch_add/sub() uses XADD rather than DECL when subtracting 1 from the
counter if the result is acted upon, but where this could be done through the
condition flags.  For instance:

   static __always_inline bool atomic_sub_and_test(int i, atomic_t *v)
   {
      return __atomic_sub_fetch(&v->counter, i, __ATOMIC_SEQ_CST);
   }

   const char *test_atomic_dec_and_test(atomic_t *counter)
   {
      if (atomic_sub_and_test(1, counter))
         return "foo";
      return "bar";
   }

produces:

  17:   83 c8 ff                or     $0xffffffff,%eax
  1a:   f0 0f c1 07             lock xadd %eax,(%rdi)
  1e:   ba 00 00 00 00          mov    $0x0,%edx
  23:   ff c8                   dec    %eax
  25:   b8 00 00 00 00          mov    $0x0,%eax
  2a:   48 0f 44 c2             cmove  %rdx,%rax
  2e:   c3                      retq   

when it should produce something more like this, which I get when adding 1
instead of subtracting 1, but with a DECL rather than an INCL:

  46:   f0 ff 07                lock incl (%rdi)
  49:   ba 00 00 00 00          mov    $0x0,%edx
  4e:   b8 00 00 00 00          mov    $0x0,%eax
  53:   48 0f 44 c2             cmove  %rdx,%rax
  57:   c3                      retq   

Note that adding or subtracting 2 and testing the zeroness of the result gives
SUBL/ADDL as expected.  If the result is not tested, DECL is generated as
expected:

  13:   f0 ff 0f                lock decl (%rdi)
  16:   c3                      retq   

See the attached test program.

This is the case for both:

    gcc version 5.3.1 20151207 (Red Hat 5.3.1-2) (GCC)
    gcc version 6.0.0 20160219 (Red Hat Cross 6.0.0-0.1) (GCC)

The following version of gcc:

    gcc version 4.8.5 20150623 (Red Hat 4.8.5-2.x) (GCC) 

also produces XADD rather than INCL/DECL/ADDL/SUBL if the result is looked at
at all.

Reply via email to