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.