I’m in the process of upgrading a gcc port, but my client is using a gcc 4.4.1 
port right now and has run into a scheduler bug.  This seems to have been fixed 
at some point, as the 8.3.1 code base doesn’t seem to have the bug.  But they’d 
like a fix on their 4.4.1 base.

Basically, what I see is a block of code where we have

        struct pnode * pn = ctx->return_pn;

        atomic_write_u32((unsigned int*)&ctx->return_pn, 0);

        x = pn-> x;

where the ‘atomic_write_u32’ is an extended asm that is basically

static inline void atomic_write_u32( unsigned int *reg, unsigned int v) {
      asm ( "move %[dest], %[src]\n”
                : [dest] “=m” (*reg)
                : [src] “r” (v));
}

What happens is that the load of the local pn gets motioned AFTER the 
assignment of zero to the passed in reference of ctx->return_pn, and we SEGV at 
runtime dereferencing a NULL pointer.

I’ve checked the phase dumps and everything’s fine in the RTL until sched1, 
where we end up with

;;====================================================== 
;;   -- basic block 2 from 2 to 13 -- before reload
;;   ======================================================

;;  0-->     2 r50=d0                                                   
:i_pipeline
;;  1-->     7 r51=0x0                                                  
:i_pipeline
;;  2-->     8 [r50+0x9c]=asm_operands                  :nothing
;;  3-->     6 r47=[r50+0x9c]                                           
:i_pipeline    <=== moved load of pn after code that zeroes it
;;  4-->     9 d0=r47                                                   
:i_pipeline
;;  5-->    10 call [`pnode_ref_dec']                           :i_pipeline
;;  6-->    12 {cc=cmp([r50+0xb0],0x0);r49=[r50+0       :i_pipeline
;;  7-->    13 pc={(cc==0x0)?L23:pc}                            :i_pipeline
;; Ready list (final):  
;;   total time = 7
;;   new head = 2
;;   new tail = 13

I grovelled thru Bugzilla, couldn’t find anything that seemed relevant using 
search terms like “sched”, “haifa”, “asm”.  I’m hoping that someone might 
recognize this problem and point me to a relevant Bugzilla report before I dig 
into the schedule pass to try and see why it goes wrong.

I’m guessing that the pass is not recognizing the aliasing of &ctx->return_pn 
in the caller and *reg in the inline asm results in thinking it’s safe to 
motion a reference to ctx->return_pn...

Reply via email to