Hello, > I think that I have found a small bug in the loop invariant code. > The problem is exhibited when building newlib for the xstormy16-elf > toolchain although it may happen with other targets as well. The > problem occurs when an insn contains an r-value use of a register > that is going to hoisted as well as a clobber of that register, like > this: > > (parallel [ > (set (pc) > (if_then_else (lt:SI (reg:SI 45) <--- > (reg:SI 26)) > (label_ref:HI 129) > (pc))) > (clobber (reg:SI 45)) <-- must be the same > (clobber (scratch:BI)) > ]) > > The important point here is that the register referenced in the > first clobber must match the register used as the first argument of > the condition operation. (This comes from the "ineqbranchsi" > pattern in the xstormy16 machine description). > > The problem is that the loop-invariant optimization was deciding > that (reg:SI 45) could be hoisted out of the loop, whereas really it > should be left alone. I have been looking at the loop invariant > code trying to figure out what needs to be changed, but so far I > have not been able to puzzle it out. > > I think that the real problem might be the clobbers in the > ineqbranchsi pattern, but I do not know how it could be changed to > fix this. > > Any ideas ?
invariant motion needs to verify that reg:45 is dead at the beginning of the loop. We cannot just avoid moving insns that contain clobbers, as then we would not move insns like (insn 23 22 25 3 xxx.c:6 (parallel [ (set (reg:SI 64 [ ivtmp.33 ]) (plus:SI (reg:SI 64 [ ivtmp.33 ]) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) 148 {*addsi_1} (nil) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) that only clobber flags. Zdenek