Hi,
I ran into a troublesome problelm about LRA. The case is hard to
construct, so I paste the RTL sequence first to ask for help.
-----------------------------------------------------------------------------------------------
The RTL sequence after IRA:
(insn 11 198 1633 20 (set (reg:DI 170 [ iftmp.176_92 ])
(const_int 0 [0])) "":2099 182 {*movdi_64bit}
(expr_list:REG_EQUAL (const_int 0 [0])
(nil)))
(insn 1632 1633 1634 20 (set (reg:SI 973)
(subreg:SI (reg:DI 170 [ iftmp.176_92 ]) 0)) "":2099 183
{*movsi_internal}
(expr_list:REG_DEAD (reg:DI 170 [ iftmp.176_92 ])
(nil)))
(insn 1634 1632 1635 20 (set (reg:SI 974)
(eq:SI (reg:DI 421)
(const_int 0 [0]))) "":2099 271 {*seq_zero_disi}
(expr_list:REG_DEAD (reg:DI 421)
(nil)))
(insn 1635 1634 1636 20 (set (reg:SI 972)
(if_then_else:SI (eq (reg/v:DI 173 [ i ])
(const_int 0 [0]))
(reg:SI 974)
(reg:SI 973))) "":2099 238 {*cmovzsi}
(expr_list:REG_DEAD (reg:SI 974)
(expr_list:REG_DEAD (reg:SI 973)
(nil))))
(insn 1636 1635 212 20 (set (subreg:SI (reg:DI 170 [ iftmp.176_92 ]) 0)
(reg:SI 972)) "":2099 183 {*movsi_internal}
(expr_list:REG_DEAD (reg:SI 972)
(nil)))
...
(jump_insn 1022 1021 1023 104 (set (pc)
(if_then_else (eq (reg:DI 170 [ iftmp.176_92 ])
(const_int 0 [0]))
(label_ref 1051)
(pc))) "":1467 252 {*branch_zerodi}
(expr_list:REG_DEAD (reg:DI 170 [ iftmp.176_92 ])
(int_list:REG_BR_PROB 354334804 (nil)))
-----------------------------------------------------------------------------------------------
The RTL sequence after LRA RELOAD:
(insn 11 198 2025 20 (set (reg:DI 13 a3 [orig:170 iftmp.176_92 ] [170])
(const_int 0 [0])) "":2099 182 {*movdi_64bit}
(expr_list:REG_EQUAL (const_int 0 [0])
(nil)))
(insn 1633 2025 1632 20 (set (reg:DI 15 a5 [421])
(minus:DI (reg:DI 15 a5 [orig:125 _13 ] [125])
(reg:DI 14 a4 [orig:254 pretmp_372 ] [254]))) "":2099 11
{*subdi3}
(nil))
(insn 1632 1633 1634 20 (set (reg:SI 13 a3 [973])
(reg:SI 13 a3 [orig:170 iftmp.176_92 ] [170])) "":2099 183
{*movsi_internal}
(nil))
(insn 1634 1632 1635 20 (set (reg:SI 15 a5 [974])
(eq:SI (reg:DI 15 a5 [421])
(const_int 0 [0]))) "":2099 271 {*seq_zero_disi}
(nil))
(insn 1635 1634 1636 20 (set (reg:SI 15 a5 [972])
(if_then_else:SI (eq (reg/v:DI 19 s3 [orig:173 i ] [173])
(const_int 0 [0]))
(reg:SI 15 a5 [974])
(reg:SI 13 a3 [973]))) "":2099 238 {*cmovzsi}
(nil))
(insn 1636 1635 212 20 (set (mem/c:SI (plus:DI (reg/f:DI 2 sp)
(const_int 24 [0x18])) [349 %sfp+-3496 S4 A64])
(reg:SI 15 a5 [972])) "":2099 183 {*movsi_internal}
(nil))
...
(insn 1926 1021 1022 104 (set (reg:DI 15 a5 [orig:170 iftmp.176_92 ] [170])
(mem/c:DI (plus:DI (reg/f:DI 2 sp)
(const_int 24 [0x18])) [349 %sfp+-3496 S8 A64]))
"":1467 182 {*movdi_64bit}
(nil))
(jump_insn 1022 1926 1023 104 (set (pc)
(if_then_else (eq (reg:DI 15 a5 [orig:170 iftmp.176_92 ] [170])
(const_int 0 [0]))
(label_ref 1051)
(pc))) "":1467 252 {*branch_zerodi}
(int_list:REG_BR_PROB 354334804 (nil))
-----------------------------------------------------------------------------------------------
The REG 170 spilled to memory, but it emits a SImode store and a DImode
load. I tried to debug and find some related code in lra.c, in
add_regs_to_insn_regno_info function, the following code is about to
check SUBREG
if (GET_CODE (x) == SUBREG)
{
mode = wider_subreg_mode (x);
if (read_modify_subreg_p (x))
subreg_p = true;
x = SUBREG_REG (x);
code = GET_CODE (x);
}
If read_modify_subreg_p (x) is true, the subreg_p flag will be set. But
if SUBREG's mode is narrower than register mode, the subreg_p flag will
not be set just like the case I wrote.
If I let read_modify_subreg_p (x) return true, my case will turn right.
But I'm not sure if it's appropriate, because it may decrease target
performance.
Hope someone can help me.
Best Regards,
Cooper