GNU bug report logs - #46847
28.0.50; [native-comp] assume pseudo-insns should be verified

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> gmail.com>

Date: Mon, 1 Mar 2021 13:08:01 UTC

Severity: normal

Found in version 28.0.50

Done: Andrea Corallo <acorallo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 46847 in the body.
You can then email your comments to 46847 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Mon, 01 Mar 2021 13:08:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Pip Cet <pipcet <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 01 Mar 2021 13:08:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 28.0.50; [native-comp] assume pseudo-insns should be verified
Date: Mon, 1 Mar 2021 13:06:31 +0000
This is a wishlist item for the native-comp branch, though I consider
the feature in question to be so essential that its absence also
qualifies as a bug.

The native-comp branch is emitting assume pseudo-insns. Those come in
various forms, but their interpretation is clear: they express
conditions which are meant to hold at runtime, and which the compiler
may use to optimize code.

I would like to add an optional compiler pass which asserts that the
conditions are actually true at runtime. This is a basic safeguard
that any assume() mechanism should have, and it's perfectly equivalent
to the way eassume() becomes eassert() in debug builds of Emacs.

Unfortunately, it turns out that while adding the compiler pass is
easy, there are many failures because the assume pseudo-insns emitted
at present are inconsistent or plain wrong. Some of these wrong
assumes result in reproducible Lisp-to-native-code bugs today; others
will not; for still others, we're not sure.

For example, the four following bugs became a problem only because of
a lack of this safeguard: bug#46843 (both bugs), bug#46812, bug#46670.

Merging native-comp without such a safeguard would, I am convinced,
introduce preventable, tricky, unnecessary bugs into the Emacs master
branch.  We shouldn't do that.

Pip




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Mon, 01 Mar 2021 20:13:02 GMT) Full text and rfc822 format available.

Message #8 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <akrl <at> sdf.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Mon, 01 Mar 2021 20:12:15 +0000
Pip Cet <pipcet <at> gmail.com> writes:

> This is a wishlist item for the native-comp branch, though I consider
> the feature in question to be so essential that its absence also
> qualifies as a bug.
>
> The native-comp branch is emitting assume pseudo-insns. Those come in
> various forms, but their interpretation is clear: they express
> conditions which are meant to hold at runtime, and which the compiler
> may use to optimize code.
>
> I would like to add an optional compiler pass which asserts that the
> conditions are actually true at runtime. This is a basic safeguard
> that any assume() mechanism should have, and it's perfectly equivalent
> to the way eassume() becomes eassert() in debug builds of Emacs.
>
> Unfortunately, it turns out that while adding the compiler pass is
> easy, there are many failures because the assume pseudo-insns emitted
> at present are inconsistent or plain wrong. Some of these wrong
> assumes result in reproducible Lisp-to-native-code bugs today; others
> will not; for still others, we're not sure.

I think the issue might be that how assumes works has been
miss-understood here.

Assumes are working after SSA rename in the world of mvar ids, in
contrast we render code based on slot numbers.  Rendering assertions
based on assumes using the slot numbers (IIUC that's what your patch
did) certainly leads to inconsistencies, but that's a fundamental
miss-interpretation of how assumes are working.  This is probably also
why you often suggests assumes are inconsistent.

Anyway, for the reasons above rendering 1:1 assumes into run-time checks
is not easily possible.

OTOH a possible way, and that's what I want to do, would be to verify
just before each (non pseudo) insn actually rendered that the slots in
use there are consistent with the prediction.

One could even control that with a parameter and have a mode where we
just inject asserts on return insns not to bloat excessively the code.

Note: I'm not aware of any compiler emitting run-time checks to verify
its compile time predictions by why not.

I'll take this task as sounds like good verification/development cost
trade-off to me.  Will follow-up on this!

Thanks

  Andrea




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Tue, 02 Mar 2021 06:59:02 GMT) Full text and rfc822 format available.

Message #11 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: Andrea Corallo <akrl <at> sdf.org>
Cc: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50;
 [native-comp] assume pseudo-insns should be verified
Date: Tue, 2 Mar 2021 06:57:42 +0000
On Mon, Mar 1, 2021 at 8:12 PM Andrea Corallo <akrl <at> sdf.org> wrote:
> Pip Cet <pipcet <at> gmail.com> writes:
> > This is a wishlist item for the native-comp branch, though I consider
> > the feature in question to be so essential that its absence also
> > qualifies as a bug.
> >
> > The native-comp branch is emitting assume pseudo-insns. Those come in
> > various forms, but their interpretation is clear: they express
> > conditions which are meant to hold at runtime, and which the compiler
> > may use to optimize code.
> >
> > I would like to add an optional compiler pass which asserts that the
> > conditions are actually true at runtime. This is a basic safeguard
> > that any assume() mechanism should have, and it's perfectly equivalent
> > to the way eassume() becomes eassert() in debug builds of Emacs.
> >
> > Unfortunately, it turns out that while adding the compiler pass is
> > easy, there are many failures because the assume pseudo-insns emitted
> > at present are inconsistent or plain wrong. Some of these wrong
> > assumes result in reproducible Lisp-to-native-code bugs today; others
> > will not; for still others, we're not sure.
>
> I think the issue might be that how assumes works has been
> miss-understood here.

