diff --git a/pcl/cmu-low.lisp b/pcl/cmu-low.lisp
index d8e7618feed299e63c6854b9a6b2c421c75531ed..5b5b08368c14f9f978273b54eefb8509fe1d1af6 100644
--- a/pcl/cmu-low.lisp
+++ b/pcl/cmu-low.lisp
@@ -127,8 +127,32 @@
 ;;;
 (defmacro std-instance-p (x)
   `(kernel:%instancep ,x))
-(defmacro pcl-instance-p (x)
-  `(typep (kernel:layout-of ,x) 'wrapper))
+
+;;; PCL-INSTANCE-P is implemented via a compiler transform so that the
+;;; test can be optimised away when the result is known, such as is
+;;; typically the case during slot access within methods, see
+;;; get-slots-or-nil below.
+
+(in-package "C")
+
+(defknown pcl::pcl-instance-p (t) boolean
+  (movable foldable flushable explicit-check))
+
+(deftransform pcl::pcl-instance-p ((object))
+  (let* ((otype (continuation-type object))
+	 (std-obj (specifier-type 'pcl::std-object)))
+    (cond
+      ;; Flush tests whose result is known at compile time.
+      ((csubtypep otype std-obj) 't)
+      ((not (types-intersect otype std-obj)) 'nil)
+      (t
+       `(typep (kernel:layout-of object) 'pcl::wrapper)))))
+
+(in-package "PCL")
+
+;;; Definition for interpreted code.
+(defun pcl-instance-p (x)
+  (typep (kernel:layout-of x) 'wrapper))
 
 
 ;;; We define this as STANDARD-INSTANCE, since we're going to clobber the