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

--- Comment #10 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #5)
> I guess it depends on what exactly a normal subreg on lhs means.
> The documentation says:
>           When used as an lvalue, 'subreg' is a word-based accessor.
>           Storing to a 'subreg' modifies all the words of REG that
>           overlap the 'subreg', but it leaves the other words of REG
>           alone.
> but in this case, we really don't have a GPR, but rather a single much
> larger (512-bit) register.  Does it still imply that for -m32 (subreg:SI
> (reg:V32HI) 0)
> sets just the low 32 bits of the large register and doesn't modify anything
> else,
> and for -m64 the same means set low 32 bits, have the 32 bits above it
> undefined and the rest of bits unmodified?
> 

Yes, I guess so. For x86-64 "the 32 bits above" will be zero which might be
treated as undefined.

> Seems store_bit_field treats it that way, but perhaps IRA does not?

I believe IRA treats it in the same way.

LRA does not just emit

(insn 5658 4214 5812 2 (set (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                (const_int 264 [0x108])) [4 %sfp+-64 S8 A512])
        (reg:DI 0 ax [4040])) "pr85090.c":13 85 {*movdi_internal}
     (nil))
(insn 5812 5658 4219 2 (set (reg:DI 57 xmm20 [orig:422 i ] [422])
        (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                (const_int 264 [0x108])) [4 %sfp+-64 S8 A512])) "pr85090.c":13
85 {*movdi_internal}
     (nil))

It emits through emit_move_insn (instead of xmm20, a pseudo is used on some LRA
sub-passes):

(insn 5812 5658 4219 2 (set (subreg:DI (reg/v:V32HI 57 xmm20 [orig:422 i ]
[422]) 0)                                                                       
        (mem/c:DI (plus:DI (reg/f:DI 7 sp)                                      
                (const_int 264 [0x108])) [4 %sfp+-64 S8 A512])) "v.i":13 85
{*movdi_internal}                                                               
     (expr_list:REG_DEAD (reg:TI 20 frame)                                      
        (nil)))                                                                 

and this insn exists till the very LRA end where it is changed (through
alter_subreg):

(insn 5812 5658 4219 2 (set (reg:DI 57 xmm20 [orig:422 i ] [422])
        (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                (const_int 264 [0x108])) [4 %sfp+-64 S8 A512])) "pr85090.c":13
85 {*movdi_internal}
     (nil))

So LRA keeps subreg semantics.  It cannot change movdi_internal into the right
vector insn sequence.  I believe it is not LRA responsibility.

Reply via email to