master: x86-64: use test x, x instead of bt more often

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  58abf340577aaaa08a322c9e7a14e04c3e6d3ec1 (commit)
      from  cd160079fcbf298ede538257ce0ea835f3578844 (commit)

- Log -----------------------------------------------------------------
commit 58abf340577aaaa08a322c9e7a14e04c3e6d3ec1
Author: Stas Boukarev <[email protected]>
Date:   Sat Aug 29 19:57:33 2026 +0300

    x86-64: use test x, x instead of bt more often
---
 src/compiler/debug-dump.lisp   |  2 +-
 src/compiler/x86-64/arith.lisp | 71 ++++++++++++++++++++++++++----------------
 2 files changed, 46 insertions(+), 27 deletions(-)

diff --git a/src/compiler/debug-dump.lisp b/src/compiler/debug-dump.lisp
index 37d49b521..50994d3da 100644
--- a/src/compiler/debug-dump.lisp
+++ b/src/compiler/debug-dump.lisp
@@ -147,7 +147,7 @@
            (type hash-table var-locs) (type node node)
            (type (or vop null) vop)
            #-sb-xc-host (values simple-bit-vector))
-  (let ((res (make-array (logandc2 (+ (hash-table-count var-locs) 7) 7)
+  (let ((res (make-array (align-up (hash-table-count var-locs) 8)
                          :element-type 'bit
                          :initial-element 0))
         (spilled (gethash vop
diff --git a/src/compiler/x86-64/arith.lisp b/src/compiler/x86-64/arith.lisp
index 5b767c2e4..9efa61d04 100644
--- a/src/compiler/x86-64/arith.lisp
+++ b/src/compiler/x86-64/arith.lisp
@@ -3077,30 +3077,46 @@
          ;; in an 8-bit-aligned field. For now I'm only dealing with
          ;; the restricted case of 8 bits at (BYTE 8 8).
          (reducible-to-byte-p
-          (and (eq size :word) (not (logtest #xFF y)))))
-    (cond  ((and (integerp y)
-                 (not (plausible-signed-imm32-operand-p y))
-                 (= (logcount (ldb (byte n-word-bits 0) y)) 1))
-            (change-vop-flags sb-assem::*current-vop* '(:c))
-            (inst bt x (1- (integer-length (ldb (byte n-word-bits 0) y)))))
-           ((not size)
-            ;; Ensure that both operands are acceptable
-            ;; by possibly loading one into TEMP
+           (and (eq size :word) (not (logtest #xFF y))))
+         (memory-p (sc-is x control-stack unsigned-stack signed-stack)))
+    (cond ((and (not memory-p)
+                (case y
+                  (#.(ash 1 63)
+                   (inst test x x)
+                   t)
+                  (#.(ash 1 31)
+                   (inst test :dword x x)
+                   t)
+                  (#.(ash 1 15)
+                   (inst test :word x x)
+                   t)
+                  (#.(ash 1 7)
+                   (inst test :byte x x)
+                   t)))
+           (change-vop-flags sb-assem::*current-vop* '(:s)))
+          ((and (integerp y)
+                (not (plausible-signed-imm32-operand-p y))
+                (= (logcount (ldb (byte n-word-bits 0) y)) 1))
+           (change-vop-flags sb-assem::*current-vop* '(:c))
+           (inst bt x (1- (integer-length (ldb (byte n-word-bits 0) y)))))
+          ((not size)
+           ;; Ensure that both operands are acceptable
+           ;; by possibly loading one into TEMP
             (multiple-value-setq (x y) (ensure-not-mem+mem x y temp))
             (inst test :qword x y))
-          ((sc-is x control-stack unsigned-stack signed-stack)
+          (memory-p
            ;; Otherwise, when using an immediate operand smaller
            ;; than 64 bits, narrow the reg/mem operand to match.
-           (let ((disp (frame-byte-offset (tn-offset x))))
-             (when reducible-to-byte-p
-               (setq size :byte disp (1+ disp) y (ash y -8)))
-             (inst test size (ea disp rbp-tn) y)))
+            (let ((disp (frame-byte-offset (tn-offset x))))
+              (when reducible-to-byte-p
+                (setq size :byte disp (1+ disp) y (ash y -8)))
+              (inst test size (ea disp rbp-tn) y)))
           (t
            (aver (gpr-tn-p x))
            (if (and reducible-to-byte-p (<= (tn-offset x) rbx-offset))
                ;; Use upper byte of word reg {A,C,D,B}X -> {A,C,D,B}H
-               (inst test :byte `(,x . :high-byte) (ash y -8))
-               (inst test size x y))))))
+                (inst test :byte `(,x . :high-byte) (ash y -8))
+                (inst test size x y))))))
 
 (deftransform logtest ((x y) (:or ((signed-word signed-word) *)
                                   ((word word) *))
@@ -3276,21 +3292,24 @@
            (binding* ((frame-disp  (frame-byte-offset (tn-offset int)))
                       ((extra-disp bit-shift) (floor bit 8)))
              (inst test :byte (ea (+ frame-disp extra-disp) rbp-tn) (ash 1 bit-shift)))
-           (change-vop-flags vop '(:ne))
-           (return-from logbitp/c))
-          ((= bit 31)       ; test the sign bit of the 32-bit register
+           (change-vop-flags vop '(:ne)))
+          ((= bit 7) ; test the sign bit
+           (inst test :byte int int)
+           (change-vop-flags vop '(:s)))
+          ((= bit 15)
+           (inst test :word int int)
+           (change-vop-flags vop '(:s)))
+          ((= bit 31)
            (inst test :dword int int)
-           (change-vop-flags vop '(:s))
-           (return-from logbitp/c))
+           (change-vop-flags vop '(:s)))
           ((= bit 63)
            (inst test int int)
-           (change-vop-flags vop '(:s))
-           (return-from logbitp/c))
+           (change-vop-flags vop '(:s)))
           ((< bit 32)
            (inst test (if (< bit 8) :byte :dword) int (ash 1 bit))
-           (change-vop-flags vop '(:ne))
-           (return-from logbitp/c)))
-    (inst bt (if (<= bit 31) :dword :qword) int bit)))
+           (change-vop-flags vop '(:ne)))
+          (t
+           (inst bt (if (<= bit 31) :dword :qword) int bit)))))
 
 (define-vop (logbitp-memref fast-conditional)
   (:args (x :scs (descriptor-reg)))

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


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.