Hello,

> Just as an FYI, Kenny and I have replaced the global liveness analyzer
> with one from df.c, and removed the need for make_accurate_live_analysis
> (ie df.c now does the partial avail liveness stuff).
> 
> We are currently in the process of changing all the other users of life
> analysis to use the df.c liveness, which should solve this problem
> (since they will all then use the accurate life analysis).

Good to hear! Unfortunately this will come too late to fix the bug in gcc 
4.1. What about the following workaround? This one could be fine for 
the 4.1.0 release:

Remember the situation after reload. r1 is used for an uninitialized variable
hence it is live from the beginning to the read of the variable.
The special liveness analyzer in global alloc not considering uninitialized 
quantities to conflict with others assigns r1 also to a local pseudo.

bb 1 start: r1 dead
  insn 1: r1 = 0;
  insn 2: use r1; clobber r1; REG_DEAD (r1) !!!
bb 1 end: r1 live

Due to the REG_DEAD note regrename assumes it is safe to rename r1 locally to r5
resulting in:

bb 1 start: r1 live !!!
  insn 1: r5 = 0;
  insn 2: use r5; clobber r5; REG_DEAD (r5)
bb 1 end: r1 live

Because live at start has changed due to a local change an assertion in flow is
triggered.

The cause of the problem is that we already enter regrename with wrong liveness
info which in turn is caused by using a different liveness analyzer in global 
alloc
than elsewhere.  We have the register r1 live at the end of the basic block but 
the
last rtx writing this value is a clobber.  This situation should only occur if 
we had 
overlapping live ranges which were assigned to the same hard reg. Under normal
circumstances this should be considered a bug and an assertion would be the 
right
choice. But knowing that this could only be caused by the global alloc liveness 
analyzer the flow analyzer should avoid emitting a REG_DEAD note. That way the
value of the uninitialized variable (which is undefined anyway) would be 
clobbered
what should not cause any trouble.

The attached patch modifies mark_set_1 to consider a CLOBBER a normal SET if the
clobbered register is live afterwards.

So as a rfc what do you (or anybody else) think about the attached patch for 
mainline gcc.

Bootstrapped on i686, s390 and s390x without testsuite regressions.

This patch fixes the 920501-4.c regression on s390x.

Bye,

-Andreas-


2005-10-13  Andreas Krebbel  <[EMAIL PROTECTED]>

        * flow.c (mark_set_1): Handle CLOBBERs like SETs if the register
        is live afterwards.


Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.635
diff -p -c -r1.635 flow.c
*** gcc/flow.c  22 Aug 2005 16:58:46 -0000      1.635
--- gcc/flow.c  13 Oct 2005 09:25:51 -0000
*************** mark_set_1 (struct propagate_block_info 
*** 2819,2825 ****
              else
                SET_REGNO_REG_SET (pbi->local_set, i);
            }
!         if (code != CLOBBER)
            SET_REGNO_REG_SET (pbi->new_set, i);
  
          some_was_live |= needed_regno;
--- 2819,2825 ----
              else
                SET_REGNO_REG_SET (pbi->local_set, i);
            }
!         if (code != CLOBBER || needed_regno)
            SET_REGNO_REG_SET (pbi->new_set, i);
  
          some_was_live |= needed_regno;

Reply via email to