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

            Bug ID: 104582
           Summary: Unoptimal code for __negdi2 (and others) from libgcc2
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

Following testcase (taken from libgcc):

--cut here--
typedef          int DItype     __attribute__ ((mode (DI)));
typedef unsigned int UDItype    __attribute__ ((mode (DI)));
typedef          int TItype     __attribute__ ((mode (TI)));

#define Wtype   DItype
#define UWtype  UDItype
#define DWtype  TItype

#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
  struct DWstruct {Wtype high, low;};
#else
  struct DWstruct {Wtype low, high;};
#endif

typedef union
{
  struct DWstruct s;
  DWtype ll;
} DWunion;

DWtype
__negdi2 (DWtype u)
{
  const DWunion uu = {.ll = u};
  const DWunion w = { {.low = -uu.s.low,
                       .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };

  return w.ll;
}
--cut here--

compiles with -O2 on x86_64 to:

__negdi2:
        movq    %rdi, %rax
        negq    %rsi
        negq    %rax
        cmpq    $1, %rdi
        adcq    $-1, %rsi
        movq    %rax, %xmm0
        movq    %rsi, %xmm1
        punpcklqdq      %xmm1, %xmm0
        movaps  %xmm0, -24(%rsp)
        movq    -24(%rsp), %rax
        movq    -16(%rsp), %rdx
        ret

Please note the convoluted sequence to move the value at the end.

gcc-10 compiles the code to:

__negdi2:
        negq    %rsi
        movq    %rdi, %rax
        negq    %rax
        movq    %rsi, %rdx
        cmpq    $1, %rdi
        adcq    $-1, %rdx
        ret

Reply via email to