(defun constant-lvar-p (thing)
(declare (type (or lvar null) thing))
(and (lvar-p thing)
- (let ((use (principal-lvar-use thing)))
- (and (ref-p use) (constant-p (ref-leaf use))))))
+ (or (let ((use (principal-lvar-use thing)))
+ (and (ref-p use) (constant-p (ref-leaf use))))
+ ;; check for EQL types (but not singleton numeric types)
+ (let ((type (lvar-type thing)))
+ (and (member-type-p type)
+ (eql 1 (member-type-size type)))))))
;;; Return the constant value for an LVAR whose only use is a constant
;;; node.
(declaim (ftype (function (lvar) t) lvar-value))
(defun lvar-value (lvar)
- (let ((use (principal-lvar-use lvar)))
- (constant-value (ref-leaf use))))
+ (let ((use (principal-lvar-use lvar))
+ (type (lvar-type lvar))
+ leaf)
+ (cond ((and (ref-p use)
+ (constant-p (setf leaf (ref-leaf use))))
+ (constant-value leaf))
+ ((and (member-type-p type)
+ (eql 1 (member-type-size type)))
+ (first (member-type-members type)))
+ (t
+ (error "~S used on non-constant LVAR ~S" 'lvar-value lvar)))))
\f
;;;; interface for obtaining results of type inference
:load-if (not (sc-is x ,constant-sc)))
(y :scs (,sc ,constant-sc)
:target mask
- :load-if (not (sc-is x ,constant-sc))))
+ :load-if (not (sc-is y ,constant-sc))))
(:arg-types ,type ,type)
(:temporary (:sc ,sc :from :eval) mask)
(:temporary (:sc any-reg) bits)
(assert (eql 0.0d0 (funcall f 123.0d0 0.0)))
(assert (eql 0.0d0 (funcall f 123.0d0 0.0d0)))
(assert (eql 0.0d0 (funcall f 123.0 0.0d0)))))
+
+;; Bug reported by Eric Marsden on July 15 2009. The compiler
+;; used not to constant fold calls with arguments of type
+;; (EQL foo).
+(with-test (:name :eql-type-constant-fold)
+ (assert (equal '(FUNCTION (T) (VALUES (MEMBER T) &OPTIONAL))
+ (sb-kernel:%simple-fun-type
+ (compile nil `(lambda (x)
+ (eql #c(1.0 2.0)
+ (the (eql #c(1.0 2.0))
+ x))))))))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.30.1"
+"1.0.30.2"