regmove question

Jeffrey A Law law@cygnus.com
Thu Sep 2 00:17:00 GMT 1999


  In message <199909010102.CAA29370@phal.cygnus.co.uk>you write:
  > > The testcase for this is execute/990829-1.c -O2 on i686-pc-linux-gnu.
  > 
  > regmove confuses itself because it causes an unchanging regsiter to change.
  > If have tested the following patch with the testcase, but not bootstrapped
  > yet.
  > 
  > Wed Sep  1 01:59:02 1999  J"orn Rennecke <amylaar@cygnus.co.uk>
  > 
  > 	* regmove.c (fixup_match_1): Don't change an unchanging register.
Hmmm, I'm not sure that is the right fix.

>From my reading of the code you're just papering over the real bug which
involves not moving death notes correctly.

ie, consider the following from .combine:

(insn 11 10 13 (set (reg:DF 27)
        (minus:DF (reg/v/u:DF 25)
            (reg/v/u:DF 24))) 423 {*fop_df_1} (insn_list 4 (insn_list 6 (nil)))
    (nil))

(note 13 11 14 "" NOTE_INSN_DELETED)

(insn 14 13 15 (set (reg:DF 28)
        (mult:DF (reg/v/u:DF 24)
            (reg/v/u:DF 25))) 423 {*fop_df_1} (nil)
    (expr_list:REG_DEAD (reg/v/u:DF 24)
        (nil)))

(insn 15 14 16 (set (reg:DF 30)
        (plus:DF (reg:DF 28)
            (reg/v/u:DF 25))) 423 {*fop_df_1} (insn_list 14 (nil))
    (expr_list:REG_DEAD (reg:DF 28)
        (expr_list:REG_DEAD (reg/v/u:DF 25)
            (nil))))

(insn 16 15 19 (set (reg/v:DF 26)
        (div:DF (reg:DF 27)
            (reg:DF 30))) 423 {*fop_df_1} (insn_list 11 (insn_list 15 (nil)))
    (expr_list:REG_DEAD (reg:DF 27)
        (expr_list:REG_DEAD (reg:DF 30)
            (nil))))

Note carefully where reg24 and reg25 die.

After the first call to fixup_match_1 returns we have:

(note 11 10 13 "" NOTE_INSN_DELETED)

(note 13 11 14 "" NOTE_INSN_DELETED)

(insn 14 13 15 (set (reg:DF 28)
        (mult:DF (reg/v/u:DF 24)
            (reg/v/u:DF 25))) 423 {*fop_df_1} (nil)
    (expr_list:REG_DEAD (reg/v/u:DF 24)
        (nil)))

(insn 15 14 30 (set (reg:DF 30)
        (plus:DF (reg:DF 28)
            (reg/v/u:DF 25))) 423 {*fop_df_1} (insn_list 14 (nil))
    (expr_list:REG_DEAD (reg:DF 28)
        (nil)))

(insn 30 15 16 (set (reg/v/u:DF 25)
        (minus:DF (reg/v/u:DF 25)
            (reg/v/u:DF 24))) -1 (nil)
    (nil))

(insn 16 30 19 (set (reg/v:DF 26)
        (div:DF (reg/v/u:DF 25)
            (reg:DF 30))) 423 {*fop_df_1} (insn_list 11 (insn_list 15 (nil)))
    (expr_list:REG_DEAD (reg/v/u:DF 25)
        (expr_list:REG_DEAD (reg:DF 30)
            (nil))))

Note how we moved the operation previously at insn 11 to insn 30.  In the
process we extended the lifetime of reg24 and reg25.

We fixed the death note for reg25, but not for reg24.

I believe that leaving a (now bogus) death node for reg24 on insn 14
causes regmove to think it can clobber reg24 at insn 24.

So while your patch may still be a good idea, I do not think it really
fixes the problem we're trying to solve.

jeff



More information about the Gcc-bugs mailing list