> Assumes are working after SSA rename in the world of mvar ids, in
> contrast we render code based on slot numbers.

If mvars introduced in assumes don't have valid slot numbers, they
shouldn't have a valid slot number in the :slot slot.

But in the case of the assumes emitted so far, they do have valid slot
numbers, they're just not the ones that are used.

>  Rendering assertions
> based on assumes using the slot numbers (IIUC that's what your patch
> did)

I merely converted the assumes into assertions. I did not use the slot
numbers there.

> certainly leads to inconsistencies, but that's a fundamental
> miss-interpretation of how assumes are working.

If there is a consistent slot number to assign to an assume-d
variable, we should use it. If there isn't, we shouldn't use a slot
number at all. What we do right now is to simply use a slot number
that we know to be incorrect, even though a correct one is available.

Again, what we emit is

(assume (mvar X :slot 1) (not (mvar Y :slot 1)))
(assume (mvar Z :slot 2) (and ... (mvar X :slot 1)))

what we should emit is

(assume (mvar X :slot 2) (not (mvar Y :slot 1)))
(assume (mvar Z :slot 2) (and ... (mvar X :slot 2)))

or even

(assume (mvar X :slot -1) (not (mvar Y :slot 1)))
(assume (mvar Z :slot 2) (and ... (mvar X :slot -1)))

or whatever mechanism you're proposing to name mvars which do not
refer to variables (respectfully, but that's what a metavariable is
defined to be).

> This is probably also why you often suggests assumes are inconsistent.

No, the seven bugs we ran into so far which were caused by
inconsistent assumes are why I often suggest assumes are inconsistent.

> Anyway, for the reasons above rendering 1:1 assumes into run-time checks
> is not easily possible.

Then we should call them something else, because that's what an "assume" is.

> OTOH a possible way, and that's what I want to do, would be to verify
> just before each (non pseudo) insn actually rendered that the slots in
> use there are consistent with the prediction.

That would catch fewer bugs, and it would catch them much later, when
code which uses them has been written.

> One could even control that with a parameter and have a mode where we
> just inject asserts on return insns not to bloat excessively the code.

That seems like an entirely arbitrary place to check our assumes, to me.

> Note: I'm not aware of any compiler emitting run-time checks to verify
> its compile time predictions by why not.

I don't know why you're unaware Emacs (pre-native-comp) and GCC both
do that, but they do.

Pip




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Fri, 05 Mar 2021 11:17:02 GMT) Full text and rfc822 format available.

Message #14 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <akrl <at> sdf.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Fri, 05 Mar 2021 11:16:19 +0000
Pip Cet <pipcet <at> gmail.com> writes:

[...]

> (assume (mvar X :slot -1) (not (mvar Y :slot 1)))
> (assume (mvar Z :slot 2) (and ... (mvar X :slot -1)))

Now that we can generate temporaries this might be an option.  But I
think would be helpful if you could show what exactly are the 1:1
assertions you'd like to synthesize for the above assumes, otherwise
this discussion will stay just too high level.

[...]

>> Note: I'm not aware of any compiler emitting run-time checks to verify
>> its compile time predictions by why not.
>
> I don't know why you're unaware Emacs (pre-native-comp) and GCC both
> do that, but they do.

I wasn't even aware that the byte compiler is doing any value prediction
and that is emitting code for to verify these, could give pointers to
boths cases?

  Andrea




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Fri, 05 Mar 2021 16:11:03 GMT) Full text and rfc822 format available.

Message #17 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> gmail.com>
To: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50;
 [native-comp] assume pseudo-insns should be verified
Date: Fri, 5 Mar 2021 16:09:20 +0000
On Mon, Mar 1, 2021 at 1:08 PM Pip Cet <pipcet <at> gmail.com> wrote:
> I would like to add an optional compiler pass which asserts that the
> conditions are actually true at runtime. This is a basic safeguard
> that any assume() mechanism should have, and it's perfectly equivalent
> to the way eassume() becomes eassert() in debug builds of Emacs.

I've proceeded to change things so I can assert assumes, and here's an
incomplete list of the bugs I've found so far:

