GCC 4.8 for VAX is generating a subreg:HI for mem:SI indexed address. This
eventually gets caught by an assert in change_address_1. Since the MEM rtx is
SI, legimate_address_p thinks it's fine.
I have a change to vax.md which catches these but it's extremely ugly and I
have to think there's a better way. But I have to wonder why is gcc even
constructing a subreg of a mem with a mode dependent address.
(gdb) call debug_rtx(insn)
(insn 73 72 374 12 (set (reg/v:HI 0 %r0 [orig:29 iCol ] [29])
(subreg:HI (mem/c:SI (plus:SI (mult:SI (reg/v:SI 10 %r10 [orig:22 i ]
[22])
(const_int 4 [0x4]))
(reg/v/f:SI 11 %r11 [orig:101 aiCol ] [101])) [4 MEM[base:
_154, offset: 0B]+0 S4 A32]) 0)) sqlite3.c:92031 13 {movhi_2}
(nil))
Since this wasn't movstricthi, this could be rewritten to avoid the subreg and
just treat %r0 as SI as in:
(insn 73 72 374 12 (set (reg/v:SI 0 %r0 [orig:29 iCol ] [29])
(mem/c:SI (plus:SI (mult:SI (reg/v:SI 10 %r10 [orig:22 i ] [22])
(const_int 4 [0x4]))
(reg/v/f:SI 11 %r11 [orig:101 aiCol ] [101]) [4 MEM[base:
_154, offset: 0B]+0 S4 A32]) 0)) sqlite3.c:92031 13 {movsi_2}
But even if movhi is a define_expand, as far as I can tell there's isn't
enough info to know whether that is possible. At that time, how can I tell
that operands[0] will be a hard reg or operands[1] will be subreg of a mode
dependent memory access?
I've tried using secondary_reload and it called called with
(subreg:HI (reg:SI 113 [ MEM[base: _154, offset: 0B] ]) 0)
but it dies in change_address_1 before invoking the code returned in sri.
I've tracked this down to reload replacing (reg:SI 113) with reg_equiv_mem
(133) in the rtx. However, it doesn't verify the rtx is actually valid. I
added a gcc_assert to trap this and got:
#1 0x000000000089ab87 in eliminate_regs_1 (x=0x7f7fe7b5c498,
mem_mode=VOIDmode, insn=0x0, may_use_invariant=true, for_costs=true)
at
/u1/netbsd-HEAD/src/tools/gcc/../../external/gpl3/gcc/dist/gcc/reload1.c:2850(gdb)
list
2845 && reg_equivs
2846 && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
2847 {
2848 new_rtx = SUBREG_REG (x);
2849 rtx z = reg_equiv_memory_loc (REGNO (new_rtx));
2850 gcc_assert (memory_address_addr_space_p (GET_MODE (x),
2851 XEXP (z, 0),
2852 MEM_ADDR_SPACE (z)));
2853 }
2854 else
(gdb) call debug_rtx(z)
(mem:SI (plus:SI (mult:SI (reg/v:SI 22 [ i ])
(const_int 4 [0x4]))
(reg/v/f:SI 101 [ aiCol ])) [4 MEM[base: _154, offset: 0B]+0 S4 A32])
(gdb) call debug_rtx(x)
(subreg:HI (reg:SI 113 [ MEM[base: _154, offset: 0B] ]) 0)
#2 0x000000000089cb31 in elimination_costs_in_insn (insn=0x7f7fe7b5bbd0)
at
/u1/netbsd-HEAD/src/tools/gcc/../../external/gpl3/gcc/dist/gcc/reload1.c:3751
(gdb) call debug_rtx (insn)
(insn 73 72 374 12 (set (nil)
(subreg:HI (reg:SI 113 [ MEM[base: _154, offset: 0B] ]) 0))
/u1/netbsd-HEAD/src/external/public-domain/sqlite/lib/../dist/sqlite3.c:92031
14 {movhi}
(expr_list:REG_DEAD (reg:SI 113 [ MEM[base: _154, offset: 0B] ])
(nil)))
And now I'm stymied. The limits of gcc-ness are now exceeded :) I'n looking
for ideas on how to proceed.
Thanks.