mit-scheme-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MIT-Scheme-devel] Re: Bug in x86-64 compiler?


From: Chris Hanson
Subject: [MIT-Scheme-devel] Re: Bug in x86-64 compiler?
Date: Sat, 24 Apr 2010 22:07:45 -0700

Thanks; that was the problem.  Fixed in git.

On Sat, Apr 24, 2010 at 1:01 PM, Taylor R Campbell <address@hidden> wrote:
>   Date: Sat, 24 Apr 2010 12:17:15 -0700
>   From: Chris Hanson <address@hidden>
>
>   There's a reproducible bug in Edwin that appears to be a compiler bug
>   in the x86-64 back end.  The problem is the following sequence (from
>   edwin/bufwmc, procedure column->y, the second to last procedure in the
>   file):
>
>           ;; (assign (register #x3a) (fixnum-2-args fixnum-quotient (register
>   #x29) (register #x2b) #f))
>           (mov q (r 0) (r 1))
>           (cse q (r 2) (r 0))
>           (idiv q ((r 2) : (r 0)) (@ro 6 #x300))
>           (sal q (r 0) (&u 6))
>
> Here's the analogous i386 code:
>
>        ;; (assign (register #x2a) (fixnum-2-args fixnum-quotient (register 
> #x19) (register #x1b) #f))
>        (mov w (r 0) (r 1))
>        (mov w (r 2) (r 0))
>        (sar w (r 2) (& #x1f))
>        (idiv w (r 0) (@ro w 6 #x600))
>        (sal w (r 0) (& 6))
>
> So I don't think this is specific to the x86-64 back end.  (The LAP
> generation methods for FIXNUM-QUOTIENT are nearly identical, except
> for MOV/SAR vs CSE, which has to do with some fiddly details of sign
> extension that I have thoroughly forgotten.)  What's a little puzzling
> is that any pseudo-registers should be saved into their homes in the
> x86-64 code -- there ought to be plenty machine registers to go
> around.  I guess this just reflects the greediness of the register
> allocation algorithm, which doesn't look ahead to see what machine
> registers the following instructions may need.
>
>   Basically, just before this code is run, r0 contains register #x2b
>   (x-max), and r1 contains register #x29 (column).  The first
>   instruction clobbers r0, losing x-max, then the idiv instruction
>   refers to register #x2b's memory home; however that value was never
>   saved to memory, so whatever is there is complete junk.  Usually the
>   result of the idiv instruction is an exception that crashes Scheme.
>   Sometimes it's just the wrong answer.
>
> Just before lie the instructions
>
>        (mov w (@ro w 6 #x600) (r 0))   ; i386
>        ...
>        (mov w (r 3) (@ro w 6 #x600))
>        ...
>        (mov w (r 0) (r 3))
>
>        (mov q (@ro 6 #x300) (r 0))     ; x86-64
>        ...
>        (mov q (r 3) (@ro 6 #x300))
>        ...
>        (mov q (r 0) (r 3))
>
> with no writes to r3 in the ellipsis.  These instructions are skipped,
> though, if LINE-END? is false.  What I think happened is that, upon
> seeing
>
> (if line-end?
>    (if (eq? (fix:remainder column x-max) 0)
>        ...
>        (fix:quotient column x-max))
>    (fix:quotient column x-max)),
>
> the RTL optimizer merged the common suffixes for the tail expression
>
> (fix:quotient column x-max),
>
> and the register allocator saved X-MAX (formerly in r0) into its home
> #x300/#x600, for the evaluation of
>
> (eq? (fix:remainder column x-max) 0),
>
> but failed to reflect the save along both paths into the common suffix
> block.  Consequently, the common suffix block thinks that X-MAX will
> be in its home, but the path when LINE-END? is false fails to save
> X-MAX into its home.
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]