James E Wilson <[EMAIL PROTECTED]> writes:
> Greg McGary wrote:
> > I found that
> > emit_no_conflict_block() reordered insns gen'd by
> > expand_doubleword_shift() in a way that violated dependency between
> > compares and associated conditional-move insns that had the target
> > register as destination.
>
> You didn't say precisely what went wrong, but I'd guess you have
> cmpsi ...
> movsicc target, ...
> cmpsi ...
> movsicc target, ...
> which got reordered to
> cmpsi ...
> cmpsi ...
> movsicc target, ...
> movsicc target, ...
> which obviously does not work if your condition code register is a
> hard register.
Correct. FYI, the two "cmpsi" insns are identical and redundant, so
don't conflict, however, all bit-logic and shift insns on this CPU
clobber condition codes, and the CC-producing cmpsi insns are
separated from their consumers by CC-clobbering logic & shift insns.
> Perhaps a check like
> && GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_CC
> or maybe check for any hard register
> && (SET_DEST (set) != REG
> || REGNO (set) >= FIRST_PSEUDO_REGISTER)
> Safer is probably to do both checks, so that we only reject CCmode
> hard regs here, e.g.
> && (GET_MODE_CLASS (GET_MODE (SET_DEST (set))) != MODE_CC
> || SET_DEST (set) != REG
> || REGNO (set) >= FIRST_PSEUDO_REGISTER))
> which should handle the specific case you ran into.
That will do fine for ports that have conditional move, but without
movsicc, you'll have this case:
cmpsi ...
bcc 1f
movsi target, ...
1:
cmpsi ...
bcc 2f
movsi target, ...
2:
<cc-clobbering insns...>
which without the above fix will be reordered:
cmpsi ...
bcc 1f
1:
cmpsi ...
bcc 2f
2:
<cc-clobbering insns...>
movsi target, ...
movsi target, ...
while with the above fix, will be reordered:
bcc 1f
1:
bcc 2f
2:
<cc-clobbering insns...>
cmpsi ...
movsi target, ...
cmpsi ...
movsi target, ...
Here, the branches and labels need to also travel with the cmpsi and movsi.
Greg