master: x86-64: sign-extend logand constants to make them encodable

stassats via Sbcl-commits <[email protected]>
Newsgroups gmane.lisp.steel-bank.cvs
Message-ID <[email protected]>
The branch "master" has been updated in SBCL:
       via  0a17885e2733eea227cf5b5d404cd5bb8bbd8c2e (commit)
      from  5710e793ff07274c0c5390f55c5368657d16fe41 (commit)

- Log -----------------------------------------------------------------
commit 0a17885e2733eea227cf5b5d404cd5bb8bbd8c2e
Author: Stas Boukarev <[email protected]>
Date:   Wed Aug 5 23:41:37 2026 +0300

    x86-64: sign-extend logand constants to make them encodable
    
    If it doesn't affect the result.
---
 src/compiler/x86-64/arith.lisp | 48 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/src/compiler/x86-64/arith.lisp b/src/compiler/x86-64/arith.lisp
index 946928d48..5b767c2e4 100644
--- a/src/compiler/x86-64/arith.lisp
+++ b/src/compiler/x86-64/arith.lisp
@@ -215,6 +215,7 @@
                    ,@(or signed=>signed `((move r x) (inst ,op r y)))))
                 (define-vop (,(symbolicate 'fast- translate '-c/signed=>signed)
                              fast-signed-binop-c)
+                  (:arg-refs x-ref)
                   (:translate ,translate)
                   (:generator ,untagged-penalty
                    ,@(or c/signed=>signed `((move r x) (inst ,op r (constantize y))))))
@@ -229,6 +230,7 @@
                                            translate
                                            '-c/unsigned=>unsigned)
                              fast-unsigned-binop-c)
+                  (:arg-refs x-ref)
                   (:translate ,translate)
                   (:generator ,untagged-penalty
                    ,@(or c/unsigned=>unsigned
@@ -258,14 +260,24 @@
                 (inst mov (if gpr-r-p :dword :qword) r x))
               (inst and :dword r y))
              ((and (not (plausible-signed-imm32-operand-p y))
-                   (let* ((int (sb-c::type-approximate-interval (tn-ref-type x-ref)))
-                          (mask (logandc1 (logior y fixnum-tag-mask)
-                                          (ldb (byte (+ (integer-length (sb-c::interval-high int)) n-fixnum-tag-bits) 0) -1))))
-                     (when (and (>= (sb-c::interval-low int) 0)
-                                (= (logcount mask) 1))
-                       (move r x)
-                       (inst btr r (1- (integer-length mask)))
-                       t))))
+                   (let* ((width (sb-c::unsigned-type-width (tn-ref-type x-ref)))
+                          (extra-ones (and width
+                                           (dpb -1 (byte (- 64 (1+ width)) (1+ width)) y))))
+                     ;; Try filling the zeros in the mask with ones where the integer already has zeros,
+                     ;; which might sign-extend the mask into a negative 32-bit immediate
+                     (cond ((plausible-signed-imm32-operand-p extra-ones)
+                            (move r x)
+                            (inst and r extra-ones)
+                            t)
+                           (t
+                            (let* ((int (sb-c::type-approximate-interval (tn-ref-type x-ref)))
+                                   (mask (logandc1 (logior y fixnum-tag-mask)
+                                                   (ldb (byte (+ (integer-length (sb-c::interval-high int)) n-fixnum-tag-bits) 0) -1))))
+                              (when (and (>= (sb-c::interval-low int) 0)
+                                         (= (logcount mask) 1))
+                                (move r x)
+                                (inst btr r (1- (integer-length mask)))
+                                t)))))))
              (t
               (move r x)
               (inst and r (constantize y))))))
@@ -282,6 +294,16 @@
              ((and gpr-r-p
                    (eql y (1- (expt 2 8))))
               (inst movzx '(:byte :dword) r x))
+             ((and (not (plausible-signed-imm32-operand-p y))
+                   (let* ((width (sb-c::unsigned-type-width (tn-ref-type x-ref)))
+                          (extra-ones (and width
+                                           (dpb -1 (byte (- 64 width) width) y))))
+                     ;; Try filling the zeros in the mask with ones where the integer already has zeros,
+                     ;; which might sign-extend the mask into a negative 32-bit immediate
+                     (when (plausible-signed-imm32-operand-p extra-ones)
+                       (move r x)
+                       (inst and r extra-ones)
+                       t))))
              ((and (not (plausible-signed-imm32-operand-p y))
                    (= (logcount (logandc1 y most-positive-word)) 1))
               (move r x)
@@ -300,6 +322,16 @@
              ((and gpr-r-p
                    (eql y (1- (expt 2 8))))
               (inst movzx '(:byte :dword) r x))
+             ((and (not (plausible-signed-imm32-operand-p y))
+                   (let* ((width (sb-c::unsigned-type-width (tn-ref-type x-ref)))
+                          (extra-ones (and width
+                                           (dpb -1 (byte (- 64 width) width) y))))
+                     ;; Try filling the zeros in the mask with ones where the integer already has zeros,
+                     ;; which might sign-extend the mask into a negative 32-bit immediate
+                     (when (plausible-signed-imm32-operand-p extra-ones)
+                       (move r x)
+                       (inst and r extra-ones)
+                       t))))
              ((and (not (plausible-signed-imm32-operand-p y))
                    (= (logcount (logandc1 y most-positive-word)) 1))
               (move r x)

-----------------------------------------------------------------------


hooks/post-receive
-- 
SBCL
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.