emit_no_conflict_block breaks some conditional moves

James E Wilson wilson@specifixinc.com
Fri Apr 22 06:45:00 GMT 2005


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 ...
     movsi target, ...
     movsi target, ...
which obviously does not work if your condition code register is a hard 
register.

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.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com



More information about the Gcc mailing list