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