Hongtao Liu <crazy...@gmail.com> writes: > On Mon, Jan 18, 2021 at 6:18 PM Richard Sandiford > <richard.sandif...@arm.com> wrote: >> >> Hongtao Liu via Gcc-patches <gcc-patches@gcc.gnu.org> writes: >> > Hi: >> > If SRC had been assigned a mode narrower than the copy, we can't link >> > DEST into the chain even they have same >> > hard_regno_nregs(i.e. HImode/SImode in i386 backend). >> >> In general, changes between modes within the same hard register are OK. >> Could you explain in more detail what's going wrong? >> > > cprop hardreg change > > (insn 457 499 460 33 (set (reg:SI 39 r11 [orig:86 _11 ] [86]) > (reg:SI 37 r9 [orig:86 _11 ] [86])) "test.c":29:36 75 > {*movsi_internal} > (expr_list:REG_DEAD (reg:SI 37 r9 [orig:86 _11 ] [86]) > (nil))) > > to > > (insn 457 499 460 33 (set (reg:SI 39 r11 [orig:86 _11 ] [86]) > (reg:SI 22 xmm2 [orig:86 _11 ] [86])) "test.c":29:36 75 > {*movsi_internal} > (expr_list:REG_DEAD (reg:SI 22 xmm2 [orig:86 _11 ] [86]) > (nil))) > > since (reg:SI 22 xmm2) and (reg:SI r9) are in the same value chain in > which the oldest regno is k0. > > but with xmm2 defined as > > kmovw %k0, %edi # 69 [c=4 l=4] *movhi_internal/6----- kmovw move the > lower 16bits to %edi, and clear the upper 16 bits. > vmovd %edi, %xmm2 # 489 *movsi_internal --- vmovd move 32bits from > %edi to %xmm2. > > (insn 69 68 70 12 (set (reg:HI 5 di [orig:96 _52 ] [96]) > (reg:HI 68 k0 [orig:82 var_6.0_1 ] [82])) "test.c":21:23 76 > {*movhi_internal} > (nil)) > > (insn 489 75 78 12 (set (reg:SI 22 xmm2 [297]) > (reg:SI 5 di [orig:96 _52 ] [96])) 75 {*movsi_internal} > (nil))
The sequence is OK in itself, but insn 489 can't make any assumptions about what's in the upper 16 bits of %edi. In other words, as far as RTL semantics are concerned, insn 489 only leaves bits 0-15 of %xmm2 with defined values; the other bits are undefined. If the target wants all 32 bits of %edi to be carried over to insn 489 then it needs to make insn 69 an SImode set instead of a HImode set. So what cprop is doing is OK: it's changing the values of undefined bits but not changing the definition of defined bits (from an RTL point of view). Thanks, Richard