master: Propagate that after (/= (rem n d) 0) D is (not (integer -1 1))

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  87930f9417b8c88c5fdc36595837ba577fb4e533 (commit)
      from  5d6cba27663dba7374d7bcc6d8cce2d0db370a8b (commit)

- Log -----------------------------------------------------------------
commit 87930f9417b8c88c5fdc36595837ba577fb4e533
Author: Stas Boukarev <[email protected]>
Date:   Thu Apr 9 21:33:47 2026 +0300

    Propagate that after (/= (rem n d) 0) D is (not (integer -1 1))
---
 src/compiler/constraint-back.lisp | 23 +++++++++++++++++------
 tests/constraint.pure.lisp        | 37 +++++++++++++++++++++++++------------
 2 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/src/compiler/constraint-back.lisp b/src/compiler/constraint-back.lisp
index ad2d8b643..73fed0401 100644
--- a/src/compiler/constraint-back.lisp
+++ b/src/compiler/constraint-back.lisp
@@ -321,22 +321,33 @@
            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(not null)) nil consequent)))))))
 
 ;;; If the remainder is non-zero then X can't be zero.
+;;; And the divisior is (not (integer -1 1))
 (defoptimizer (truncate constraint-propagate-back) ((x d) node nth-value kind constraint gen consequent alternative)
-  (let ((var (ok-lvar-lambda-var x gen)))
+  (let ((var (ok-lvar-lambda-var x gen))
+        (divisor-var (ok-lvar-lambda-var d gen)))
     (cond
       ((and var
             (eql nth-value 1)
-            (csubtypep (lvar-type x) (specifier-type 'integer))
-            (csubtypep (lvar-type d) (specifier-type 'integer)))
+            (lvar-csubtypep x integer)
+            (lvar-csubtypep d integer))
        (case kind
          (eql
           (when (and (constant-p constraint)
                      (eql (constant-value constraint) 0)
                      alternative)
-            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(and integer (not (eql 0)))) nil alternative)))
+            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(and integer (not (eql 0)))) nil alternative)
+            (when divisor-var
+              (conset-add-constraint-to-eql gen 'typep divisor-var (specifier-type '(and integer (not (integer -1 1)))) nil alternative))))
          (>
-          (when (csubtypep (lvar-type constraint) (specifier-type '(integer 0)))
-            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(integer 1)) nil consequent)))))
+          (when (lvar-csubtypep constraint (integer 0))
+            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(integer 1)) nil consequent)
+            (when divisor-var
+              (conset-add-constraint-to-eql gen 'typep divisor-var (specifier-type '(and integer (not (integer -1 1)))) nil consequent))))
+         (<
+          (when (lvar-csubtypep constraint (integer * 0))
+            (conset-add-constraint-to-eql gen 'typep var (specifier-type '(integer * -1)) nil consequent)
+            (when divisor-var
+              (conset-add-constraint-to-eql gen 'typep divisor-var (specifier-type '(and integer (not (integer -1 1)))) nil consequent))))))
       ((eq kind 'typep)
        (if (eql nth-value 1)
            (cond ((and (csubtypep constraint (specifier-type 'integer))
diff --git a/tests/constraint.pure.lisp b/tests/constraint.pure.lisp
index 846f4db39..f3914f585 100644
--- a/tests/constraint.pure.lisp
+++ b/tests/constraint.pure.lisp
@@ -535,18 +535,31 @@
     '(values integer &optional))))
 
 (with-test (:name :truncate-zero-remainder)
-  (assert
-   (type-specifiers-equal
-    (caddr
-     (sb-kernel:%simple-fun-type
-      (checked-compile
-       `(lambda (x y)
-          (declare (integer x y))
-          (multiple-value-bind (q r) (truncate x y)
-            (if (zerop r)
-                (error "~a" q)
-                x))))))
-    '(values (or (integer * -1) (integer 1)) &optional))))
+  (assert-type
+   (lambda (x y)
+     (declare (integer x y))
+     (multiple-value-bind (q r) (truncate x y)
+       (if (zerop r)
+           (error "~a" q)
+           (values x y))))
+   (values (or (integer * -1) (integer 1))
+           (or (integer * -2) (integer 2)) &optional))
+  (assert-type
+   (lambda (x y)
+     (declare (integer x y))
+     (multiple-value-bind (q r) (truncate x y)
+       (if (> r 0)
+           (values x y)
+           (error "~a" q))))
+   (values (integer 1) (or (integer * -2) (integer 2)) &optional))
+  (assert-type
+   (lambda (x y)
+     (declare (integer x y))
+     (multiple-value-bind (q r) (truncate x y)
+       (if (< r 0)
+           (values x y)
+           (error "~a" q))))
+   (values (integer * -1) (or (integer * -2) (integer 2)) &optional)))
 
 (with-test (:name :vector-length-var)
   (assert

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


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.