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