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

            Bug ID: 88233
           Summary: combine fails to merge insns leaving unneeded reg
                    copies
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bergner at gcc dot gnu.org
  Target Milestone: ---

bergner@pike:~/gcc/BUGS/PR69493$ cat test.i
typedef struct { double a[2]; } A;
A
foo (const A *a)
{
  return *a;
}
bergner@pike:~$ .../xgcc -B.../gcc -O2 -S test.i
bergner@pike:~$ cat test.s 
        ld 10,0(3)
        ld 11,8(3)
        mtvsrd 1,10
        mtvsrd 2,11
        blr

Entering combine, we have the following rtl:
...
insn 6 3 9 2 (set (reg:TI 121 [ D.2829 ])
        (mem:TI (reg/v/f:DI 124 [ aD.2825 ]) [1 *a_2(D)+0 S16 A64]))
"test.i":5:10 1048 {*vsx_le_perm_load_ti}
     (expr_list:REG_DEAD (reg/v/f:DI 124 [ aD.2825 ])
        (nil)))
(insn 9 6 10 2 (set (reg:DF 122 [ <retval> ])
        (subreg:DF (reg:TI 121 [ D.2829 ]) 0)) "test.i":5:10 515
{*movdf_hardfloat64}
     (nil))
(insn 10 9 14 2 (set (reg:DF 123 [ <retval>+8 ])
        (subreg:DF (reg:TI 121 [ D.2829 ]) 8)) "test.i":5:10 515
{*movdf_hardfloat64}
     (expr_list:REG_DEAD (reg:TI 121 [ D.2829 ])
        (nil)))
...

Combine should be able to merge insn 6 with both insn 9 and insn 10 to produce:

(insn ... (set (reg:DF 122)
               (mem:DF (reg:DI 124))
(insn ... (set (reg:DF 123)
               (mem:DF (plus:DI (reg:DI 124)
                                (const_int 8)))

By not merging them, we end up with two unneeded register copies we cannot
remove.

Reply via email to