On Tue, Jan 19, 2021 at 12:38:47PM +0000, Richard Sandiford via Gcc-patches 
wrote:
> > actually only the lower 16bits are needed, the original insn is like
> >
> > .294.r.ira
> > (insn 69 68 70 13 (set (reg:HI 96 [ _52 ])
> >         (subreg:HI (reg:DI 82 [ var_6.0_1 ]) 0)) "test.c":21:23 76
> > {*movhi_internal}
> >      (nil))
> > (insn 78 75 82 13 (set (reg:V4HI 140 [ _283 ])
> >         (vec_duplicate:V4HI (truncate:HI (subreg:SI (reg:HI 96 [ _52
> > ]) 0)))) 1412 {*vec_dupv4hi}
> >      (nil))
> >
> > .295r.reload
> > (insn 69 68 70 13 (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 13 (set (reg:SI 22 xmm2 [297])
> >         (reg:SI 5 di [orig:96 _52 ] [96])) 75 {*movsi_internal}
> >      (nil))
> > (insn 78 489 490 13 (set (reg:V4HI 20 xmm0 [orig:140 _283 ] [140])
> >         (vec_duplicate:V4HI (truncate:HI (reg:SI 22 xmm2 [297]))))
> > 1412 {*vec_dupv4hi}
> >      (nil))
> >
> > and insn 489 is created by lra/reload which seems ok for the sequence,
> > but problemistic with considering the logic of hardreg_cprop.
> 
> It looks OK even with the regcprop behaviour though:
> 
> - insn 69 defines only the low 16 bits of di,
> - insn 489 defines only the low 16 bits of xmm2, but copies bits 16-31
>   too (with unknown contents)
> - insn 78 uses only the low 16 bits of xmm2 (the unknown contents
>   introduced by insn 489 are truncated away)
> 
> So where do bits 16-31 become significant?  What goes wrong if they're
> not zero?

The k0 register is initialized I believe with
(insn 20 2 21 2 (set (reg:DI 68 k0 [orig:82 var_6.0_1 ] [82])
        (mem/c:DI (symbol_ref:DI ("var_6") [flags 0x40]  <var_decl 
0x7f7babeaaf30 var_6>) [3 var_6+0 S8 A64])) "pr98694.C":21:10 74 
{*movdi_internal}
     (nil))
and so it contains all 64-bits, and then the code sometimes uses all the
bits, sometimes just the low 16-bits and sometimes low 32-bits of that
value.
(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])) "pr98694.C":27:23 76 
{*movhi_internal}
     (nil))
(insn 74 73 75 12 (set (reg:SI 36 r8 [orig:149 _52 ] [149])
        (zero_extend:SI (reg:HI 68 k0 [orig:82 var_6.0_1 ] [82]))) 144 
{*zero_extendhisi2}
     (nil))
(insn 489 75 78 12 (set (reg:SI 22 xmm2 [297])
        (reg:SI 5 di [orig:96 _52 ] [96])) 75 {*movsi_internal}
     (nil))
(insn 78 489 490 12 (set (reg:V4HI 20 xmm0 [orig:140 _283 ] [140])
        (vec_duplicate:V4HI (truncate:HI (reg:SI 22 xmm2 [297])))) 1412 
{*vec_dupv4hi}
     (expr_list:REG_DEAD (reg:SI 22 xmm2 [297])
        (nil)))
are examples when it uses only the low 16 bits from that, and
(insn 487 72 73 12 (set (reg:SI 1 dx [148])
        (reg:SI 68 k0 [orig:82 var_6.0_1 ] [82])) 75 {*movsi_internal}
     (nil))

(insn 85 84 491 13 (set (reg:SI 37 r9 [orig:86 _11 ] [86])
        (reg:SI 68 k0 [orig:82 var_6.0_1 ] [82])) "pr98694.C":28:14 75 
{*movsi_internal}
     (nil))

(insn 491 85 88 13 (set (reg:SI 3 bx [299])
        (reg:SI 68 k0 [orig:82 var_6.0_1 ] [82])) 75 {*movsi_internal}
     (nil))
(insn 88 491 89 13 (set (reg:CCNO 17 flags)
        (compare:CCNO (reg:SI 3 bx [299])
            (const_int 0 [0]))) 7 {*cmpsi_ccno_1}
     (expr_list:REG_DEAD (reg:SI 3 bx [299])
        (nil)))

(insn 457 499 460 33 (set (reg:SI 39 r11 [orig:86 _11 ] [86])
        (reg:SI 37 r9 [orig:86 _11 ] [86])) "pr98694.C":35:36 75 
{*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 37 r9 [orig:86 _11 ] [86])
        (nil)))
are examples where it uses low 32-bits from k0.
So the
 (insn 457 499 460 33 (set (reg:SI 39 r11 [orig:86 _11 ] [86])
-        (reg:SI 37 r9 [orig:86 _11 ] [86])) "pr98694.C":35:36 75 
{*movsi_internal}
-     (expr_list:REG_DEAD (reg:SI 37 r9 [orig:86 _11 ] [86])
+        (reg:SI 22 xmm2 [orig:86 _11 ] [86])) "pr98694.C":35:36 75 
{*movsi_internal}
+     (expr_list:REG_DEAD (reg:SI 22 xmm2 [orig:86 _11 ] [86])
         (nil)))
cprop_hardreg change indeed looks bogus, while xmm2 has SImode, it holds
only the low 16-bits of the value and has the upper bits undefined, while r9
it is replacing had all of the low 32-bits well defined.

        Jakub

Reply via email to