http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43088
--- Comment #6 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2011-07-02 21:07:50 UTC --- Created attachment 24659 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24659 C source file Compile with -mmcu=atmega168 -Os. This file shows the flaw in function foo_3f that compares against 0x3f in comparison to foo_3e that compares against 0x3e. If the comparison is against 0x3e the code is fine. The difference happens in pass combine. For 0x3f, combine tryes ZERO_EXTRACT: Trying 8, 9 -> 10: Failed to match this instruction: (parallel [ (set (cc0) (compare (zero_extract:HI (reg:QI 43 [ count.3 ]) (const_int 6 [0x6]) (const_int 0 [0])) (const_int 0 [0]))) (clobber (scratch:QI)) ]) Failed to match this instruction: (set (cc0) (compare (zero_extract:HI (reg:QI 43 [ count.3 ]) (const_int 6 [0x6]) (const_int 0 [0])) (const_int 0 [0]))) Failed to match this instruction: (set (reg:HI 52) (zero_extract:HI (reg:QI 43 [ count.3 ]) (const_int 6 [0x6]) (const_int 0 [0]))) ............................................. But for 0x3e it tryes AND, which matches (presumably combine-split): Trying 8, 9 -> 10: Failed to match this instruction: (parallel [ (set (cc0) (compare (and:QI (reg:QI 43 [ count.1 ]) (const_int 62 [0x3e])) (const_int 0 [0]))) (clobber (scratch:QI)) ]) Failed to match this instruction: (set (cc0) (compare (and:QI (reg:QI 43 [ count.1 ]) (const_int 62 [0x3e])) (const_int 0 [0]))) Successfully matched this instruction: (set (reg:QI 52) (and:QI (reg:QI 43 [ count.1 ]) (const_int 62 [0x3e]))) Successfully matched this instruction: (set (cc0) (compare (reg:QI 52) (const_int 0 [0]))) deferring deletion of insn with uid = 8. ...