Combine repeats matching on insn pairs and will ICE on 3.

Andy H hutchinsonandy@aim.com
Sun Mar 9 00:30:00 GMT 2008


Hi,

I have problem with data flow and combine that is causing ICE with 
experimental build. Despite all efforts to blame my own target changes,
I have reached the conclusion that this is a gcc COMBINE bug, but seek 
your advice before filing a bug report.

The problem seems to be that the LOG_LINKS that combine creates and uses 
can include multiple references between  instruction pairs.

The information is derived from DF. That will produce multiple 
references to the same instructions if  the register in question is a 
hard register that decomposes into several smaller registers.

The RTL that triggered problem is:

(insn 45 42 46 4 920625-1.c:55 (set (reg:SI 22 r22 [ temp.24 ])
        (mem:SI (reg/v/f:HI 71 [ alpha ]) [2 S4 A8])) 19 {*movsi} (nil))

(insn 46 45 47 4 920625-1.c:55 (set (reg:SI 18 r18)
        (mem:SI (plus:HI (reg:HI 68 [ ivtmp.18 ])
                (const_int 4 [0x4])) [2 S4 A8])) 19 {*movsi} (nil))

(insn 47 46 48 4 920625-1.c:55 (parallel [
            (set (reg:SI 22 r22)
                (mult:SI (reg:SI 22 r22)
                    (reg:SI 18 r18)))
            (clobber (reg:HI 26 r26))
            (clobber (reg:HI 30 r30))
        ]) 43 {*mulsi3_call} (expr_list:REG_DEAD (reg:SI 18 r18)
        (expr_list:REG_UNUSED (reg:HI 30 r30)
            (expr_list:REG_UNUSED (reg:HI 26 r26)
                (nil)))))


This is call to library function, and the parameter for instruction 47 
are hard registers for example SI:R22 - which is physically actually 
R22,23,24 and 25.
DF marks all 4 in def/use chains (which seems entirely correct)

When DF information is transferred into LOG_LINKS we still have 4 
references back to the definition in instructions 45 and 47. From gdb 
this was:

(gdb) print uid_log_links[47]
$8 = (rtx) 0x7ff140d0
(gdb) pr
(insn_list:REG_DEP_TRUE 45 (insn_list:REG_DEP_TRUE 45 
(insn_list:REG_DEP_TRUE 45
 (insn_list:REG_DEP_TRUE 45 (insn_list:REG_DEP_TRUE 46 
(insn_list:REG_DEP_TRUE 4
6 (insn_list:REG_DEP_TRUE 46 (insn_list:REG_DEP_TRUE 46 (nil)))))))))

These multiple references causes COMBINE to try the same combinations 
multiple times (it thinks they are different instructions). Apart from 
burning CPU time, this appears to have no obvious problem for 
instruction pairs (i.e. 2 only)

However, when 3 are combined, we end up trying to combine i3=47 with 
instruction i2=46 and instruction i1=46 (thats right two copies of 46). 
Mostly this is ok - except when we get a new pattern for i2, and then 
delete  i1 - and not realizing that i2 is also deleted.

This ICE occured when it tried to copy the  REG_DEAD notes back to the 
source of R22 - instruction 46 - which, of course was no longer there!

I'm thinking that create_log_links, needs to distill the links down to 
avoid duplicates, but I'm really not sure what to blame.

best regards

Andy








More information about the Gcc mailing list