https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116932
Kazumoto Kojima <kkojima at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kkojima at gcc dot gnu.org --- Comment #1 from Kazumoto Kojima <kkojima at gcc dot gnu.org> --- This was floating around in my list for a while. It's simply experimental, but I would like to send it here anyway. I've been looking into pr64661-[23].c regressions. As Oleg commented, LRA unexpectedly reloads the hard gbr with a general reg. First I tried to stop that reload with predicates and constraints, but all attempts were unsuccessful. OTOH, LRA leaves gbr reg in the raw gbr memory pattern like (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4]))) I defined an early splitter and an insn (define_split [(set (match_operand:QIHISI 0 "arith_reg_dest") (match_operand:QIHISI 1 "gbr_address_mem")) (set (match_dup 1) (unspec:QIHISI [(FETCHOP:QIHISI (match_dup 1) (match_operand:QIHISI 2 "<fetchop_predicate_1>"))] UNSPEC_ATOMIC)) (clobber (reg:SI R0_REG)) (clobber (scratch:QIHISI))] "TARGET_ATOMIC_SOFT_IMASK && sh_lra_p () && ! lra_in_progress && ! reload_completed" [(const_int 0)] { rtx addr = XEXP (operands[1], 0); rtx disp = GET_CODE (addr) == PLUS ? XEXP (addr, 1) : const0_rtx; emit_insn (gen_atomic_fetch_<fetchop_name><mode>_soft_imask_g ( operands[0], disp, operands[2])); }) (define_insn "atomic_fetch_<fetchop_name><mode>_soft_imask_g" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") (mem:QIHISI (plus:SI (reg:SI GBR_REG) (match_operand:SI 1 "gbr_displacement" "")))) (set (mem:QIHISI (plus:SI (reg:SI GBR_REG) (match_dup 1))) (unspec:QIHISI [(FETCHOP:QIHISI (mem:QIHISI (plus:SI (reg:SI GBR_REG) (match_dup 1))) (match_operand:QIHISI 2 "<fetchop_predicate_1>" "<fetchop_constraint_1_imask>"))] UNSPEC_ATOMIC)) (const_int 0) (clobber (reg:SI R0_REG)) (clobber (match_scratch:QIHISI 3 "=&r"))] "TARGET_ATOMIC_SOFT_IMASK && sh_lra_p ()" { return "\r stc sr,r0" "\n" " mov r0,%3" "\n" " or #0xF0,r0" "\n" " ldc r0,sr" "\n" " mov.<bwl> @(%O1,gbr),r0" "\n" " mov r0,%0" "\n" " <fetchop_name> %2,r0" "\n" " mov.<bwl> r0,@(%O1,gbr)" "\n" " ldc %3,sr"; } [(set_attr "length" "18")]) so as to let LRA pass gbr through. The extra (const_int 0) in the latter is to avoid recursive splitting. Similar splitters and insns can fix 64661-[23].c tests, though I'm not sure whether it's acceptable or not.