From dd18ecfb2cde114c75d4f6b4a172d1f4723eafbb Mon Sep 17 00:00:00 2001 From: Christophe Rhodes Date: Tue, 4 Dec 2012 20:50:12 +0000 Subject: [PATCH] fix a bug in signed modular arithmetic Sadly not the ones that Eric gently reminds us of every month or so, but a far more basic one. If something is a (signed-byte x), its integer-length will be at most (1- x). Search appropriately for a signed arithmetic variant. --- src/compiler/srctran.lisp | 2 +- tests/compiler.pure.lisp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/srctran.lisp b/src/compiler/srctran.lisp index 3278e7b..7736902 100644 --- a/src/compiler/srctran.lisp +++ b/src/compiler/srctran.lisp @@ -3160,7 +3160,7 @@ (when (and (numberp low) (numberp high)) (let ((width (max (integer-length high) (integer-length low)))) (multiple-value-bind (w kind) - (best-modular-version width t) + (best-modular-version (1+ width) t) (when w ;; FIXME: This should be (CUT-TO-WIDTH NODE KIND W T). ;; [ see comment above in LOGAND optimizer ] diff --git a/tests/compiler.pure.lisp b/tests/compiler.pure.lisp index 7d8faf1..8e37cf2 100644 --- a/tests/compiler.pure.lisp +++ b/tests/compiler.pure.lisp @@ -4357,3 +4357,16 @@ (destructuring-bind (orig conservative) pair (assert sb-c::(type= (specifier-type cl-user::conservative) (conservative-type (specifier-type cl-user::orig)))))))) + +(with-test (:name (:smodular64 :wrong-width)) + (let ((fun (compile nil + '(lambda (x) + (declare (type (signed-byte 64) x)) + (sb-c::mask-signed-field 64 (- x 7033717698976965573)))))) + (assert (= (funcall fun 10038) -7033717698976955535)))) + +(with-test (:name (:smodular32 :wrong-width)) + (let ((fun (compile nil '(lambda (x) + (declare (type (signed-byte 31) x)) + (sb-c::mask-signed-field 31 (- x 1055131947)))))) + (assert (= (funcall fun 10038) -1055121909)))) -- 1.7.10.4