https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104110
Bug ID: 104110 Summary: AArch64 unnecessary use of call-preserved register Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: nate at thatsmathematics dot com Target Milestone: --- gcc misses an optimization (or in some sense deoptimizes) by using a call-preserved register to save a trivial constant across a function call. Source code: void bar(unsigned); unsigned foo(unsigned c) { bar(1U << c); return 1; } Output from gcc -O3 on AArch64: foo: stp x29, x30, [sp, -32]! mov x29, sp str x19, [sp, 16] mov w19, 1 lsl w0, w19, w0 bl bar mov w0, w19 ldr x19, [sp, 16] ldp x29, x30, [sp], 32 ret Note that x19 is used unnecessarily to save the constant 1 across the function call, causing an unnecessary push and pop. It would have been better to just use some call-clobbered register for the constant 1 before the function call, and then a simple `mov w0, 1` afterward.\ Same behavior with -O, -O2, -Os. Tested on godbolt, affects yesterday's trunk and all the way back to 5.4. Might be related to bug 70801 or bug 71768 but I am not sure.