check-mod-fixnum: correct the test for power-of-two.
authorStas Boukarev <stassats@gmail.com>
Tue, 11 Jun 2013 11:20:10 +0000 (15:20 +0400)
committerStas Boukarev <stassats@gmail.com>
Tue, 11 Jun 2013 11:20:10 +0000 (15:20 +0400)
Testing for the power of two was performed on a fixnumized number,
causing the optimization for power-of-two to be never applied.

src/compiler/x86-64/type-vops.lisp
src/compiler/x86/type-vops.lisp

index 5c54135..f5a50f6 100644 (file)
   (:temporary (:sc any-reg) temp)
   (:generator 30
      (let* ((low (numeric-type-low type))
-            (hi (fixnumize (numeric-type-high type)))
+            (hi (numeric-type-high type))
+            (fixnum-hi (fixnumize hi))
             (error (gen-label)))
        ;; FIXME: abstract
        (assemble (*elsewhere*)
          (emit-label error)
-         (inst mov temp hi)
+         ;; The general case uses the number directly,
+         ;; and it will already have the number constantized
+         ;; even though MOV can use 64-bit immediates,
+         ;; using the same inlined constant will save space
+         (if (= (logcount (1+ hi)) 1)
+             (inst mov temp fixnum-hi)
+             (inst mov temp (constantize fixnum-hi)))
          (emit-error-break vop error-trap
                            (error-number-or-lose 'object-not-mod-error)
                            (list value temp)))
          ;; The higher bits and the fixnum tag can be tested in one go
          ((= (logcount (1+ hi)) 1)
           (inst test value
-                (constantize (lognot hi)))
+                (constantize (lognot fixnum-hi)))
           (inst jmp :ne error))
          (t
           (generate-fixnum-test value)
           (inst jmp :ne error)
-          (inst cmp value (constantize hi))
+          (inst cmp value (constantize fixnum-hi))
           (inst jmp :a error)))
        (move result value))))
 
index 4ad6d5d..a0223ff 100644 (file)
   (:temporary (:sc any-reg) temp)
   (:generator 30
      (let* ((low (numeric-type-low type))
-            (hi (fixnumize (numeric-type-high type)))
+            (hi (numeric-type-high type))
+            (fixnum-hi (fixnumize hi))
             (error (gen-label)))
        ;; FIXME: abstract
        (assemble (*elsewhere*)
          (emit-label error)
-         (inst mov temp hi)
+         (inst mov temp fixnum-hi)
          (emit-error-break vop error-trap
                            (error-number-or-lose 'object-not-mod-error)
                            (list value temp)))
          ;; Handle powers of two specially
          ;; The higher bits and the fixnum tag can be tested in one go
          ((= (logcount (1+ hi)) 1)
-          (inst test value (lognot hi))
+          (inst test value (lognot fixnum-hi))
           (inst jmp :ne error))
          (t
           (generate-fixnum-test value)
           (inst jmp :ne error)
-          (inst cmp value hi)
+          (inst cmp value fixnum-hi)
           (inst jmp :a error)))
        (move result value))))