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

            Bug ID: 122335
           Summary: RTL ifcvt  vs copy propagation
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

This testcase originally from pr67635 when compiled with -march=rv64gcb_zicond
-O2 on riscv64 shows an annoying bad interaction between copy propagation and
if-conversion.

int test_05_3 (int x)
{
  return x > 0 ? x + 1 : x;
}

This is just a conditional increment, so an addcc like sequence should be
sufficient (sgt+add on riscv).  Yet we actually get:

        sgt     a5,a0,zero      # 30    [c=4 l=4]  *sgt_didi
        addiw   a4,a0,1 # 28    [c=8 l=4]  addsi3_extended/1
        czero.eqz       a4,a4,a5        # 31    [c=4 l=4]  *czero.eqz.didi
        czero.nez       a0,a0,a5        # 32    [c=4 l=4]  *czero.nez.didi
        add     a0,a0,a4        # 18    [c=4 l=4]  *adddi3/0

The root of the problem is ifcvt thinks the true block of the conditional is
not "simple" because of an extraneous copy:

(insn 9 8 11 3 (set (reg:DI 137)
        (sign_extend:DI (plus:SI (subreg/s/u:SI (reg/v:DI 135 [ x ]) 0)
                (const_int 1 [0x1])))) "j.c":72:24 discrim 1 6
{addsi3_extended}
     (expr_list:REG_DEAD (reg/v:DI 135 [ x ])
        (nil)))
(insn 11 9 24 3 (set (reg:DI 134 [ <retval> ])
        (reg:DI 137)) "j.c":72:24 discrim 1 275 {*movdi_64bit}
     (nil))



We can safely replace the destination of insn 9 with (reg 134) which in turn
would make insn 11 dead and that block would become simple in the eyes of ifcvt
allowing direct generation of an addcc style sequence rather than a conditional
move style sequence.

Reply via email to