This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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







Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]