aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Corallo2021-02-27 22:00:11 +0100
committerAndrea Corallo2021-02-28 23:30:03 +0100
commit5bc08559e8f171eafc3c034232f8cfd9eaf89862 (patch)
treea8337beeb2bbb180603cccc754fbc52a0700ff38
parent2acc46b55bdf518ece6301913ffa074f31563fa4 (diff)
downloademacs-5bc08559e8f171eafc3c034232f8cfd9eaf89862.tar.gz
emacs-5bc08559e8f171eafc3c034232f8cfd9eaf89862.zip
Don't treat '=' as simple equality emitting constraints (bug#46812)
Extend assumes allowing the following form (assume dst (= src1 src2)) to caputure '=' semanting during fwprop handling float integer conversions. * lisp/emacs-lisp/comp.el (comp-equality-fun-p): Don't treat '=' as simple equality. (comp-arithm-cmp-fun-p, comp-negate-arithm-cmp-fun) (comp-reverse-arithm-fun): Rename and add '=' '!='. (comp-emit-assume, comp-add-cond-cstrs, comp-fwprop-insn): Update for new function nameing and to handle '='. * lisp/emacs-lisp/comp-cstr.el (comp-cstr-=): New function. * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a bunch of '=' specific tests.
-rw-r--r--lisp/emacs-lisp/comp-cstr.el12
-rw-r--r--lisp/emacs-lisp/comp.el37
-rw-r--r--test/src/comp-tests.el47
3 files changed, 75 insertions, 21 deletions
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index 89815f03b53..bd1e04fb0bb 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -859,6 +859,18 @@ Non memoized version of `comp-cstr-intersection-no-mem'."
859 (null (neg cstr)) 859 (null (neg cstr))
860 (equal (typeset cstr) '(cons))))) 860 (equal (typeset cstr) '(cons)))))
861 861
862(defun comp-cstr-= (dst old-dst src)
863 "Constraint DST being = SRC."
864 (with-comp-cstr-accessors
865 (comp-cstr-intersection dst old-dst src)
866 (cl-loop for v in (valset dst)
867 when (and (floatp v)
868 (= v (truncate v)))
869 do (push (cons (truncate v) (truncate v)) (range dst)))
870 (cl-loop for (l . h) in (range dst)
871 when (eql l h)
872 do (push (float l) (valset dst)))))
873
862(defun comp-cstr-> (dst old-dst src) 874(defun comp-cstr-> (dst old-dst src)
863 "Constraint DST being > than SRC. 875 "Constraint DST being > than SRC.
864SRC can be either a comp-cstr or an integer." 876SRC can be either a comp-cstr or an integer."
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index e71d4abbd53..03999d3e66f 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -906,11 +906,11 @@ To be used by all entry points."
906 906
907(defun comp-equality-fun-p (function) 907(defun comp-equality-fun-p (function)
908 "Equality functions predicate for FUNCTION." 908 "Equality functions predicate for FUNCTION."
909 (when (memq function '(eq eql = equal)) t)) 909 (when (memq function '(eq eql equal)) t))
910 910
911(defun comp-range-cmp-fun-p (function) 911(defun comp-arithm-cmp-fun-p (function)
912 "Predicate for range comparision functions." 912 "Predicate for arithmetic comparision functions."
913 (when (memq function '(> < >= <=)) t)) 913 (when (memq function '(= > < >= <=)) t))
914 914
915(defun comp-set-op-p (op) 915(defun comp-set-op-p (op)
916 "Assignment predicate for OP." 916 "Assignment predicate for OP."
@@ -2238,17 +2238,21 @@ into the C code forwarding the compilation unit."
2238 else 2238 else
2239 do (comp-collect-mvars args)))) 2239 do (comp-collect-mvars args))))
2240 2240
2241(defun comp-negate-range-cmp-fun (function) 2241(defun comp-negate-arithm-cmp-fun (function)
2242 "Negate FUNCTION." 2242 "Negate FUNCTION.
2243Return nil if we don't want to emit constraints for its
2244negation."
2243 (cl-ecase function 2245 (cl-ecase function
2246 (= nil)
2244 (> '<=) 2247 (> '<=)
2245 (< '>=) 2248 (< '>=)
2246 (>= '<) 2249 (>= '<)
2247 (<= '>))) 2250 (<= '>)))
2248 2251
2249(defun comp-reverse-cmp-fun (function) 2252(defun comp-reverse-arithm-fun (function)
2250 "Reverse FUNCTION." 2253 "Reverse FUNCTION."
2251 (cl-case function 2254 (cl-case function
2255 (= '=)
2252 (> '<) 2256 (> '<)
2253 (< '>) 2257 (< '>)
2254 (>= '<=) 2258 (>= '<=)
@@ -2279,15 +2283,16 @@ The assume is emitted at the beginning of the block BB."
2279 (comp-cstr-negation-make rhs) 2283 (comp-cstr-negation-make rhs)
2280 rhs))) 2284 rhs)))
2281 (comp-block-insns bb)))) 2285 (comp-block-insns bb))))
2282 ((pred comp-range-cmp-fun-p) 2286 ((pred comp-arithm-cmp-fun-p)
2283 (let ((kind (if negated 2287 (when-let ((kind (if negated
2284 (comp-negate-range-cmp-fun kind) 2288 (comp-negate-arithm-cmp-fun kind)
2285 kind))) 2289 kind)))
2286 (push `(assume ,(make-comp-mvar :slot lhs-slot) 2290 (push `(assume ,(make-comp-mvar :slot lhs-slot)
2287 (,kind ,lhs 2291 (,kind ,lhs
2288 ,(if-let* ((vld (comp-cstr-imm-vld-p rhs)) 2292 ,(if-let* ((vld (comp-cstr-imm-vld-p rhs))
2289 (val (comp-cstr-imm rhs)) 2293 (val (comp-cstr-imm rhs))
2290 (ok (integerp val))) 2294 (ok (and (integerp val)
2295 (not (memq kind '(= !=))))))
2291 val 2296 val
2292 (make-comp-mvar :slot (comp-mvar-slot rhs))))) 2297 (make-comp-mvar :slot (comp-mvar-slot rhs)))))
2293 (comp-block-insns bb)))) 2298 (comp-block-insns bb))))
@@ -2418,7 +2423,7 @@ TARGET-BB-SYM is the symbol name of the target block."
2418 (`((set ,(and (pred comp-mvar-p) cmp-res) 2423 (`((set ,(and (pred comp-mvar-p) cmp-res)
2419 (,(pred comp-call-op-p) 2424 (,(pred comp-call-op-p)
2420 ,(and (or (pred comp-equality-fun-p) 2425 ,(and (or (pred comp-equality-fun-p)
2421 (pred comp-range-cmp-fun-p)) 2426 (pred comp-arithm-cmp-fun-p))
2422 fun) 2427 fun)
2423 ,op1 ,op2)) 2428 ,op1 ,op2))
2424 ;; (comment ,_comment-str) 2429 ;; (comment ,_comment-str)
@@ -2441,7 +2446,7 @@ TARGET-BB-SYM is the symbol name of the target block."
2441 (comp-maybe-add-vmvar op2 cmp-res prev-insns-seq) 2446 (comp-maybe-add-vmvar op2 cmp-res prev-insns-seq)
2442 block-target negated)) 2447 block-target negated))
2443 (when (comp-mvar-used-p target-mvar2) 2448 (when (comp-mvar-used-p target-mvar2)
2444 (comp-emit-assume (comp-reverse-cmp-fun kind) 2449 (comp-emit-assume (comp-reverse-arithm-fun kind)
2445 target-mvar2 2450 target-mvar2
2446 (comp-maybe-add-vmvar op1 cmp-res prev-insns-seq) 2451 (comp-maybe-add-vmvar op1 cmp-res prev-insns-seq)
2447 block-target negated))) 2452 block-target negated)))
@@ -3108,7 +3113,9 @@ Fold the call in case."
3108 (< 3113 (<
3109 (comp-cstr-< lval (car operands) (cadr operands))) 3114 (comp-cstr-< lval (car operands) (cadr operands)))
3110 (<= 3115 (<=
3111 (comp-cstr-<= lval (car operands) (cadr operands))))) 3116 (comp-cstr-<= lval (car operands) (cadr operands)))
3117 (=
3118 (comp-cstr-= lval (car operands) (cadr operands)))))
3112 (`(setimm ,lval ,v) 3119 (`(setimm ,lval ,v)
3113 (setf (comp-cstr-imm lval) v)) 3120 (setf (comp-cstr-imm lval) v))
3114 (`(phi ,lval . ,rest) 3121 (`(phi ,lval . ,rest)
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 402ba7cd8b8..0598eeeb05d 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -891,24 +891,24 @@ Return a list of results."
891 891
892 ;; 10 892 ;; 10
893 ((defun comp-tests-ret-type-spec-f (x) 893 ((defun comp-tests-ret-type-spec-f (x)
894 (if (= x 3) 894 (if (eql x 3)
895 x 895 x
896 'foo)) 896 'foo))
897 (or (member foo) (integer 3 3))) 897 (or (member foo) (integer 3 3)))
898 898
899 ;; 11 899 ;; 11
900 ((defun comp-tests-ret-type-spec-f (x) 900 ((defun comp-tests-ret-type-spec-f (x)
901 (if (= 3 x) 901 (if (eql 3 x)
902 x 902 x
903 'foo)) 903 'foo))
904 (or (member foo) (integer 3 3))) 904 (or (member foo) (integer 3 3)))
905 905
906 ;; 12 906 ;; 12
907 ((defun comp-tests-ret-type-spec-f (x) 907 ((defun comp-tests-ret-type-spec-f (x)
908 (if (= x 3) 908 (if (eql x 3)
909 'foo 909 'foo
910 x)) 910 x))
911 (or (member foo) marker number)) 911 (not (integer 3 3)))
912 912
913 ;; 13 913 ;; 13
914 ((defun comp-tests-ret-type-spec-f (x y) 914 ((defun comp-tests-ret-type-spec-f (x y)
@@ -1214,7 +1214,7 @@ Return a list of results."
1214 ;; 57 1214 ;; 57
1215 ((defun comp-tests-ret-type-spec-f (x) 1215 ((defun comp-tests-ret-type-spec-f (x)
1216 (unless (or (eq x 'foo) 1216 (unless (or (eq x 'foo)
1217 (= x 3)) 1217 (eql x 3))
1218 (error "Not foo or 3")) 1218 (error "Not foo or 3"))
1219 x) 1219 x)
1220 (or (member foo) (integer 3 3))) 1220 (or (member foo) (integer 3 3)))
@@ -1244,7 +1244,42 @@ Return a list of results."
1244 (>= x y)) 1244 (>= x y))
1245 x 1245 x
1246 (error ""))) 1246 (error "")))
1247 (or float (integer 3 10))))) 1247 (or float (integer 3 10)))
1248
1249 ;; 61
1250 ((defun comp-tests-ret-type-spec-f (x)
1251 (if (= x 1.0)
1252 x
1253 (error "")))
1254 (or (member 1.0) (integer 1 1)))
1255
1256 ;; 62
1257 ((defun comp-tests-ret-type-spec-f (x)
1258 (if (= x 1.0)
1259 x
1260 (error "")))
1261 (or (member 1.0) (integer 1 1)))
1262
1263 ;; 63
1264 ((defun comp-tests-ret-type-spec-f (x)
1265 (if (= x 1.1)
1266 x
1267 (error "")))
1268 (member 1.1))
1269
1270 ;; 64
1271 ((defun comp-tests-ret-type-spec-f (x)
1272 (if (= x 1)
1273 x
1274 (error "")))
1275 (or (member 1.0) (integer 1 1)))
1276
1277 ;; 65
1278 ((defun comp-tests-ret-type-spec-f (x)
1279 (if (= x 1)
1280 x
1281 (error "")))
1282 (or (member 1.0) (integer 1 1)))))
1248 1283
1249 (defun comp-tests-define-type-spec-test (number x) 1284 (defun comp-tests-define-type-spec-test (number x)
1250 `(comp-deftest ,(intern (format "ret-type-spec-%d" number)) () 1285 `(comp-deftest ,(intern (format "ret-type-spec-%d" number)) ()