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?