Reload bug & SRA oddness

Bernd Schmidt bernds_cb1@t-online.de
Fri Apr 20 00:29:00 GMT 2007


execute/20040709-2.c is currently failing on the Blackfin at -O3.  This 
is a problem in reload: these days register allocation can assign the 
same hard register to two pseudos even if their lifetimes overlap if one 
of them is uninitialized.  If you then have an insn where the 
uninitialized pseudo dies, and reload needs an output reload, it can 
choose the dying register for it.  Doing so, it clobbers the other live 
pseudo that shares the hardregister with the uninitialized register.

We've fixed this bug twice before, once in find_dummy_reload, and in 
push_reload.  This adds the same check to combine_reloads, where we can 
hit the same problem.

Bootstrapped and regression tested on i686-linux; committed as 123986.

Now, the reason why we have an uninitialized register at all is some 
strangeness in the tree optimizers.  I'm not too familiar with the 
tree-ssa machinery yet, but from what I've seen I blame the SRA pass. 
I've attached a reduced version of the testcase.  Consider the following 
diff between 029t.forwprop1 and 030t.esra:

;; Function fn1D (fn1D)                 ;; Function fn1D (fn1D)

                                       > Initial instantiation for y
                                       >   y.k -> y$k
                                       > Using block-copy for y
                                       > Initial instantiation for x
                                       > Using block-copy for x
                                       > Initial instantiation for D.1631
                                       > Using block-copy for D.1631
                                       >
                                       >
                                       >
                                       > Symbols to be put in SSA form
                                       >
                                       > { y y$k }
                                       >
                                       >
                                       > Incremental SSA update started
                                       >
                                       > Number of blocks in CFG: 3
                                       > Number of blocks to update: 2
                                       >
                                       >
                                       >
fn1D (x)                                fn1D (x)
{                                       {
                                       >   <unnamed-unsigned:29> y$k;
   struct D D.1631;                        struct D D.1631;
   struct D x;                             struct D x;
   struct D y;                             struct D y;
   unsigned int D.1534;                    unsigned int D.1534;
   <unnamed-unsigned:29> D.1533;           <unnamed-unsigned:29> D.1533;
   unsigned int D.1532;                    unsigned int D.1532;
   unsigned int D.1531;                    unsigned int D.1531;
   <unnamed-unsigned:29> D.1530;           <unnamed-unsigned:29> D.1530;

<bb 2>:                                 <bb 2>:
                                       >   y.k = y$k_9(D);
   y = sD;                                 y = sD;
   D.1530_1 = y.k;                     |   y$k_10 = y.k;
                                       >   D.1530_1 = y$k_10;
   D.1531_2 = (unsigned int) D.1530_1;     D.1531_2 = (unsigned int) 
D.1530_1;
   D.1532_4 = D.1531_2 + x_3(D);           D.1532_4 = D.1531_2 + x_3(D);
   D.1533_5 = (<unnamed-unsigned:29>)      D.1533_5 = 
(<unnamed-unsigned:29>)
   y.k = D.1533_5;                     |   y$k_11 = D.1533_5;
                                       >   y.k = y$k_11;
   x = y;                                  x = y;
   D.1631 = x;                             D.1631 = x;
                                       >   y.k = y$k_11;
   y = D.1631;                             y = D.1631;
   D.1530_6 = y.k;                     |   y$k_12 = y.k;
                                       >   D.1530_6 = y$k_12;
   D.1534_7 = (unsigned int) D.1530_6;     D.1534_7 = (unsigned int) 
D.1530_6;
   return D.1534_7;                        return D.1534_7;

}                                       }

What strikes me as odd here is the following piece of code:
    y.k = y$k_9(D);
    y = sD;
The (D) apparently stands for "default definition" which I take to mean 
it's considered uninitialized.  I don't know why SRA thinks it needs to 
insert this statement, as all of y is overwritten immediately after. 
This survives into RTL, there are several uninitialized pseudos with 
variable name "y$k", and since we're dealing with bit fields it's not 
eliminated - a lot of unneeded code seems to make it into the final output.

I'll try to dig deeper, but someone more familiar with this code 
(Diego?) can probably fix it more quickly.


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: uninitialized.diff
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070420/face05ae/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 20040709-2-reduced.c
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070420/face05ae/attachment.c>


More information about the Gcc-patches mailing list