This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

combine corrupts insns + dumps with insn cost problems


   I'm seeing this on my 16-bit ix86 port. Something isn't right:

insn_cost 5: 12
insn_cost 6: 8
insn_cost 7: 4
...
rejecting combination of insns 5 and 6
original costs 12 + 8 = 24
replacement cost 28

   Now, 12 + 8 = 20, not 24. The cost obviously includes insn 7 also. What's
happening is that combine is trying to combine insns 5, 6 but needs a CCmode
change in insn 7 because we have plain CCmode but SELECT_CC_MODE chooses
CCZ_Cmode for the combined insn 5+6. The original insns:

(insn 5 2 6 2 .../gcc.c-torture/execute/20000801-4.c:12 (set (reg/f:HI 22)
        (const:HI (plus:HI (symbol_ref/f:HI ("*.LC0") [flags 0x2] <string_cst 0xb7ea5ee0>)
                (const_int 1 [0x1])))) 9 {*movhi} (nil))

(insn 6 5 7 2 .../gcc/testsuite/gcc.c-torture/execute/20000801-4.c:12 (set (reg:CC 13 cc)
        (compare:CC (mem/s:QI (reg/f:HI 22) [0 S1 A8])
            (const_int 0 [0x0]))) 436 {cmpqi_cc} (expr_list:REG_DEAD (reg/f:HI 22)
        (nil)))

(insn 7 6 10 2 .../gcc/testsuite/gcc.c-torture/execute/20000801-4.c:12 (parallel [
            (set (reg:HI 24)
                (eq:HI (reg:CC 13 cc)
                    (const_int 0 [0x0])))
            (clobber (scratch:QI))
            (clobber (reg:CC 13 cc))
        ]) 454 {*seqhi_cc} (expr_list:REG_DEAD (reg:CC 13 cc)
        (expr_list:REG_UNUSED (reg:CC 13 cc)
            (nil))))

The replacements:

(set (reg:CCZ_C 13 cc)
    (compare:CCZ_C (mem/s:QI (const:HI (plus:HI (symbol_ref/f:HI ("*.LC0") [flags 0x2] <string_cst 0xb7ea5ee0>)
                    (const_int 1 [0x1]))) [0 S1 A8])
        (const_int 0 [0x0])))

(set (reg:HI 24)
    (eq:HI (reg:CCZ_C 13 cc)
        (const_int 0 [0x0])))

   As noted, combine rejects the replacement. But the structure of insn 7
has now been corrupted:

(insn 5 2 6 2 .../gcc.c-torture/execute/20000801-4.c:12 (set (reg/f:HI 22)
        (const:HI (plus:HI (symbol_ref/f:HI ("*.LC0") [flags 0x2] <string_cst 0xb7ea5ee0>)
                (const_int 1 [0x1])))) 9 {*movhi} (nil))

(insn 6 5 7 2 .../gcc.c-torture/execute/20000801-4.c:12 (set (reg:CC 13 cc)
        (compare:CC (mem/s:QI (reg/f:HI 22) [0 S1 A8])
            (const_int 0 [0x0]))) 436 {cmpqi_cc} (expr_list:REG_DEAD (reg/f:HI 22)
        (nil)))

(insn 7 6 10 2 .../gcc.c-torture/execute/20000801-4.c:12 (parallel [
            (set (reg:HI 24)
                (eq:HI (reg:CC 13 cc)
                    (const_int 0 [0x0])))
            (clobber (reg:CC 13 cc))
        ]) 454 {*seqhi_cc} (expr_list:REG_DEAD (reg:CC 13 cc)
        (expr_list:REG_UNUSED (reg:CC 13 cc)
            (nil))))

The clobber of the scratch register has disappeared!

A possible clue as to what sets up the failure is that the second
replacement insn (to replace insn 7)

(set (reg:HI 24)
    (eq:HI (reg:CCZ_C 13 cc)
        (const_int 0 [0x0])))

needs to have a clobber added. It really looks like this:

(set (reg:HI 24)
    (eq:HI (reg:CCZ_C 13 cc)
        (const_int 0 [0x0])))
(clobber (reg:CC 13 cc))

Combine knows how to add clobbers to make insns recognizable. I'm guessing
it accidentally clobbers the original insn in doing so. Where would I look?

-- 
Rask Ingemann Lambertsen


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]