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.

Reply via email to