Problem with auto-inc code (ARM)

Richard Earnshaw rearnsha@arm.com
Mon Nov 8 06:45:00 GMT 1999


I thought I'd have a go at building gcc on the ARM with --enable-checking 
to find out just how slow it is... :-)

Unfortunately, it has already tripped twice (and I've only reached 
building cccp.o with the stage1 compiler :-()

The bug I've just found is occuring in combine_instructions, but can be 
tracked back to the flow pass when we set up an auto_inc but don't clean 
up properly after doing so.

Before flow we have the insns:

(insn/i 5853 5851 5855 (set (mem:QI (reg:SI 1185) 0)
        (subreg:QI (reg/v:SI 1178) 0)) 214 {*movqi_insn} (nil)
    (nil))

(insn/i 5855 5853 5856 (set (reg:SI 1185)
        (plus:SI (reg:SI 1185)
            (const_int 1 [0x1]))) 8 {*addsi3_insn} (nil)
    (nil))

(insn/i 5856 5855 5857 (set (mem/s:SI (reg/v:SI 52) 10)
        (reg:SI 1185)) 189 {*movsi_insn} (nil)
    (expr_list:REG_DEAD (reg:SI 1185)
        (nil)))

find_auto_inc detects that insn 5855 is a valid increment to be combined 
with insn 5853 to create

(insn/i 5853 5851 5855 (set (mem:QI (post_inc:SI (reg:SI 1185)) 0)
        (subreg:QI (reg/v:SI 1178) 0)) 214 {*movqi_insn} (nil)
    (nil))

(note 5855 5853 5856 "" NOTE_INSN_DELETED)

(insn/i 5856 5855 5857 (set (mem/s:SI (reg/v:SI 52) 10)
        (reg:SI 1185)) 189 {*movsi_insn} (insn_list 5855 (nil))
    (expr_list:REG_DEAD (reg:SI 1185)
        (nil)))

Unfortunately, this leaves the log_links of insn 5856 pointing at the 
deleted insn, which trips the checking code in combine when we try to get 
the links from the deleted insn as part of a three-way combine.

I guess the correct thing to do is to update the links correctly, but I'm 
not particularly familiar with the data structures used in flow.  Is there 
a simple way to find insn 5856 when we delete the increment?

If this isn't feasible I can see two other approaches:

1) we could modify combine_instructions to check that an insn hasn't been 
deleted before we try to dereference its links.  I don't like this, since 
it's really papering over a crack.

2) We could turn the insn that we have deleted into a no-op move so that 
it is never deleted (this is essentially what would happen if the 
increment insn had written its result to a different register with the 
source register dying in the insn); but there is a comment in there that 
says that it should be deleted so that it doesn't appear as a "use and a 
set" of the reg.

Comments?

R.



More information about the Gcc-bugs mailing list