Function types:
1. append has type (function (&rest t) t), not (function (&rest list) list)
2. aref has type (function (t fixnum) t), not (function (array fixnum) t)
3. bool-vector-count-consecutive has type (function (bool-vector
boolean integer) fixnum), not (function (bool-vector bool-vector
integer) fixnum))
4. at least some of the frame-* functions accept nil parameters
5. intern-soft has type (function ((or string symbol) &optional
vector) symbol), not (function (string &optional vector) symbol)
6. length has type (function (t) integer), not (function (sequence) integer)
7. at least some of the minibuffer functions can return nil as well as a window.
8. nthcdr has type (function (integer t) t), not (function (integer list) list)
9. radians-to-degrees is a macro and probably shouldn't have a function type
10. string has type (function (&rest fixnum) string), not (function
(&rest fixnum) strng)
11. user-full-name has type (function (&optional integer) (or string
null)), not (function (&optional integer) string)

Predicate types:
1. functionp isn't equivalent to (or function symbol)

Other:
1. comp-lambda-list-gen has to allow optional arguments to be nil even
if explicitly specified.

Furthermore, I've already reported some other bugs.

So I think this is worth pursuing further.

Pip




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Fri, 05 Mar 2021 19:37:02 GMT) Full text and rfc822 format available.

Message #20 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <akrl <at> sdf.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Fri, 05 Mar 2021 19:36:57 +0000
Pip Cet <pipcet <at> gmail.com> writes:

> On Mon, Mar 1, 2021 at 1:08 PM Pip Cet <pipcet <at> gmail.com> wrote:
>> I would like to add an optional compiler pass which asserts that the
>> conditions are actually true at runtime. This is a basic safeguard
>> that any assume() mechanism should have, and it's perfectly equivalent
>> to the way eassume() becomes eassert() in debug builds of Emacs.
>
> I've proceeded to change things so I can assert assumes, and here's an
> incomplete list of the bugs I've found so far:
>
> Function types:
> 1. append has type (function (&rest t) t), not (function (&rest list) list)
> 2. aref has type (function (t fixnum) t), not (function (array fixnum) t)
> 3. bool-vector-count-consecutive has type (function (bool-vector
> boolean integer) fixnum), not (function (bool-vector bool-vector
> integer) fixnum))
> 4. at least some of the frame-* functions accept nil parameters
> 5. intern-soft has type (function ((or string symbol) &optional
> vector) symbol), not (function (string &optional vector) symbol)
> 6. length has type (function (t) integer), not (function (sequence) integer)
> 7. at least some of the minibuffer functions can return nil as well as a window.
> 8. nthcdr has type (function (integer t) t), not (function (integer list) list)
> 9. radians-to-degrees is a macro and probably shouldn't have a function type
> 10. string has type (function (&rest fixnum) string), not (function
> (&rest fixnum) strng)
> 11. user-full-name has type (function (&optional integer) (or string
> null)), not (function (&optional integer) string)

> Predicate types:
> 1. functionp isn't equivalent to (or function symbol)

Thanks, patches are welcome.

  Andrea




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Sun, 14 Mar 2021 21:08:01 GMT) Full text and rfc822 format available.

Message #23 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <akrl <at> sdf.org>
To: Pip Cet <pipcet <at> gmail.com>
Cc: 46847 <at> debbugs.gnu.org
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Sun, 14 Mar 2021 21:07:47 +0000
Pip Cet <pipcet <at> gmail.com> writes:

[...]

> Function types:
> 1. append has type (function (&rest t) t), not (function (&rest list) list)
> 2. aref has type (function (t fixnum) t), not (function (array fixnum) t)
> 3. bool-vector-count-consecutive has type (function (bool-vector
> boolean integer) fixnum), not (function (bool-vector bool-vector
> integer) fixnum))
> 4. at least some of the frame-* functions accept nil parameters
> 5. intern-soft has type (function ((or string symbol) &optional
> vector) symbol), not (function (string &optional vector) symbol)
> 6. length has type (function (t) integer), not (function (sequence) integer)
> 7. at least some of the minibuffer functions can return nil as well as a window.
> 8. nthcdr has type (function (integer t) t), not (function (integer
> list) list)
> 9. radians-to-degrees is a macro and probably shouldn't have a function type
> 10. string has type (function (&rest fixnum) string), not (function
> (&rest fixnum) strng)
> 11. user-full-name has type (function (&optional integer) (or string
> null)), not (function (&optional integer) string)

I've fixed most of these, please given you have already investigated
this issue be more precise on points 4 and 7.

> Predicate types:
> 1. functionp isn't equivalent to (or function symbol)

Would you suggest what's the right type specifier or the counter example
that violated this so we can fix it?

> Other:
> 1. comp-lambda-list-gen has to allow optional arguments to be nil even
> if explicitly specified.

Not sure I understand, please be more precise in describing the issue so
we can fix it.

Thanks

  Andrea




Reply sent to Andrea Corallo <acorallo <at> gnu.org>:
You have taken responsibility. (Wed, 20 Mar 2024 09:34:02 GMT) Full text and rfc822 format available.

