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.

Reply via email to