- (char-type (specifier-type 'character))
- (number-type (specifier-type 'number)))
- (cond ((same-leaf-ref-p x y)
- t)
- ((not (types-equal-or-intersect x-type y-type))
- nil)
- ((and (csubtypep x-type char-type)
- (csubtypep y-type char-type))
- '(char= x y))
- ((or (not (types-equal-or-intersect x-type number-type))
- (not (types-equal-or-intersect y-type number-type)))
- '(eq x y))
- ((and (not (constant-lvar-p y))
- (or (constant-lvar-p x)
- (and (csubtypep x-type y-type)
- (not (csubtypep y-type x-type)))))
- '(eql y x))
- (t
- (give-up-ir1-transform)))))
+ (char-type (specifier-type 'character)))
+ (flet ((simple-type-p (type)
+ (csubtypep type (specifier-type '(or fixnum (not number)))))
+ (fixnum-type-p (type)
+ (csubtypep type (specifier-type 'fixnum))))
+ (cond
+ ((same-leaf-ref-p x y) t)
+ ((not (types-equal-or-intersect x-type y-type))
+ nil)
+ ((and (csubtypep x-type char-type)
+ (csubtypep y-type char-type))
+ '(char= x y))
+ ((or (fixnum-type-p x-type) (fixnum-type-p y-type))
+ (give-up-ir1-transform))
+ ((or (simple-type-p x-type) (simple-type-p y-type))
+ '(eq x y))
+ ((and (not (constant-lvar-p y))
+ (or (constant-lvar-p x)
+ (and (csubtypep x-type y-type)
+ (not (csubtypep y-type x-type)))))
+ '(eql y x))
+ (t
+ (give-up-ir1-transform))))))
+
+;;; similarly to the EQL transform above, we attempt to constant-fold
+;;; or convert to a simpler predicate: mostly we have to be careful
+;;; with strings and bit-vectors.
+(deftransform equal ((x y) * *)
+ "convert to simpler equality predicate"
+ (let ((x-type (lvar-type x))
+ (y-type (lvar-type y))
+ (string-type (specifier-type 'string))
+ (bit-vector-type (specifier-type 'bit-vector)))
+ (cond
+ ((same-leaf-ref-p x y) t)
+ ((and (csubtypep x-type string-type)
+ (csubtypep y-type string-type))
+ '(string= x y))
+ ((and (csubtypep x-type bit-vector-type)
+ (csubtypep y-type bit-vector-type))
+ '(bit-vector-= x y))
+ ;; if at least one is not a string, and at least one is not a
+ ;; bit-vector, then we can reason from types.
+ ((and (not (and (types-equal-or-intersect x-type string-type)
+ (types-equal-or-intersect y-type string-type)))
+ (not (and (types-equal-or-intersect x-type bit-vector-type)
+ (types-equal-or-intersect y-type bit-vector-type)))
+ (not (types-equal-or-intersect x-type y-type)))
+ nil)
+ (t (give-up-ir1-transform)))))