Notification sent to Pip Cet <pipcet <at> gmail.com>:
bug acknowledged by developer. (Wed, 20 Mar 2024 09:34:02 GMT) Full text and rfc822 format available.

Message #28 received at 46847-done <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <acorallo <at> gnu.org>
To: Andrea Corallo <akrl <at> sdf.org>
Cc: 46847-done <at> debbugs.gnu.org, Pip Cet <pipcet <at> gmail.com>
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Wed, 20 Mar 2024 05:30:04 -0400
I'm closing this old bug as with 0b0c7da8c80 I've installed a sanitizer
that instruments the code in order to check that compile time value
predictions of mvars are respected at runtime.  Mvars verified are all
mvars being tested by conditional branches, this to verify the correct
CFG/execution of the program.

Enabling sanitizer instrumentation and runtime verification I'm able to
bootstrap the compiler and run all the compiler testsuite.

We might extend this further in the future but I think for now is okay.

Thanks

  Andrea




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Wed, 20 Mar 2024 13:12:01 GMT) Full text and rfc822 format available.

Message #31 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Andrea Corallo <acorallo <at> gnu.org>
Cc: 46847 <at> debbugs.gnu.org, pipcet <at> gmail.com
Subject: Re: bug#46847: 28.0.50;
 [native-comp] assume pseudo-insns should be verified
Date: Wed, 20 Mar 2024 15:05:40 +0200
> Resent-To: bug-gnu-emacs <at> gnu.org
> Cc: 46847-done <at> debbugs.gnu.org, Pip Cet <pipcet <at> gmail.com>
> From: Andrea Corallo <acorallo <at> gnu.org>
> Date: Wed, 20 Mar 2024 05:30:04 -0400
> 
> I'm closing this old bug as with 0b0c7da8c80 I've installed a sanitizer
> that instruments the code in order to check that compile time value
> predictions of mvars are respected at runtime.  Mvars verified are all
> mvars being tested by conditional branches, this to verify the correct
> CFG/execution of the program.
> 
> Enabling sanitizer instrumentation and runtime verification I'm able to
> bootstrap the compiler and run all the compiler testsuite.
> 
> We might extend this further in the future but I think for now is okay.

Thanks, but would it be possible to document the suggested use of this
sanitizer in the comments somewhere?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Wed, 20 Mar 2024 14:00:02 GMT) Full text and rfc822 format available.

Message #34 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Andrea Corallo <acorallo <at> gnu.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 46847 <at> debbugs.gnu.org, pipcet <at> gmail.com
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Wed, 20 Mar 2024 09:58:53 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> Resent-To: bug-gnu-emacs <at> gnu.org
>> Cc: 46847-done <at> debbugs.gnu.org, Pip Cet <pipcet <at> gmail.com>
>> From: Andrea Corallo <acorallo <at> gnu.org>
>> Date: Wed, 20 Mar 2024 05:30:04 -0400
>> 
>> I'm closing this old bug as with 0b0c7da8c80 I've installed a sanitizer
>> that instruments the code in order to check that compile time value
>> predictions of mvars are respected at runtime.  Mvars verified are all
>> mvars being tested by conditional branches, this to verify the correct
>> CFG/execution of the program.
>> 
>> Enabling sanitizer instrumentation and runtime verification I'm able to
>> bootstrap the compiler and run all the compiler testsuite.
>> 
>> We might extend this further in the future but I think for now is okay.
>
> Thanks, but would it be possible to document the suggested use of this
> sanitizer in the comments somewhere?

Hi Eli,

that's a good point.

There are many usage scenarios, I just added a simple example at the
beginning of the 'Sanitizer pass specific code' section.

Thanks

  Andrea




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#46847; Package emacs. (Wed, 20 Mar 2024 14:11:01 GMT) Full text and rfc822 format available.

Message #37 received at 46847 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Andrea Corallo <acorallo <at> gnu.org>
Cc: 46847 <at> debbugs.gnu.org, pipcet <at> gmail.com
Subject: Re: bug#46847: 28.0.50; [native-comp] assume pseudo-insns should be
 verified
Date: Wed, 20 Mar 2024 16:09:12 +0200
> From: Andrea Corallo <acorallo <at> gnu.org>
> Cc: 46847 <at> debbugs.gnu.org,  pipcet <at> gmail.com
> Date: Wed, 20 Mar 2024 09:58:53 -0400
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > Thanks, but would it be possible to document the suggested use of this
> > sanitizer in the comments somewhere?
> 
> Hi Eli,
> 
> that's a good point.
> 
> There are many usage scenarios, I just added a simple example at the
> beginning of the 'Sanitizer pass specific code' section.

Thanks!




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 18 Apr 2024 11:26:45 GMT) Full text and rfc822 format available.

This bug report was last modified 4 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.