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.
...

Reply via email to