Hi Richard, On Fri, May 08, 2015 at 01:15:25PM -0700, Richard Henderson wrote: > But it *does* try to match an intermediate pattern, > > (set (reg:CCGC 17 flags) > (compare:CCGC (reg:CCGC 17 flags) > (const_int 0 [0]))) > > which can be considered a no-op move.
Maybe we should teach combine this is a no-op, then? Then everything should work as-is? Combine knows about no-op moves (they don't cost, and it deletes them itself). > Jeff or Segher, is it worth complicating the can_combine_p test near line 1958 > > /* Make sure that the value that is to be substituted for the register > does not use any registers whose values alter in between. However, > If the insns are adjacent, a use can't cross a set even though we > think it might (this can happen for a sequence of insns each setting > the same destination; last_set of that register might point to > a NOTE). If INSN has a REG_EQUIV note, the register is always > equivalent to the memory so the substitution is valid even if there > are intervening stores. Also, don't move a volatile asm or > UNSPEC_VOLATILE across any other insns. */ > || (! all_adjacent > && (((!MEM_P (src) > || ! find_reg_note (insn, REG_EQUIV, src)) > && use_crosses_set_p (src, DF_INSN_LUID (insn))) > || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src)) > || GET_CODE (src) == UNSPEC_VOLATILE)) > > to notice that the set is one of SUCC or SUCC2, and is thus included in the > insns being combined? That does seem cleaner and more general than the hacky > i386 nop_cmp pattern, but would certainly require tons more testing... "Cleaner"? In this code? Heh. use_crosses_set_p often estimates pessimistically. Is that what is happening here? Using real dataflow in combine would fix that (and many other problems). Not that that helps you right now ;-) I'll build with your patches tomorrow and investigate. Segher