https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124079

--- Comment #1 from Stefan Schulze Frielinghaus <stefansf at gcc dot gnu.org> 
---
A slightly smaller reproducer is

int foo (const char *a, const char *b)
{
  return __builtin_strcmp (a, b);
}

(insn 17 10 18 2 (parallel [
            (set (reg/i:DI 2 %r2)
                (sign_extend:DI (unspec:SI [
                            (reg:CCU 33 %cc)
                        ] UNSPEC_STRCMPCC_TO_INT)))
            (clobber (reg:CC 33 %cc))
        ]) "t.c":4:1 2022 {*cmpint_sign}
     (expr_list:REG_DEAD (reg:CCU 33 %cc)
        (expr_list:REG_UNUSED (reg:CC 33 %cc)
            (nil))))

(define_insn_and_split "*cmpint_sign"
  [(set (match_operand:DI 0 "register_operand" "=d")
        (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand"
"0")]
                                   UNSPEC_STRCMPCC_TO_INT)))
   (clobber (reg:CC CC_REGNUM))]
  "TARGET_ZARCH"
  "#"
  "&& reload_completed"
  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
   (parallel
    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
     (clobber (reg:CC CC_REGNUM))])])

Insn 17 leads to a reload because operand 1 matches operand 0 and the hard regs
differ.  So we end up in match_reload() where in_rtx equals (reg:CCU 33 %cc)
and out_rtx equals (reg/i:DI 2 %r2) which means the modes differ and we end up
in the else branch:

     else
       {
         reg = new_out_reg
           = lra_create_new_reg_with_unique_value (outmode, out_rtx,
                                                   goal_class,
                                                   exclude_start_hard_regs,
                                                   "");
         new_in_reg = get_matching_reload_reg_subreg (inmode, reg);

and try to create a subreg with inner mode DI and outer mode CCU (mode size ==
4 bytes).  Partially reverting r16-7464 by using gen_lowpart_SUBREG (mode, reg)
instead of gen_rtx_SUBREG (mode, reg, 0) in get_matching_reload_reg_subreg()
solves this and we end up with new_in_reg == (subreg:CCU (reg:DI 71) 4) which
looks good to me.  However, I haven't looked into PR121191 and how this
interferes with that so far.

Reply via email to