master: Distinguish between full and partial constant pass-through

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  1899deda6a8d986aa891ca49e945780e21c2fd03 (commit)
      from  5bfa2103ecc8139ef53198d71d32f5ac67ab1925 (commit)

- Log -----------------------------------------------------------------
commit 1899deda6a8d986aa891ca49e945780e21c2fd03
Author: Stas Boukarev <[email protected]>
Date:   Sun Aug 30 04:45:32 2026 +0300

    Distinguish between full and partial constant pass-through
---
 src/compiler/ir1util.lisp | 12 +++++++-----
 src/compiler/seqtran.lisp | 10 ++++++++--
 tests/bad-code.pure.lisp  |  5 +++++
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/compiler/ir1util.lisp b/src/compiler/ir1util.lisp
index fdd35f985..894eaff82 100644
--- a/src/compiler/ir1util.lisp
+++ b/src/compiler/ir1util.lisp
@@ -3838,7 +3838,7 @@ is :ANY, the function name is not checked."
                     collect annotation)))))))
 
 (defun lvar-constants (lvar &optional walk-functions)
-  (named-let recurse ((lvar lvar) (seen nil))
+  (named-let recurse ((lvar lvar) (seen nil) (toplevel t))
     (let ((uses (lvar-uses lvar)))
       (flet ((handle-ref (ref)
                (let* ((ref (principal-ref ref))
@@ -3852,7 +3852,7 @@ is :ANY, the function name is not checked."
                            (lambda (call lvar)
                              (unless (xset-member-p lvar seen)
                                (add-to-xset lvar seen)
-                               (multiple-value-bind (type values) (recurse lvar seen)
+                               (multiple-value-bind (type values) (recurse lvar seen toplevel)
                                  (case type
                                    (:values
                                     (push (cons call values) constants))
@@ -3868,10 +3868,12 @@ is :ANY, the function name is not checked."
                     (eq (combination-kind node) :known)
                     (let ((fun-info (fun-info-constants (combination-fun-info node))))
                       (when fun-info
-                        (let ((constants (funcall fun-info node)))
-                          (when constants
+                        (multiple-value-bind (constants partial) (funcall fun-info node)
+                          (when (and constants
+                                     (or toplevel
+                                         (not partial))) ;; (car (append x constant)) is ok
                             (multiple-value-bind (kind constants)
-                                (recurse constants seen)
+                                (recurse constants seen nil)
                               (when constants
                                 (values kind constants))))))))))
         (cond ((constant-lvar-p lvar)
diff --git a/src/compiler/seqtran.lisp b/src/compiler/seqtran.lisp
index 3e1c462bb..f7b4df72f 100644
--- a/src/compiler/seqtran.lisp
+++ b/src/compiler/seqtran.lisp
@@ -4511,7 +4511,7 @@
     (make-numeric-type 'integer min max)))
 
 (defoptimizers constants
-    (nth nthcdr sb-impl::append2 nreconc revappend
+    (nth nthcdr
      %adjoin %adjoin-eq %adjoin-key %adjoin-test %adjoin-key-eq %adjoin-key-test %adjoin-key-test-not
      %assoc %assoc-eq %assoc-key %assoc-test %assoc-key-eq %assoc-key-test %assoc-key-test-not
      %rassoc %rassoc-eq %rassoc-key %rassoc-test %rassoc-key-eq %rassoc-key-test %rassoc-key-test-not
@@ -4528,8 +4528,14 @@
     ((a &rest args))
   a)
 
+(defoptimizers constants
+    (sb-impl::append2 nreconc revappend
+     %adjoin %adjoin-eq %adjoin-key %adjoin-test %adjoin-key-eq %adjoin-key-test %adjoin-key-test-not)
+    ((a b &rest args))
+  (values b t)) ;; partial result
+
 (defoptimizers constants (append nconc list*) ((&rest args))
-  (car (last args)))
+  (values (car (last args)) t))
 
 (defoptimizer (vector-to-list derive-type) ((vector))
   (when (typep (nth-value 1 (sequence-lvar-dimensions vector)) '(integer 1))
diff --git a/tests/bad-code.pure.lisp b/tests/bad-code.pure.lisp
index e0c2708f4..709b5c870 100644
--- a/tests/bad-code.pure.lisp
+++ b/tests/bad-code.pure.lisp
@@ -1130,3 +1130,8 @@
                                      (delete 2 (list* '- a))))
                           (a (* 2 3))))
                       :allow-warnings 'sb-kernel::macro-arg-modified))))
+
+(with-test (:name :constant-modification-partial-result)
+  (checked-compile
+   '(lambda (b n)
+     (delete 10 (nth n (list* b '(a b a)))))))

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


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.