https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103541
Bug ID: 103541 Summary: unnecessary spills around const functions calls Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: hubicka at gcc dot gnu.org Target Milestone: --- While looking into reasons why modref causes some code size increases I noticed that we produce unnecessary spill on x86-64 here: float a; __attribute__((const)) float foo (float); float test() { return a + foo(a) + a; } we load "a" into register and then spill it to stack because all SSE registers are clobbered by the call. This seems to happen somewhere between gcc 4.1 and 4.6. It is caused by: /* We can combine a reg def from one insn into a reg use in another over a call if the memory is readonly or the call const/pure. However, we can't set reg_equiv notes up for reload over any call. The problem is the equivalent form may reference a pseudo which gets assigned a call clobbered hard reg. When we later replace REG with its equivalent form, the value in the call-clobbered reg has been changed and all hell breaks loose. */ ret = valid_combine; if (!MEM_READONLY_P (memref) && !RTL_CONST_OR_PURE_CALL_P (insn)) return valid_none; in ira.c:validate_equiv_mem If I read the comment correctly it is afraid of the address of memory reading being altered by the call (using call clobbered registers). But here it is a constant, so perhaps we can just rule this out when MEM rtx does not mention registers or does not mention any callee clobbered registers?