From: Pip Cet via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Andrea Corallo <acorallo@gnu.org>
Cc: Eli Zaretskii <eliz@gnu.org>,
eric.marsden@risk-engineering.org, 74771@debbugs.gnu.org
Subject: bug#74771: Native compilation bug with struct predicates when lexical binding enabled (HEAD)
Date: Wed, 08 Jan 2025 11:51:07 +0000 [thread overview]
Message-ID: <871pxdfrrr.fsf@protonmail.com> (raw)
In-Reply-To: <yp14j2m9620.fsf@fencepost.gnu.org>
"Andrea Corallo" <acorallo@gnu.org> writes:
> Eli Zaretskii <eliz@gnu.org> writes:
>
>>> Cc: 74771@debbugs.gnu.org
>>> From: Andrea Corallo <acorallo@gnu.org>
>>> Date: Wed, 11 Dec 2024 17:29:34 -0500
>>>
>>> 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.
>>
>> Any progress here?
>
> Not so far, I'm on holiday this days so I don't have much time for
> coding, it's in my todo list tho.
No activity in a while, so I tried reproducing this: bug's still there.
Can you repeat for me what
(assume #s(comp-mvar (t) nil nil nil nil nil) (not #s(comp-mvar (foobles) nil nil nil nil nil)))
is supposed to mean?
To me, it appears to mean "the value of the first mvar is different from
the value of the second mvar, which is of type foobles". This doesn't
say anything about the type of the first mvar, assuming there is more
than one value of the foobles type; if this is the correct
interpretation, we need to stop copying the typeset in this case:
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index 3d46cc8c6ae..5d87ff75703 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -1176,14 +1176,11 @@ comp-cstr-value-negation
"Negate values in SRC setting the result in DST.
DST is returned."
(with-comp-cstr-accessors
- (if (or (valset src) (range src))
- (setf (typeset dst) ()
- (valset dst) (valset src)
- (range dst) (range src)
- (neg dst) (not (neg src)))
- (setf (typeset dst) (typeset src)
- (valset dst) ()
- (range dst) ()))
+ (and (or (valset src) (range src))
+ (setf (typeset dst) ()
+ (valset dst) (valset src)
+ (range dst) (range src)
+ (neg dst) (not (neg src))))
dst))
(defun comp-cstr-negation-make (src)
I see two other possibilities:
1. it means the lhs mvar is of type "foobles", but not identical to the
second mvar. This is what comp-cstr-negation-make currently assumes.
In this case, comp--add-cond-cstrs should not be emitting this
pseudo-insn for the case in which the lhs mvar is known not to be of
type "foobles", but nothing else is known about its value:
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 269eae315e4..d5c512fbdc3 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -2033,11 +2033,7 @@ comp--add-cond-cstrs
(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))
+ nil))
(`((set ,(and (pred comp-mvar-p) cmp-res)
(,(pred comp--call-op-p)
,(and (or (pred comp--equality-fun-p)
2. it means the lhs mvar is not of type "foobles". In this case,
comp-cstr-value-negation should make the lhs mvar have a negated cstr
with type "foobles":
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index 3d46cc8c6ae..03a00123f64 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -1183,7 +1183,8 @@ comp-cstr-value-negation
(neg dst) (not (neg src)))
(setf (typeset dst) (typeset src)
(valset dst) ()
- (range dst) ()))
+ (range dst) ()
+ (neg dst) (not (neg src))))
dst))
(defun comp-cstr-negation-make (src)
Note that if (2) is intended, that is a really strange interpretation of
what "not" means: it's negating a cstr (a set of values), not an mvar (a
specific value), so why is the argument an mvar? We could make this
change, and then try to recover whichever optimizations that disables:
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 269eae315e4..bcc0628235a 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -2035,7 +2035,7 @@ comp--add-cond-cstrs
(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--type-to-cstr (comp-cstr-cl-tag mvar-tag))
(comp--add-cond-cstrs-target-block b bb1)
t))
(`((set ,(and (pred comp-mvar-p) cmp-res)
In any case, please consider documenting the pseudo-insns.
not-eq-to-mvar and not-matching-cstr are two very different things!
Pip
prev parent reply other threads:[~2025-01-08 11:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
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
2024-12-28 10:58 ` Eli Zaretskii
2024-12-29 9:44 ` Andrea Corallo
2025-01-08 11:51 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=871pxdfrrr.fsf@protonmail.com \
--to=bug-gnu-emacs@gnu.org \
--cc=74771@debbugs.gnu.org \
--cc=acorallo@gnu.org \
--cc=eliz@gnu.org \
--cc=eric.marsden@risk-engineering.org \
--cc=pipcet@protonmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.