https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113701
Bug ID: 113701 Summary: Issues with __int128 argument passing Product: gcc Version: 14.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: --cut here-- typedef unsigned __int128 U; U f0 (U x, U y) { return x + y; } U f1 (U x, U y) { return x - y; } U f2 (U x, U y) { return x | y; } int f3 (U x, U y) { return x == y; } int f4 (U x, U y) { return x < y; } --cut here-- shows some issues with __int128 parameter passing. gcc -O2: f0: movq %rdx, %rax movq %rcx, %rdx addq %rdi, %rax adcq %rsi, %rdx ret f1: xchgq %rdi, %rsi movq %rdx, %r8 movq %rsi, %rax movq %rdi, %rdx subq %r8, %rax sbbq %rcx, %rdx ret f2: xchgq %rdi, %rsi movq %rdx, %rax movq %rcx, %rdx orq %rsi, %rax orq %rdi, %rdx ret f3: xchgq %rdi, %rsi movq %rdx, %r8 movq %rcx, %rax movq %rsi, %rdx movq %rdi, %rcx xorq %rax, %rcx xorq %r8, %rdx xorl %eax, %eax orq %rcx, %rdx sete %al ret f4: xorl %eax, %eax cmpq %rdx, %rdi sbbq %rcx, %rsi setc %al ret Functions f0 and f4 are now optimal. Functions f1, f2 and f3 emit extra XCHG, but the swap should be propagated to MOV instructions instead. The most problematic function is f3, which regressed noticeably from gcc-12.3: f3: xorq %rdx, %rdi xorq %rcx, %rsi xorl %eax, %eax orq %rsi, %rdi sete %al ret