Subject: bug#42060: [3.0.4] Incorrect ‘eqv?’ reduction in 64→32-bit cross-compilation

From: Ludovic Courtès <[email-masked]>
Date: Fri, 26 Jun 2020 16:04:34 +0200

Hello,

In <https://issues.guix.gnu.org/42047>, janneke found that
cross-compiling an ‘eqv?’ form from x86_64 to i686 leads to an incorrect
‘eqv?’ reduction (this was not the case in 3.0.2).  Reproducer:

  (lambda (i)
    (eqv? i #x6478696f))

Then cross-compile from x86_64 like this:

  guild compile -O3 --target=i586-pc-gnu -o bad.go reproducer.scm

and compile natively on a 32-bit platform with:

  guild compile -O3 -o good.go reproducer.scm

If you disassemble good.go and bad.go, the diff goes like this:

--- /tmp/good.asm	2020-06-26 15:56:35.671024432 +0200
+++ /tmp/bad.asm	2020-06-26 15:56:35.651024548 +0200
@@ -1,55 +1,39 @@
 Disassembly of <unnamed function> at #x98:
 
-   0    (instrument-entry 16348)                              at eqv-reduction-bug.scm:1:0
+   0    (instrument-entry 16348)                              at /home/ludo/src/guile-debugging/eqv-reduction-bug.scm:1:0
    2    (assert-nargs-ee/locals 1 0)    ;; 1 slot (0 args)
-   3    (make-non-immediate 0 16343)    ;; #<procedure a4f000 at eqv-reduction-bug.scm:1:0 (i)>
+   3    (make-non-immediate 0 16343)    ;; #<procedure a4f000 at /home/ludo/src/guile-debugging/eqv-reduction-bug.scm:1:?>
    5    (handle-interrupts)             
    6    (return-values)                 

 Disassembly of <unnamed function> at #xb4:
 
-   0    (instrument-entry 16351)                              at eqv-reduction-bug.scm:1:0
+   0    (instrument-entry 16351)                              at /home/ludo/src/guile-debugging/eqv-reduction-bug.scm:1:0
    2    (assert-nargs-ee/locals 2 0)    ;; 2 slots (1 arg)
    3    (static-ref 1 16346)            ;; 1685612911
-   5    (eq? 0 1)                                             at eqv-reduction-bug.scm:2:2
-   6    (je 21)                         ;; -> L3
-   7    (immediate-tag=? 0 7 0)         ;; heap-object?
-   9    (jne 14)                        ;; -> L2
-  10    (heap-tag=? 0 127 23)           ;; heap-number?
-  12    (jne 11)                        ;; -> L2
-  13    (heap-numbers-equal? 0 1)       
-  14    (jne 5)                         ;; -> L1
-  15    (make-short-immediate 1 1028)   ;; #t
-  16    (reset-frame 1)                 ;; 1 slot
-  17    (handle-interrupts)             
-  18    (return-values)                 
+   5    (eq? 0 1)                                             at /home/ludo/src/guile-debugging/eqv-reduction-bug.scm:2:2
+   6    (jne 5)                         ;; -> L1
+   7    (make-short-immediate 1 1028)   ;; #t
+   8    (reset-frame 1)                 ;; 1 slot
+   9    (handle-interrupts)             
+  10    (return-values)                 
 L1:
-  19    (make-short-immediate 1 4)      ;; #f
-  20    (reset-frame 1)                 ;; 1 slot
-  21    (handle-interrupts)             
-  22    (return-values)                 
-L2:
-  23    (make-short-immediate 1 4)      ;; #f
-  24    (reset-frame 1)                 ;; 1 slot
-  25    (handle-interrupts)             
-  26    (return-values)                 
-L3:
-  27    (make-short-immediate 1 1028)   ;; #t
-  28    (reset-frame 1)                 ;; 1 slot
-  29    (handle-interrupts)             
-  30    (return-values)                 
+  11    (make-short-immediate 1 4)      ;; #f
+  12    (reset-frame 1)                 ;; 1 slot
+  13    (handle-interrupts)             
+  14    (return-values)                 

IOW, bad.go reduced ‘eqv?’ to ‘eq?’.

This might come from 7df3f3414bfb19a1bd7fbe29bc30a1ab28bf4319, perhaps
with an issue of the time at which ‘target-most-positive-fixnum’ is
called, similar to what was fixed in
a0b9d866380b04aff27dcbcf1e13051f3d9685ad.

To be continued…

Ludo’.