Compiler trouble with sb-simd-sse2:f64.2-horizonal functions

Bug #2012990 reported by ari pro
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Undecided
Unassigned

Bug Description

(require "SB-SIMD")
(setf sb-ext:*evaluator-mode* :compile)
;; This works as expected:
(sb-simd-sse2:f64.2-horizontal* (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)) ;=> 4.68d0
;; This does not:
(let ((x (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)))
  (sb-simd-sse2:f64.2-horizontal* x))
;;=>0.0d0

(defmacro baz (body)
  `(let ((x (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)))
     ,@(cdr body)
     (list
      (sb-simd-sse2:f64.2-horizontal* x)
      (sb-simd-sse2:f64.2-horizontal+ x)
      (sb-simd-sse2:f64.2-horizontal-and x)
      (sb-simd-sse2:f64.2-horizontal-max x)
      (sb-simd-sse2:f64.2-horizontal-min x)
      (sb-simd-sse2:f64.2-horizontal-or x)
      (sb-simd-sse2:f64.2-horizontal-xor x)
      )))

(baz '(declare (optimize debug))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)
(baz '(declare (optimize (debug 2)))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)
(baz '(declare (optimize (debug 1)))) ;=> (0.0d0 1.2d0 0.0d0 1.2d0 0.0d0 1.2d0 1.2d0)
(baz '(declare (optimize (speed 0) (safety 3) (compilation-speed 0) (space 0) (debug 1)))) ;=> (0.0d0 1.2d0 0.0d0 1.2d0 0.0d0 1.2d0 1.2d0)
(baz '(declare (special x))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)

(let ((x (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)))
  (loop for i in (apropos-list "f64.2-horizontal" (find-package "SB-SIMD-SSE2") t)
 collect (funcall i x)))
;;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)

;; sb-eval and sb-fasteval both function correctly
(setf sb-ext:*evaluator-mode* :interpret)
(baz '(declare (optimize debug))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)
(baz '(declare (optimize (debug 1)))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)
(baz '(declare (special x))) ;=> (4.68d0 5.1d0 4.450147717014402d-309 3.9d0 1.2d0 #<DOUBLE-FLOAT quiet NaN> #<DOUBLE-FLOAT quiet NaN>)

;; Other things that work as expected:
(setf sb-ext:*evaluator-mode* :compile)
(let ((x (sb-simd-avx2:make-f64.2 1.2d0 3.9d0)))
  (sb-simd-avx2:f64.2-horizontal* x))
;;=>4.68d0

(let ((x (sb-kernel:%make-simd-pack-double 1.2d0 3.9d0)))
  (sb-simd-sse2:f64.2+ x x))
;;=> #<SIMD-PACK 2.4000000000000d+0 7.8000000000000d+0>

(lisp-implementation-version) ;=>2.3.2.116-f4e98cbf2
The behavior described above remains unchanged when tested in a previous release and has probably been the same since sb-simd was introduced.

Changed in sbcl:
assignee: nobody → Marco Heisig (marco-heisig-h)
Revision history for this message
ari pro (aripro) wrote :

I think the issue might be with f64.2-shuffle, which is used by f64.2-values, which in turn is used to define the horizontal functions mentioned above.

(require "SB-SIMD")
(setf sb-ext:*evaluator-mode* :compile)

(sb-simd-sse2:f64.2-shuffle (sb-simd-sse2:make-f64.2 1.2d0 3.9d0) 1)
=> #<SIMD-PACK 3.9000000000000d+0 1.2000000000000d+0>

(let ((x (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)))
  (sb-simd-sse2:f64.2-shuffle x 1))
=> #<SIMD-PACK 0.0000000000000d+0 1.2000000000000d+0>

(let ((x (sb-simd-sse2:make-f64.2 1.2d0 3.9d0)))
  (declare (optimize (debug 2)))
  (sb-simd-sse2:f64.2-shuffle x 1))
=> #<SIMD-PACK 3.9000000000000d+0 1.2000000000000d+0>

As above, f64.2-shuffle works fine with sb-eval and sb-fasteval.

You could "fix" f64.2-values and the horizontal functions with the following, but it would be better to figure out the cause of the f64.2-shuffle trouble.

From d4a01c7c1d10087e33c025023b727cd41cbd1441 Mon Sep 17 00:00:00 2001
From: me <email address hidden>
Date: Wed, 29 Mar 2023 01:32:58 +0000
Subject: [PATCH] Adjust sb-simd-sse2:f64.2-values

---
 contrib/sb-simd/code/define-fake-vops.lisp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/sb-simd/code/define-fake-vops.lisp b/contrib/sb-simd/code/define-fake-vops.lisp
index 4432791c4..e0099c63e 100644
--- a/contrib/sb-simd/code/define-fake-vops.lisp
+++ b/contrib/sb-simd/code/define-fake-vops.lisp
@@ -420,7 +420,7 @@
 (define-fake-vop f64.2-values (x)
   (values
    (%f64!-from-p128 x)
- (%f64!-from-p128 (%f64.2-shuffle x 1))))
+ (%f64!-from-p128 (%f64.2-unpackhi x x))))

 (define-fake-vop f64.2-broadcast (x)
   (let ((v (%f64.2!-from-f64 x)))
--
2.39.1

Revision history for this message
Marco Heisig (marco-heisig-h) wrote :

You are right, the problem is sb-simd-sse2:f64.2-shuffle. It should take three arguments (the two SIMD packs to shuffle, and the bits indicating how to shuffle), but takes only two.

The attached patch fixes the issue. It also fixes a minor issue about the AVX shuffles.

Changed in sbcl:
status: New → Confirmed
Revision history for this message
ari pro (aripro) wrote (last edit ):

Edit: this comment will be moved elsewhere, in accordance with Marco's request below.

Revision history for this message
Marco Heisig (marco-heisig-h) wrote :

This is a new bug that is not fixed by repairing f64.2-shuffle. Can you file it as a different bug, so that it gets its own number?

Stas Boukarev (stassats)
Changed in sbcl:
status: Confirmed → Fix Committed
assignee: Marco Heisig (marco-heisig-h) → nobody
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.