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

--- Comment #14 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
When I'm testing a LoongArch patch, ext_dce seems removing a zero extension in
libcpp/expr.cc, causing stage 2 GCC miscompiled.  Before ext_dce:

(insn 110 108 115 14 (set (reg:DI 91 [ num$17 ])
        (zero_extend:DI (subreg:QI (reg:SI 134) 0)))
"../../gcc/libcpp/expr.cc":1968:17 discrim 6 129 {zero_extendqidi2}
     (expr_list:REG_DEAD (reg:SI 134)
        (nil)))

(insn 3472 1254 1255 145 (set (reg:DI 1530)
        (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1565:33 158
{*movdi_64bit}
     (nil))

(insn 1259 1258 134 145 (set (reg:DI 329 [ prephitmp_444 ])
        (zero_extend:DI (subreg/s/v:QI (reg:DI 1530) 0)))
"../../gcc/libcpp/expr.cc":1681:22 129 {zero_extendqidi2}
     (expr_list:REG_DEAD (reg:DI 1530)
        (nil))) 

But during ext_dce:

Processing insn:
  110: r91:DI=zero_extend(r134:SI#0)
      REG_DEAD r134:SI
Trying to simplify pattern:
(zero_extend:DI (subreg:QI (reg:SI 134) 0))
rescanning insn with uid = 110.
Successfully transformed to:
(subreg:DI (reg:SI 134) 0)

So insn 110 becomes:

(insn 110 108 115 14 (set (reg:DI 91 [ num$17 ])
        (subreg:DI (reg:SI 134) 0)) "../../gcc/libcpp/expr.cc":1968:17 discrim
6 158 {*movdi_64bit}
     (expr_list:REG_DEAD (reg:SI 134)
        (nil)))

But insn 3472 and 1259 are not changed (i.e. in 1259 the SUBREG_PROMOTED_VAR_P,
printed as "/s" isn't removed).  Subsequently the combine pass optimizes 1259
to:

(insn 1259 1258 134 145 (set (reg:DI 329 [ prephitmp_444 ])
        (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1681:22 158
{*movdi_64bit}
     (expr_list:REG_DEAD (reg:DI 294 [ num$17 ])
        (nil)))

And now we are doomed.  Either insn 110 shouldn't be changed or
SUBREG_PROMOTED_VAR_P in 1259 should be removed.  I see some code in ext-dce.cc
removing SUBREG_PROMOTED_VAR_P but it seems this case isn't caught.

I tried to make a reduced test case but failed.

Reply via email to