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: [email protected]
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)