* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) @ 2024-12-10 16:55 Eric Marsden 2024-12-10 21:21 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Eric Marsden @ 2024-12-10 16:55 UTC (permalink / raw) To: 74771 [-- Attachment #1: Type: text/plain, Size: 671 bytes --] Hi, With the attached source file, Emacs miscompiles the struct predicate such that a repeated call to the predicate on a non-struct object returns t. This occurs with current HEAD on Linux/AMD64, but not on the Emacs 30.0.92 pretest. It does not occur when the lexical binding cookie is not present. % /opt/emacs/bin/emacs -Q --batch --eval "(load (native-compile \"/tmp/bug.el\"))" -f run Loading /home/emarsden/.emacs.d/eln-cache/31.0.50-c021c983/bug-59c4b27c-c70072f9.eln (native compiled elisp)... Running in GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.43, cairo version 1.18.2) of 2024-12-09 is? nil is? t ;; expecting nil bar: 111 [-- Attachment #2: bug.el --] [-- Type: text/x-emacs-lisp, Size: 409 bytes --] ;;; -*- lexical-binding: t -*- ;; ;; /opt/emacs/bin/emacs -Q --batch -L . --eval "(load (native-compile \"/tmp/bug.el\"))" -f run (require 'cl-lib) (cl-defstruct foobles bar baz) (defun bug (foo) (message "is? %s" (foobles-p foo)) (message "is? %s" (foobles-p foo)) (message "bar: %s" (foobles-bar foo))) (defun run () (message "Running in %s" (version)) (let ((foo "foo")) (bug foo))) ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) 2024-12-10 16:55 bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) Eric Marsden @ 2024-12-10 21:21 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-10 22:12 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-11 22:29 ` Andrea Corallo 2 siblings, 0 replies; 6+ messages in thread From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-10 21:21 UTC (permalink / raw) To: Eric Marsden; +Cc: 74771 "Eric Marsden" <eric.marsden@risk-engineering.org> writes: > Hi, > > With the attached source file, Emacs miscompiles the struct predicate such > that a repeated call to the predicate on a non-struct object returns t. > This occurs with current HEAD on Linux/AMD64, but not on the Emacs 30.0.92 > pretest. It does not occur when the lexical binding cookie is not present. > > % /opt/emacs/bin/emacs -Q --batch --eval "(load (native-compile \"/tmp/bug.el\"))" -f run > Loading /home/emarsden/.emacs.d/eln-cache/31.0.50-c021c983/bug-59c4b27c-c70072f9.eln (native compiled elisp)... > Running in GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.43, cairo version 1.18.2) > of 2024-12-09 > is? nil > is? t ;; expecting nil > bar: 111 > > [2. text/x-emacs-lisp; bug.el]... Can you try this patch? diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 0d40f05bef1..c3e9a8be66d 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -2029,15 +2029,18 @@ comp--add-cond-cstrs (call symbol-value ,(and (pred comp-cstr-cl-tag-p) mvar-tag))) (set ,(and (pred comp-mvar-p) mvar-3) (call memq ,(and (pred comp-mvar-p) mvar-1) ,(and (pred comp-mvar-p) mvar-2))) - (cond-jump ,(and (pred comp-mvar-p) mvar-3) ,(pred comp-mvar-p) ,bb1 ,bb2)) - (comp--emit-assume 'and mvar-tested - (make--comp-mvar :type (comp-cstr-cl-tag mvar-tag)) - (comp--add-cond-cstrs-target-block b bb2) - nil) - (comp--emit-assume 'and mvar-tested - (make--comp-mvar :type (comp-cstr-cl-tag mvar-tag)) - (comp--add-cond-cstrs-target-block b bb1) - t)) + (cond-jump ,(and (pred comp-mvar-p) mvar-3) ,(and (pred comp-mvar-p) mvar-4) ,bb1 ,bb2)) + (cond + ((and (comp-cstr-imm-vld-p mvar-4) + (eq (comp-cstr-imm mvar-4) t)) + (comp--emit-assume 'and mvar-tested + (make--comp-mvar :type (comp-cstr-cl-tag mvar-tag)) + (comp--add-cond-cstrs-target-block b bb2) + nil) + (comp--emit-assume 'and mvar-tested + (make--comp-mvar :type (comp-cstr-cl-tag mvar-tag)) + (comp--add-cond-cstrs-target-block b bb1) + t)))) (`((set ,(and (pred comp-mvar-p) cmp-res) (,(pred comp--call-op-p) ,(and (or (pred comp--equality-fun-p) IIUC, the code blindly assumes that cond-jump would use t as its second argument. In your code, the second argument was nil, so the assumptions were put into the wrong basic blocks. It looks like there are quite a few such assumptions in comp.el. I think we should fix them all to ensure that they test for truth, not falsehood. After that, we'll have to decide whether it's worth it to optimize the negated cases. Pip ^ permalink raw reply related [flat|nested] 6+ messages in thread
* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) 2024-12-10 16:55 bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) Eric Marsden 2024-12-10 21:21 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-10 22:12 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-11 12:32 ` Eli Zaretskii 2024-12-11 22:29 ` Andrea Corallo 2 siblings, 1 reply; 6+ messages in thread From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-10 22:12 UTC (permalink / raw) To: Eric Marsden; +Cc: 74771 Pip Cet <pipcet@protonmail.com> writes: > IIUC, the code blindly assumes that cond-jump would use t as its second > argument. In your code, the second argument was nil, so the assumptions > were put into the wrong basic blocks. I did not understand correctly. It seems cond-jump is still limited to a nil second argument, which is an undocumented assumption that comp.el continues to rely on. I still think comp--emit-assume does the wrong thing when negating an assumption, but we've been there before... Pip ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) 2024-12-10 22:12 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-11 12:32 ` Eli Zaretskii 2024-12-11 14:01 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 6+ messages in thread From: Eli Zaretskii @ 2024-12-11 12:32 UTC (permalink / raw) To: Pip Cet, Andrea Corallo; +Cc: 74771, eric.marsden > Cc: 74771@debbugs.gnu.org > Date: Tue, 10 Dec 2024 22:12:03 +0000 > From: Pip Cet via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org> > > Pip Cet <pipcet@protonmail.com> writes: > > > IIUC, the code blindly assumes that cond-jump would use t as its second > > argument. In your code, the second argument was nil, so the assumptions > > were put into the wrong basic blocks. > > I did not understand correctly. It seems cond-jump is still limited to > a nil second argument, which is an undocumented assumption that comp.el > continues to rely on. > > I still think comp--emit-assume does the wrong thing when negating an > assumption, but we've been there before... Let's hear from Andrea (CC'ed) about this. ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) 2024-12-11 12:32 ` Eli Zaretskii @ 2024-12-11 14:01 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 0 replies; 6+ messages in thread From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-11 14:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Andrea Corallo, 74771, eric.marsden "Eli Zaretskii" <eliz@gnu.org> writes: >> Cc: 74771@debbugs.gnu.org >> Date: Tue, 10 Dec 2024 22:12:03 +0000 >> From: Pip Cet via "Bug reports for GNU Emacs, >> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org> >> >> Pip Cet <pipcet@protonmail.com> writes: >> >> > IIUC, the code blindly assumes that cond-jump would use t as its second >> > argument. In your code, the second argument was nil, so the assumptions >> > were put into the wrong basic blocks. >> >> I did not understand correctly. It seems cond-jump is still limited to >> a nil second argument, which is an undocumented assumption that comp.el >> continues to rely on. >> >> I still think comp--emit-assume does the wrong thing when negating an >> assumption, but we've been there before... > > Let's hear from Andrea (CC'ed) about this. You're right. I have a new theory, but as it boils down to something that has been discussed before (whether "assume" pseudo-insns apply to individual mvars or to all mvars sharing a slot - my understanding is it has to be the latter, so we end up making invalid assumptions about the new mvar in the slot based on things we know about the old, clobbered mvar), it's best to let Andrea handle this one. I'll just disable nativecomp assume pseudo-insns for my builds as I don't want to run into this bug. Pip ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) 2024-12-10 16:55 bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) Eric Marsden 2024-12-10 21:21 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-10 22:12 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-11 22:29 ` Andrea Corallo 2 siblings, 0 replies; 6+ messages in thread From: Andrea Corallo @ 2024-12-11 22:29 UTC (permalink / raw) To: Eric Marsden; +Cc: 74771 Eric Marsden <eric.marsden@risk-engineering.org> writes: > Hi, > > With the attached source file, Emacs miscompiles the struct predicate such > that a repeated call to the predicate on a non-struct object returns t. > This occurs with current HEAD on Linux/AMD64, but not on the Emacs 30.0.92 > pretest. It does not occur when the lexical binding cookie is not present. > > % /opt/emacs/bin/emacs -Q --batch --eval "(load (native-compile \"/tmp/bug.el\"))" -f run > Loading /home/emarsden/.emacs.d/eln-cache/31.0.50-c021c983/bug-59c4b27c-c70072f9.eln (native compiled elisp)... > Running in GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.43, cairo version 1.18.2) > of 2024-12-09 > is? nil > is? t ;; expecting nil > bar: 111 > > ;;; -*- lexical-binding: t -*- > ;; > ;; /opt/emacs/bin/emacs -Q --batch -L . --eval "(load (native-compile \"/tmp/bug.el\"))" -f run > > (require 'cl-lib) > > (cl-defstruct foobles bar baz) > > (defun bug (foo) > (message "is? %s" (foobles-p foo)) > (message "is? %s" (foobles-p foo)) > (message "bar: %s" (foobles-bar foo))) > > (defun run () > (message "Running in %s" (version)) > (let ((foo "foo")) > (bug foo))) Hi Eric, thanks for the report, I'll look at this in the coming days. Andrea ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-12-11 22:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-12-10 16:55 bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD) Eric Marsden 2024-12-10 21:21 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-10 22:12 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-11 12:32 ` Eli Zaretskii 2024-12-11 14:01 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-12-11 22:29 ` Andrea Corallo
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).