https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51954
--- Comment #7 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Hongtao.liu from comment #5)
> >
> > Yes, neg rdx = (0 - rdx) = (0 - (rdx + CF)(last def)) = (sbb 0, rdx)
>
> And we need an extra register for it.
The patch in Comment #6 does a conversion, but only when a move is also found.
I have tried to peephole2 with a new temporary, but an additional move to a
temporary besides clearing xor was needed in that case. So the following
testcae:
--cut here--
#ifdef __x86_64__
#define TYPE __int128
#else
#define TYPE long long
#endif
TYPE bar (TYPE x)
{
return -x;
}
--cut here--
when compiled with -O2 -m32 -mregparm=3 leaves unconverted the sequence:
negl %eax
adcl $0, %edx
negl %edx
but generates:
movl 4(%esp), %eax
xorl %edx, %edx
negl %eax
sbbl 8(%esp), %edx
without -mregparm.