do
(let ((lvar-type (lvar-type arg)))
(unless (or (csubtypep list-type lvar-type)
- (csubtypep lvar-type list-type))
+ (csubtypep lvar-type list-type)
+ ;; Check for NIL specifically, because
+ ;; SYMBOL or ATOM won't satisfie the above
+ (csubtypep null-type lvar-type))
(assert-lvar-type arg list-type
(lexenv-policy *lexenv*))
(return *empty-type*))))
"Convert %ASH/RIGHT by constant back to ASH"
`(ash integer ,(- (lvar-value amount))))
- (deftransform %ash/right ((integer amount) * (member -1 0) :node node)
- ;; constant-fold large shifts
+ (deftransform %ash/right ((integer amount) * * :node node)
+ "strength reduce large variable right shift"
(let ((return-type (single-value-type (node-derived-type node))))
(cond ((type= return-type (specifier-type '(eql 0)))
0)
((type= return-type (specifier-type '(eql -1)))
-1)
+ ((csubtypep return-type (specifier-type '(member -1 0)))
+ `(ash integer ,(- sb!vm:n-word-bits)))
(t
- (aver (csubtypep (lvar-type integer) (specifier-type 'sb!vm:signed-word)))
- `(ash integer ,(- 1 sb!vm:n-word-bits))))))
+ (give-up-ir1-transform)))))
(defun %ash/right-derive-type-aux (n-type shift same-arg)
(declare (ignore same-arg))
(mask-signed-field width constant-value)
(ldb (byte width 0) constant-value))))
(unless (= constant-value new-value)
- (change-ref-leaf node (make-constant new-value))
+ (change-ref-leaf node (make-constant new-value)
+ :recklessly t)
(let ((lvar (node-lvar node)))
(setf (lvar-%derived-type lvar)
(and (lvar-has-single-use-p lvar)
(if (and (constant-lvar-p x)
(not (constant-lvar-p y)))
`(,(lvar-fun-name (basic-combination-fun node))
- y
+ (truly-the ,(lvar-type y) y)
,(lvar-value x))
(give-up-ir1-transform)))
-(dolist (x '(= char= + * logior logand logxor))
+(dolist (x '(= char= + * logior logand logxor logtest))
(%deftransform x '(function * *) #'commutative-arg-swap
"place constant arg last"))
(splice-fun-args x '%negate 1)
'(the rational x))
+(deftransform %negate ((x) (number))
+ "Combine %negate/*"
+ (let ((use (lvar-uses x))
+ arg)
+ (unless (and (combination-p use)
+ (eql '* (lvar-fun-name (combination-fun use)))
+ (constant-lvar-p (setf arg (second (combination-args use))))
+ (numberp (setf arg (lvar-value arg))))
+ (give-up-ir1-transform))
+ (splice-fun-args x '* 2)
+ `(lambda (x y)
+ (declare (ignore y))
+ (* x ,(- arg)))))
+
;;; Return T if in an arithmetic op including lvars X and Y, the
;;; result type is not affected by the type of X. That is, Y is at
;;; least as contagious as X.
(policy-quality-name-p (lvar-value quality-name)))
(give-up-ir1-transform))
'(%policy-quality policy quality-name))
+\f
+(deftransform encode-universal-time
+ ((second minute hour date month year &optional time-zone)
+ ((constant-arg (mod 60)) (constant-arg (mod 60))
+ (constant-arg (mod 24))
+ (constant-arg (integer 1 31))
+ (constant-arg (integer 1 12))
+ (constant-arg (integer 1899))
+ (constant-arg (rational -24 24))))
+ (let ((second (lvar-value second))
+ (minute (lvar-value minute))
+ (hour (lvar-value hour))
+ (date (lvar-value date))
+ (month (lvar-value month))
+ (year (lvar-value year))
+ (time-zone (lvar-value time-zone)))
+ (if (zerop (rem time-zone 1/3600))
+ (encode-universal-time second minute hour date month year time-zone)
+ (give-up-ir1-transform))))