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

Reply via email to