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.