Fix PR optimization/7520

Eric Botcazou ebotcazou@libertysurf.fr
Wed Sep 18 16:03:00 GMT 2002


Hello,

The testcase ICEs at the end of the register renaming pass because the
pass alters the set of live registers at the beginning of a basic block
after reload is completed.

The basic bloc (from Volker's reduced testcase) looks as follows after
the flow2 pass:

;; Start of basic block 1, registers live: 2 [cx] 3 [bx] 6 [bp] 7 [sp] 16 []
20 [frame]
(code_label:HI 45 15 72 1 16 "" [1 uses])

(note:HI 72 45 97 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 97 72 98 1 0x40188814 (parallel [
            (set (reg:SI 2 ecx [61])
                (ior:SI (ashiftrt:SI (reg:SI 2 ecx [61])
                        (const_int 1 [0x1]))
                    (ashift:SI (reg:SI 3 ebx)
                        (minus:QI (const_int 32 [0x20])
                            (const_int 1 [0x1])))))
            (clobber (reg:CC 17 flags))
        ]) 304 {x86_shrd_1} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

(insn 98 97 37 1 0x40188814 (parallel [
            (set (reg:SI 3 ebx)
                (ashiftrt:SI (reg:SI 3 ebx)
                    (const_int 1 [0x1])))
            (clobber (reg:CC 17 flags))
        ]) 306 {*ashrsi3_1_one_bit} (nil)
    (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

(note:HI 37 98 96 1 NOTE_INSN_DELETED)

(insn 96 37 38 1 (nil) (set (reg:SI 0 eax)
        (reg:SI 3 ebx)) 38 {*movsi_1} (insn_list 98 (nil))
    (nil))

(insn:HI 38 96 39 1 0x40188814 (parallel [
            (set (reg:CCZ 17 flags)
                (compare:CCZ (ior:SI (reg:SI 0 eax)
                        (reg:SI 2 ecx [61]))
                    (const_int 0 [0x0])))
            (clobber (reg:SI 0 eax))
        ]) 217 {*iorsi_3} (insn_list 97 (insn_list 96 (nil)))
    (expr_list:REG_DEAD (reg:SI 0 eax)
        (nil)))

(jump_insn:HI 39 38 44 1 0x40188814 (set (pc)
        (if_then_else (eq (reg:CCZ 17 flags)
                (const_int 0 [0x0]))
            (label_ref 45)
            (pc))) 356 {*jcc_1} (insn_list 38 (nil))
    (expr_list:REG_DEAD (reg:CCZ 17 flags)
        (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
            (nil))))
;; End of basic block 1, registers live:
 0 [ax] 2 [cx] 3 [bx] 6 [bp] 7 [sp] 16 [] 20 [frame]


The rnreg pass detects that insn 96 - insn 38 form a closed chain for eax,
so renames eax into edx in those two insns. This causes the liveness of eax
at the end of the block to propagate to the beginning of the block, hence
the ICE.

The culprit is the REG_DEAD note that the flow2 pass attach to insn 38. The
flow machinery has a mechanism in order not to attach such a note to an insn
that both sets and uses a register. The problem is that it doesn't trigger
for an insn that clobbers and uses a register.

The proposed fix is to let this mecanism trigger in this latter case when
the clobbered register is live after the insn, so as to prevent the REG_DEAD
note from being attached.

Bootstrapped/regtested (C/C++) on i586-pc-linux-gnu.


2002-09-19  Eric Botcazou  <ebotcazou@libertysurf.fr>

 PR optimization/7520
 * flow.c (mark_set_1): Marks a clobbered register as set in an insn
 if it is live after the insn.



/* PR optimization/7520 */

int foo()
{
   int i;
   long long int j;

   while (1)
   {
      if (j & 1) ++i;
      j >>= 1;
      if (j) return i;
  }
}

int bar()
{
   if (foo()) return;
}


--
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr7520.diff
Type: application/octet-stream
Size: 430 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20020918/d27b3124/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: changelog.diff
Type: application/octet-stream
Size: 447 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20020918/d27b3124/attachment-0001.obj>


More information about the Gcc-patches mailing list