https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93990
Bug ID: 93990 Summary: [x86] Silly code generation for _addcarry_u32/_addcarry_u64 Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: lloyd at randombit dot net Target Milestone: --- Bug 67317 has regressed, starting in GCC 6 Same test case as 67317: #include <x86intrin.h> #include <stdint.h> unsigned long long testcarry(unsigned long long a, unsigned long long b, unsigned long long c, unsigned long long d) { unsigned long long result0, result1; _addcarry_u64(_addcarry_u64(0, a, c, &result0), b, d, &result1); return result0 ^ result1; } GCC 5.4.1 (only) produces the expected output .cfi_startproc addq %rdi, %rdx # a, tmp99 adcq %rsi, %rcx # b, tmp107 movq %rdx, %rax # tmp99, D.28638 xorq %rcx, %rax # tmp107, D.28638 ret .cfi_endproc GCC 6.4.1, 7.4.1, 8.3.0 and 9.2.0 all produce variations on this [GCC 9.2.0 output here]: .cfi_startproc subq $40, %rsp #, .cfi_def_cfa_offset 48 # adx.cpp:5: { movq %fs:40, %rax # MEM[(<address-space-1> long unsigned int *)40B], tmp107 movq %rax, 24(%rsp) # tmp107, D.33144 xorl %eax, %eax # tmp107 # /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/adxintrin.h:69: return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P); addq %rdx, %rdi # tmp105, tmp93 movq %rsi, %rax # tmp104, tmp104 setc %r8b #, _12 movq %rdi, 8(%rsp) # tmp93, addb $-1, %r8b #, _12 adcq %rcx, %rax # tmp106, tmp104 movq %rax, 16(%rsp) # tmp97, # adx.cpp:8: return result0 ^ result1; xorq %rdi, %rax # tmp93, <retval> # adx.cpp:9: } movq 24(%rsp), %rdx # D.33144, tmp109 xorq %fs:40, %rdx # MEM[(<address-space-1> long unsigned int *)40B], tmp109 jne .L5 #, addq $40, %rsp #, .cfi_remember_state .cfi_def_cfa_offset 8 ret All were compiled with -O3. I checked 9.2.0 output with -O and -O2 as well, with no significant change.