In the msp430 back end, hard registers 4 through 15 are HImode, with
adjacent register sequences used for SImode and DImode.  In preparation for
a library call, I'm emitting RTL that assigns values directly to reg:SI 4.

Despite that, in gcc 4.5.x IRA choses reg:HI 4 as the destination
for a pseudo-register for a preceding assignment, and does nothing to
preserve the value over the span where the register is part of an SI value.
The subsequence:

  (insn 2 4 3 2 (set (reg/v:HI 38 [ x ])
          (reg:HI 15 r15 [ x ])) test.c:28 21 {*movhi2}
       (expr_list:REG_DEAD (reg:HI 15 r15 [ x ])
          (nil)))

  (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

  (note 6 3 10 2 NOTE_INSN_DELETED)

  (insn 10 6 11 2 (set (reg:SI 8 r8)
          (mem/c/i:SI (symbol_ref:HI ("seed") [flags 0x2]  <var_decl
0x7f032064f960 seed>) [2 seed+0 S4 A16])) test.c:14 24 {*movsi2}
       (nil))

  (insn 11 10 12 2 (set (reg:SI 4 r4)
          (const_int 33614 [0x834e])) test.c:14 24 {*movsi2}
       (nil))

with:

  insn=2, live_throughout: 1, dead_or_set: 15, 38
  insn=10, live_throughout: 1, 38, dead_or_set: 8, 9
  insn=11, live_throughout: 1, 8, 9, 38, dead_or_set: 4, 5
  insn=12, live_throughout: 1, 38, dead_or_set: 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15

becomes:

  (insn 2 4 3 2 (set (reg/v:HI 4 r4 [orig:38 x ] [38])
          (reg:HI 15 r15 [ x ])) test.c:28 21 {*movhi2}
       (nil))

  (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

  (note 6 3 10 2 NOTE_INSN_DELETED)

  (insn 10 6 11 2 (set (reg:SI 8 r8)
          (mem/c/i:SI (symbol_ref:HI ("seed") [flags 0x2]  <var_decl
0x7f032064f960 seed>) [2 seed+0 S4 A16])) test.c:14 24 {*movsi2}
       (nil))

  (insn 11 10 12 2 (set (reg:SI 4 r4)
          (const_int 33614 [0x834e])) test.c:14 24 {*movsi2}
       (nil))

and the subsequent reference to reg:HI 4 (formerly reg/v:HI 38) has value
33614 instead of the user's parameter.

Could somebody suggest where should I look to understand why this is
happening and how should it be fixed?

Thanks.

Peter

Reply via email to