Previously (+ X 0) was reduced to (+ X) which became (* X 1) in
codegen, but this is wrong for X = -0.0 and also slightly slower.
* lisp/emacs-lisp/byte-opt.el (byte-optimize-plus): Don't reduce an
addition to (+ X) by eliminating zeros; retain one 0 argument.
* test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
Add test case.
(cons accum args))
(defun byte-optimize-plus (form)
- (let ((args (remq 0 (byte-opt--arith-reduce #'+ 0 (cdr form)))))
+ (let* ((not-0 (remq 0 (byte-opt--arith-reduce #'+ 0 (cdr form))))
+ (args (if (and (= (length not-0) 1)
+ (> (length form) 2))
+ ;; We removed numbers and only one arg remains: add a 0
+ ;; so that it isn't turned into (* X 1) later on.
+ (append not-0 '(0))
+ not-0)))
(cond
;; (+) -> 0
((null args) 0)
(nconc x nil nil))
(let ((x (cons 1 (cons 2 (cons 3 4)))))
(nconc nil x nil (list 5 6) nil))
+
+ ;; (+ 0 -0.0) etc
+ (let ((x (bytecomp-test-identity -0.0)))
+ (list x (+ x) (+ 0 x) (+ x 0) (+ 1 2 -3 x) (+ 0 x 0)))
)
"List of expressions for cross-testing interpreted and compiled code.")