diff options
| author | Andrea Corallo | 2021-02-27 22:00:11 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2021-02-28 23:30:03 +0100 |
| commit | 5bc08559e8f171eafc3c034232f8cfd9eaf89862 (patch) | |
| tree | a8337beeb2bbb180603cccc754fbc52a0700ff38 | |
| parent | 2acc46b55bdf518ece6301913ffa074f31563fa4 (diff) | |
| download | emacs-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.el | 12 | ||||
| -rw-r--r-- | lisp/emacs-lisp/comp.el | 37 | ||||
| -rw-r--r-- | test/src/comp-tests.el | 47 |
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. |
| 864 | SRC can be either a comp-cstr or an integer." | 876 | SRC 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. |
| 2243 | Return nil if we don't want to emit constraints for its | ||
| 2244 | negation." | ||
| 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)) () |