master: Rewrite (zerop (ldb ...)) as (zerop (logand ...))
stassats via Sbcl-commits <[email protected]> Tue, 04 Aug 2026 14:31:56 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via 86c7cb9eb9e823e0cd4368067ea8c22bf83e9b88 (commit)
from 503f9b8a34f1d3c4787b4ca4055a6ef66fd2bb1c (commit)
- Log -----------------------------------------------------------------
commit 86c7cb9eb9e823e0cd4368067ea8c22bf83e9b88
Author: Vasily Postnicov <[email protected]>
Date: Tue Aug 4 15:50:51 2026 +0300
Rewrite (zerop (ldb ...)) as (zerop (logand ...))
---
src/compiler/srctran.lisp | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp
index ec27e8300..3962a40e8 100644
--- a/src/compiler/srctran.lisp
+++ b/src/compiler/srctran.lisp
@@ -3612,6 +3612,21 @@
(delay-ir1-transform node :ir1-phases)
(give-up-ir1-transform "not a word-sized integer")))))))
+;; (zerop (ldb (byte s p) n)) == (zerop (logand n (ash (1- (ash 1 s)) p)))
+;; Use this only with fixnum mask so the equality test is also between fixnums.
+(deftransform %ldb ((size posn integer)
+ ((constant-arg bit-index) (constant-arg bit-index) integer)
+ * :node node)
+ (let* ((posn (lvar-value posn))
+ (size (lvar-value size))
+ (mask (ash (1- (ash 1 size)) posn)))
+ (if (and (combination-matches '= '(* 0) (node-dest node))
+ (<= mask most-positive-fixnum))
+ (progn
+ (erase-node-type node (specifier-type 'unsigned-byte))
+ `(logand integer ,mask))
+ (give-up-ir1-transform))))
+
(deftransform %mask-field ((size posn int) ((integer 0 #.sb-vm:n-word-bits) fixnum integer) word)
"convert to inline logical operations"
`(logand int (ash (ash ,most-positive-word (- size ,sb-vm:n-word-bits)) posn)))
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL