https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121483
Bug ID: 121483 Summary: m68k: Suboptimal handling of 64bit values Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ad...@tho-otto.de Target Milestone: --- Seems like handling of long long 64bit arithmetic has regressed in newer versions of the compiler for m68k. In gcc 4.6.4, the simple function unsigned long long test(unsigned long long x) { return (x >> 1) | 0x8000000000000000ULL; } when compiled with -O2 -fomit-frame-pointer, produced move.l 4(%sp),%d0 move.l 8(%sp),%d1 lsr.l #1,%d0 roxr.l #1,%d1 bset #31,%d0 rts In gcc 7 and later, the produced code is move.l %d3,-(%sp) move.l %d2,-(%sp) move.l 12(%sp),%d2 move.l 16(%sp),%d3 lsr.l #1,%d2 roxr.l #1,%d3 move.l %d2,%d0 bset #31,%d0 move.l %d3,%d1 move.l (%sp)+,%d2 move.l (%sp)+,%d3 rts Bisecting gave me this commit https://github.com/gcc-mirror/gcc/commit/27508f5fa3c79ca39d32079348017c6132d25722 as cause for the change. In gcc 15.1.0, code has become even worse: move.l %d3,-(%sp) move.l %d2,-(%sp) move.l 12(%sp),%d0 move.l 16(%sp),%d1 move.l %d0,%d2 move.l %d1,%d3 lsr.l #1,%d2 roxr.l #1,%d3 move.l %d2,%a0 move.l %d3,%a1 move.l %d2,%d0 bset #31,%d0 move.l %a1,%d1 move.l (%sp)+,%d2 move.l (%sp)+,%d3 rts (note the additional, completely unnecessary stores to a0/a1)