From 7b0a5329706a6c73e49b5e3b464543f8ba94f21d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Fri, 3 Jul 2020 20:13:50 +0200
Subject: [PATCH] Relax portable number check in byte compiler (bug#42147)

With bignums, the set of representable integers is no longer
platform-dependent, and since we use nothing but IEEE754 64-bit
floats, all numbers are now portable.  Take advantage of this fact
to simplify constant-folding in the byte compiler, allowing it to
be applied more widely.

* lisp/emacs-lisp/byte-opt.el (byte-opt--portable-max)
(byte-opt--portable-min, byte-opt--portable-numberp): Remove.
(byte-opt--arith-reduce, byte-optimize-minus, byte-optimize-1+)
(byte-optimize-1-): Simplify: any number will do, and if N is a
number, then so are -N, N+1 and N-1.
---
 lisp/emacs-lisp/byte-opt.el | 39 +++++++++----------------------------
 1 file changed, 9 insertions(+), 30 deletions(-)

diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 12bde8faf3..bf9e6a728a 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -672,36 +672,18 @@ byte-optimize-associative-math
 	    (apply (car form) constants))
 	form)))
 
-;; Portable Emacs integers fall in this range.
-(defconst byte-opt--portable-max #x1fffffff)
-(defconst byte-opt--portable-min (- -1 byte-opt--portable-max))
-
-;; True if N is a number that works the same on all Emacs platforms.
-;; Portable Emacs fixnums are exactly representable as floats on all
-;; Emacs platforms, and (except for -0.0) any floating-point number
-;; that equals one of these integers must be the same on all
-;; platforms.  Although other floating-point numbers such as 0.5 are
-;; also portable, it can be tricky to characterize them portably so
-;; they are not optimized.
-(defun byte-opt--portable-numberp (n)
-  (and (numberp n)
-       (<= byte-opt--portable-min n byte-opt--portable-max)
-       (= n (floor n))
-       (not (and (floatp n) (zerop n)
-                 (condition-case () (< (/ n) 0) (error))))))
-
-;; Use OP to reduce any leading prefix of portable numbers in the list
-;; (cons ACCUM ARGS) down to a single portable number, and return the
+;; Use OP to reduce any leading prefix of constant numbers in the list
+;; (cons ACCUM ARGS) down to a single number, and return the
 ;; resulting list A of arguments.  The idea is that applying OP to A
 ;; is equivalent to (but likely more efficient than) applying OP to
 ;; (cons ACCUM ARGS), on any Emacs platform.  Do not make any special
 ;; provision for (- X) or (/ X); for example, it is the caller’s
 ;; responsibility that (- 1 0) should not be "optimized" to (- 1).
 (defun byte-opt--arith-reduce (op accum args)
-  (when (byte-opt--portable-numberp accum)
+  (when (numberp accum)
     (let (accum1)
-      (while (and (byte-opt--portable-numberp (car args))
-                  (byte-opt--portable-numberp
+      (while (and (numberp (car args))
+                  (numberp
                    (setq accum1 (condition-case ()
                                     (funcall op accum (car args))
                                   (error))))
@@ -746,12 +728,11 @@ byte-optimize-minus
        ;; (- x -1) --> (1+ x)
        ((equal (cdr args) '(-1))
         (list '1+ (car args)))
-       ;; (- n) -> -n, where n and -n are portable numbers.
+       ;; (- n) -> -n, where n and -n are constant numbers.
        ;; This must be done separately since byte-opt--arith-reduce
        ;; is not applied to (- n).
        ((and (null (cdr args))
-             (byte-opt--portable-numberp (car args))
-             (byte-opt--portable-numberp (- (car args))))
+             (numberp (car args)))
         (- (car args)))
        ;; not further optimized
        ((equal args (cdr form)) form)
@@ -761,8 +742,7 @@ byte-optimize-1+
   (let ((args (cdr form)))
     (when (null (cdr args))
       (let ((n (car args)))
-        (when (and (byte-opt--portable-numberp n)
-                   (byte-opt--portable-numberp (1+ n)))
+        (when (numberp n)
           (setq form (1+ n))))))
   form)
 
@@ -770,8 +750,7 @@ byte-optimize-1-
   (let ((args (cdr form)))
     (when (null (cdr args))
       (let ((n (car args)))
-        (when (and (byte-opt--portable-numberp n)
-                   (byte-opt--portable-numberp (1- n)))
+        (when (numberp n)
           (setq form (1- n))))))
   form)
 
-- 
2.21.1 (Apple Git-122.3)

