https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39723
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com Assignee|unassigned at gcc dot gnu.org |vmakarov at redhat dot com --- Comment #8 from Jeffrey A. Law <law at redhat dot com> --- Vlad, this looks like a register allocation issue to me. Using the current trunk configured for v850-elf, compiling the testcase from c#0 with -O2 and comparing it to the pre-cond-optab merge, I see that we're not coalescing some of the allocnos as aggressively as perhaps we should. Let's start with a13 and a17 and work backwards from their hard register assignments: Popping a13(r46,l0) -- assign reg 12 Popping a17(r53,l0) -- assign reg 10 These registers are related by a "copy" if we look up a bit in the .ira dump: Forming thread by copy 0:a13r46-a17r53 (freq=125): Result (freq=7000): a13r46(5000) a17r53(2000) cp0:a13(r46)<->a17(r53)@125:shuffle Looking at the conflicts: ;; a13(r46,l0) conflicts: a1(r68,l0) a0(r69,l0) a2(r70,l0) a4(r42,l0) a5(r67,l0) a6(r66,l0) a14(r62,l0) a15(r61,l0) a16(r60,l0) ;; total conflict hard regs: ;; conflict hard regs: ;; a17(r53,l0) conflicts: a2(r70,l0) a4(r42,l0) a5(r67,l0) a6(r66,l0) ;; total conflict hard regs: ;; conflict hard regs: Failing to allocate these two registers to r10 results in a 3-operand add (2 bytes longer) and an unnecessary move (2 bytes). Fixing that would appear to eliminate the regression. For reference, the add insn is defined as: (define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r") (match_operand:SI 2 "nonmemory_operand" "rJ,K,U"))) (clobber (reg:CC CC_REGNUM))] Alternative 0 is preferred whenever possible as it allows us to generate the shorter add instruction. I'd appreciate if you could investigate when you have the opportunity.