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]

copyprop_hardreg_forward removes division


I have a problem with a dissapearing division instruction.  Before
copyprop_hardreg_forward in regrename.c is called, the situation looks
like this:

    (insn 47 39 19 (set (reg:SI 3 3)
            (reg:SI 3 3)) -1 (nil)
        (nil))
    
    ;; This instruction divides (reg:SI 3) by (const_int 3), and puts
    ;; the quotient in (reg:SI 3) and the remainder in the next register,
    ;; (reg:SI 4).
    (insn 19 47 24 (parallel[ 
                (set (subreg:SI (reg:DI 3 3 [30]) 0)
                    (div:SI (reg:SI 3 3)
                        (const_int 3 [0x3])))
                (set (subreg:SI (reg:DI 3 3 [30]) 4)
                    (mod:SI (reg:SI 3 3)
                        (const_int 3 [0x3])))
            ] ) 107 {IDIV} (insn_list 18 (nil))
        (expr_list:REG_UNUSED (reg:SI 4 4)
            (nil)))
    
    (note 24 19 27 NOTE_INSN_FUNCTION_END)
    
    (insn 27 24 30 (set (reg/i:SI 1 1)
            (reg:SI 3 3 [29])) 74 {*movsi_cache} (insn_list 19 (nil))
        (expr_list:REG_DEAD (reg:SI 3 3 [29])
            (nil)))

However, when copyprop_hardreg_forward_1 is called from
copyprop_hardreg_forward, it will change (reg:SI 3) in insns 47 and 27
to (reg:SI 2), but not in insn 19:

    (insn 47 39 19 (set (reg:SI 3 3)
            (reg:SI 2 2 [3])) 74 {*movsi_cache} (nil)
        (nil))
    
    (insn 19 47 24 (parallel[ 
                (set (subreg:SI (reg:DI 3 3 [30]) 0)
                    (div:SI (reg:SI 3 3)
                        (const_int 3 [0x3])))
                (set (subreg:SI (reg:DI 3 3 [30]) 4)
                    (mod:SI (reg:SI 3 3)
                        (const_int 3 [0x3])))
            ] ) 107 {IDIV} (insn_list 18 (nil))
        (expr_list:REG_UNUSED (reg:SI 4 4)
            (nil)))
    
    (note 24 19 27 NOTE_INSN_FUNCTION_END)
    
    (insn 27 24 30 (set (reg/i:SI 1 1)
            (reg:SI 2 2 [29])) 74 {*movsi_cache} (insn_list 19 (nil))
        (expr_list:REG_DEAD (reg:SI 3 3 [29])
            (nil)))

update_life_info will then happily remove the unnecessary insn 19.

How can I avoid this?

-- 
Lars Brinkhoff          http://lars.nocrew.org/     Linux, GCC, PDP-10,
Brinkhoff Consulting    http://www.brinkhoff.se/    HTTP programming


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