https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127264
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Haochen Jiang from comment #4)
> (In reply to Jakub Jelinek from comment #2)
> > Anyway, the RTL patterns look just weird:
> > (define_insn "tilezero"
> > [(set (reg:V32SI TMM_REGNUM)
> > (unspec_volatile:V32SI
> > [(match_operand:QI 0 "const_0_to_7_operand")]
> > UNSPECV_TILEZERO))]
> > "TARGET_ACEV1"
> > "tilezero\t{%%tmm%c0|tmm%c0}"
> > [(set_attr "prefix" "vex")])
> > That is as if there is just one TMM_REGNUM register fully set by the
> > instruction, but it seems that there are 8 of the tmm registers (and each of
> > those is 8192 bit, so that would be V256SI)?
>
> tilezero should only zero the corresponding tmm register, not all tmm
> registers. That operand is for the reg number want to be zeroed.
Yes, but the above representation pretends that there is just one tmm register
and that it sets it to something. So, say if you set one %tmm1 to something
and then tilezero on %tmm0, then RTL DCE could optimize the first store away.
Either you need 8 tmm registers in RTL too, and (set (reg:V256SI
TMM_FIRST_REGNUM + 1) (V256SI zero)), or, if all the tmm regs are (incorrectly)
represented by a single TMM_REGNUM, I think safer representation would be (set
(reg:BLK TMM_REGNUM) (unspec_volatile:BLK [(reg:BLK TMM_REGNUM)
(match_operand:QI 0 "const_0_to_7_operand")] UNSPECV_TILEZERO)). You have some
large set of registers and you change something in it.