https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125596

            Bug ID: 125596
           Summary: i386: redundant register swapping with TImode values
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kim.kuparinen at tuni dot fi
  Target Milestone: ---

After commit https://gcc.gnu.org/g:8911879415d6c2a7baad88235554a912887a1c5c,
code such as

typedef struct Point {
    long x;
    long y;
} Point;

long takes_point_struct(Point p);

long calls_point_struct(long x, long y)
{
    return takes_point_struct((Point){.x = x, .y = y});
}

when compiled with -O2 -c on x86_64 produces

0000000000000000 <calls_point_struct>:
   0:   48 87 fe                xchg   %rdi,%rsi
   3:   48 89 f0                mov    %rsi,%rax
   6:   48 89 fe                mov    %rdi,%rsi
   9:   48 89 c7                mov    %rax,%rdi
   c:   e9 00 00 00 00          jmp    11 <calls_point_struct+0x11>

where the first four instructions just swap %rdi and %rsi with xchg and then
swap them back with regular moves. Without the above commit, GCC produces

0000000000000000 <calls_point_struct>:
   0:   e9 00 00 00 00          jmp    5 <calls_point_struct+0x5>

which is also what Debian clang 16.0.6 (15~deb12u1) produces. Initially found
on Debian gcc 14.2.0-19, but issue persists in current master,
https://gcc.gnu.org/g:0d82756a365ee6189af4490345bc0d2595007c84 as of reporting.

The commit in question references bug 88873 and only touches i386 code.

Reply via email to