public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* basic asm and memory clobbers
@ 2015-11-09  0:10 David Wohlferd
  2015-11-09  9:32 ` Segher Boessenkool
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-09  0:10 UTC (permalink / raw)
  To: gcc; +Cc: rth, pinskia, Jeff Law, Sandra Loosemore

[-- Attachment #1: Type: text/plain, Size: 645 bytes --]

It seems like a doc update is what is needed to close PR24414 (Old-style 
asms don't clobber memory).  I'm working on this now (phase 1) in the 
unlikely event that someone is inspired to make a code change here instead.

Like  Richard Henderson, I rather expected basic (or "old-style") asm to 
perform a memory clobber (it doesn't).  This bug is now over a decade 
old, so presumably the question of how this is going to work is 
settled.  IAC, the docs should reflect the current behavior.

Based on this issue plus what I have learned since last updating this 
page, I'm proposing the attached patch.

dw

CCing the commenters from the bug.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 24414.patch --]
[-- Type: text/x-patch; name="24414.patch", Size: 1211 bytes --]

Index: extend.texi
===================================================================
--- extend.texi	(revision 229910)
+++ extend.texi	(working copy)
@@ -7353,7 +7353,8 @@
 @end itemize
 
 Safely accessing C data and calling functions from basic @code{asm} is more 
-complex than it may appear. To access C data, it is better to use extended 
+complex than it may appear. To access C data (including both local and
+global register variables), use extended
 @code{asm}.
 
 Do not expect a sequence of @code{asm} statements to remain perfectly 
@@ -7376,6 +7377,12 @@
 visibility of any symbols it references. This may result in GCC discarding 
 those symbols as unreferenced.
 
+Basic @code{asm} statements are not treated as though they used a "memory"
+clobber, although they do implicitly perform a clobber of the flags
+(@pxref{Clobbers}). Also, there is no implicit clobbering of registers,
+so any registers changed must be restored to their original value before
+exiting the @code{asm}.
+
 The compiler copies the assembler instructions in a basic @code{asm} 
 verbatim to the assembly language output file, without 
 processing dialects or any of the @samp{%} operators that are available with

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-09  0:10 basic asm and memory clobbers David Wohlferd
@ 2015-11-09  9:32 ` Segher Boessenkool
  2015-11-16  1:23   ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-09  9:32 UTC (permalink / raw)
  To: David Wohlferd; +Cc: gcc, rth, pinskia, Jeff Law, Sandra Loosemore

On Sun, Nov 08, 2015 at 04:10:01PM -0800, David Wohlferd wrote:
> It seems like a doc update is what is needed to close PR24414 (Old-style 
> asms don't clobber memory).

What is needed to close the bug is to make the compiler work properly.

Whether that means clobbering memory or not, I don't much care -- with
the status quo, if you want your asm to clobber memory you have to use
extended asm; if basic asm is made to clobber memory, if you want your
asm to *not* clobber memory you have to use extended asm (which you
can with no operands by writing e.g.  asm("bork" : );  ).  So both
behaviours are available whether we make a change or not.

But changing things now will likely break user code.

>  Safely accessing C data and calling functions from basic @code{asm} is more 
> -complex than it may appear. To access C data, it is better to use extended 
> +complex than it may appear. To access C data (including both local and
> +global register variables), use extended
>  @code{asm}.

I don't think this makes things clearer.  Register vars are described
elsewhere already; if you really think it needs mentioning here, put
it at the end (in its own sentence), don't break up this sentence.

(dot space space).

> +Basic @code{asm} statements are not treated as though they used a "memory"
> +clobber, although they do implicitly perform a clobber of the flags
> +(@pxref{Clobbers}).

They do not clobber the flags.  Observe:

===
void f(int a)
{
        a = a >> 2;
        if (a <= 0)
                asm("OHAI");
        if (a >= 0)
                asm("OHAI2");
}
===

Compiling this for powerpc gives (-m32, edited):

f:
        srawi. 9,3,2    # this sets cr0
        ble 0,.L5       # this uses cr0
.L2:
        OHAI2
        blr
        .p2align 4,,15
.L5:
        OHAI
        bnelr 0         # this uses cr0
        b .L2

which shows that CR0 (which is "cc") is live over the asm.  So are all
other condition regs.

It is true for cc0 targets I guess, but there aren't many of those left.

> Also, there is no implicit clobbering of registers,
> +so any registers changed must be restored to their original value before
> +exiting the @code{asm}.

One of the important uses of asm is to set registers GCC does not know
about, so you might want to phrase this differently.


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-09  9:32 ` Segher Boessenkool
@ 2015-11-16  1:23   ` David Wohlferd
  2015-11-16 21:29     ` Jeff Law
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-16  1:23 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc, rth, pinskia, Jeff Law, Sandra Loosemore

[-- Attachment #1: Type: text/plain, Size: 3451 bytes --]

On 11/9/2015 1:32 AM, Segher Boessenkool wrote:
> On Sun, Nov 08, 2015 at 04:10:01PM -0800, David Wohlferd wrote:
>> It seems like a doc update is what is needed to close PR24414 (Old-style
>> asms don't clobber memory).
> What is needed to close the bug is to make the compiler work properly.

The question of course is, what does 'properly' mean?  My assertion is 
that 10 years on, 'properly' means whatever it's doing now. Changing it 
at this point will probably break more than it fixes, and (as you said) 
there is a plausible work-around using extended asm.

So while this bug could be resolved as 'invalid' (since the compiler is 
behaving 'properly'), I'm thinking to split the difference and 'fix' it 
with a doc patch that describes the supported behavior.

> Whether that means clobbering memory or not, I don't much care -- with
> the status quo, if you want your asm to clobber memory you have to use
> extended asm; if basic asm is made to clobber memory, if you want your
> asm to *not* clobber memory you have to use extended asm (which you
> can with no operands by writing e.g.  asm("bork" : );  ).  So both
> behaviours are available whether we make a change or not.
>
> But changing things now will likely break user code.
>
>>   Safely accessing C data and calling functions from basic @code{asm} is more
>> -complex than it may appear. To access C data, it is better to use extended
>> +complex than it may appear. To access C data (including both local and
>> +global register variables), use extended
>>   @code{asm}.
> I don't think this makes things clearer.  Register vars are described
> elsewhere already;

The docs for local register variables describe this limitation.  But 
globals does not.

Whether this information belongs in local register, global register, 
basic asm, or all 3 depends on which section of the docs users will be 
reading when they need to know this information.

> if you really think it needs mentioning here, put
> it at the end (in its own sentence), don't break up this sentence.

Ok.

> (dot space space).
>
>> +Basic @code{asm} statements are not treated as though they used a "memory"
>> +clobber, although they do implicitly perform a clobber of the flags
>> +(@pxref{Clobbers}).
> They do not clobber the flags.  Observe:

Ouch.  i386 shows the same thing for basic asm.

Having to preserve the flags is ugly, but since that's the behavior, 
let's write it down.

> ===
> void f(int a)
> {
>          a = a >> 2;
>          if (a <= 0)
>                  asm("OHAI");
>          if (a >= 0)
>                  asm("OHAI2");
> }
> ===
>
> Compiling this for powerpc gives (-m32, edited):
>
> f:
>          srawi. 9,3,2    # this sets cr0
>          ble 0,.L5       # this uses cr0
> .L2:
>          OHAI2
>          blr
>          .p2align 4,,15
> .L5:
>          OHAI
>          bnelr 0         # this uses cr0
>          b .L2
>
> which shows that CR0 (which is "cc") is live over the asm.  So are all
> other condition regs.
>
> It is true for cc0 targets I guess, but there aren't many of those left.
>
>> Also, there is no implicit clobbering of registers,
>> +so any registers changed must be restored to their original value before
>> +exiting the @code{asm}.
> One of the important uses of asm is to set registers GCC does not know
> about, so you might want to phrase this differently.

Ahh, good point.

What would you say to "general purpose registers?"

Update attached.

dw

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 24414b.patch --]
[-- Type: text/x-patch; name="24414b.patch", Size: 1329 bytes --]

Index: extend.texi
===================================================================
--- extend.texi	(revision 229910)
+++ extend.texi	(working copy)
@@ -7353,8 +7353,9 @@
 @end itemize
 
 Safely accessing C data and calling functions from basic @code{asm} is more 
-complex than it may appear. To access C data, it is better to use extended 
-@code{asm}.
+complex than it may appear. To access C data use extended @code{asm}. Do
+not attempt to directly access local or global register variables from
+within basic @code{asm} (@pxref{Explicit Register Variables}).
 
 Do not expect a sequence of @code{asm} statements to remain perfectly 
 consecutive after compilation. If certain instructions need to remain 
@@ -7376,6 +7377,11 @@
 visibility of any symbols it references. This may result in GCC discarding 
 those symbols as unreferenced.
 
+Basic @code{asm} statements are not treated as though they used a "memory"
+clobber (@pxref{Clobbers}). Also, neither the flags nor the general-purpose
+registers are clobbered, so any changes must be restored to their original
+value before exiting the @code{asm}.
+
 The compiler copies the assembler instructions in a basic @code{asm} 
 verbatim to the assembly language output file, without 
 processing dialects or any of the @samp{%} operators that are available with

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-16  1:23   ` David Wohlferd
@ 2015-11-16 21:29     ` Jeff Law
  2015-11-17  5:56       ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Jeff Law @ 2015-11-16 21:29 UTC (permalink / raw)
  To: David Wohlferd, Segher Boessenkool; +Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/15/2015 06:23 PM, David Wohlferd wrote:
> On 11/9/2015 1:32 AM, Segher Boessenkool wrote:
>> On Sun, Nov 08, 2015 at 04:10:01PM -0800, David Wohlferd wrote:
>>> It seems like a doc update is what is needed to close PR24414 (Old-style
>>> asms don't clobber memory).
>> What is needed to close the bug is to make the compiler work properly.
>
> The question of course is, what does 'properly' mean?  My assertion is
> that 10 years on, 'properly' means whatever it's doing now. Changing it
> at this point will probably break more than it fixes, and (as you said)
> there is a plausible work-around using extended asm.
>
> So while this bug could be resolved as 'invalid' (since the compiler is
> behaving 'properly'), I'm thinking to split the difference and 'fix' it
> with a doc patch that describes the supported behavior.
I'd disagree.  A traditional asm has to be considered an opaque blob 
that read/write/clobber any register or memory location.

It's also the case that assuming an old style asm can read or clobber 
any memory location is the safe, conservative thing to do.  So the right 
thing in my mind is to ensure that behaviour and document it.

Andrew's logic is just plain wrong in that BZ.


>
>> Whether that means clobbering memory or not, I don't much care -- with
>> the status quo, if you want your asm to clobber memory you have to use
>> extended asm; if basic asm is made to clobber memory, if you want your
>> asm to *not* clobber memory you have to use extended asm (which you
>> can with no operands by writing e.g.  asm("bork" : );  ).  So both
>> behaviours are available whether we make a change or not.
>>
>> But changing things now will likely break user code.
Having an traditional asm clobber memory should not break user code.  It 
may pessimize it slightly, but if it does, that code was already broken.

>> (dot space space).
>>
>>> +Basic @code{asm} statements are not treated as though they used a
>>> "memory"
>>> +clobber, although they do implicitly perform a clobber of the flags
>>> +(@pxref{Clobbers}).
>> They do not clobber the flags.  Observe:
>
> Ouch.  i386 shows the same thing for basic asm.
Sadly, I suspect this isn't consistent across targets.

Jeff


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-16 21:29     ` Jeff Law
@ 2015-11-17  5:56       ` David Wohlferd
  2015-11-17  9:27         ` Andrew Haley
  2015-11-17 21:31         ` Jeff Law
  0 siblings, 2 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-17  5:56 UTC (permalink / raw)
  To: Jeff Law, Segher Boessenkool; +Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/16/2015 1:29 PM, Jeff Law wrote:
> On 11/15/2015 06:23 PM, David Wohlferd wrote:
>> On 11/9/2015 1:32 AM, Segher Boessenkool wrote:
>>> On Sun, Nov 08, 2015 at 04:10:01PM -0800, David Wohlferd wrote:
>>>> It seems like a doc update is what is needed to close PR24414 
>>>> (Old-style
>>>> asms don't clobber memory).
>>> What is needed to close the bug is to make the compiler work properly.
>>
>> The question of course is, what does 'properly' mean?  My assertion is
>> that 10 years on, 'properly' means whatever it's doing now. Changing it
>> at this point will probably break more than it fixes, and (as you said)
>> there is a plausible work-around using extended asm.
>>
>> So while this bug could be resolved as 'invalid' (since the compiler is
>> behaving 'properly'), I'm thinking to split the difference and 'fix' it
>> with a doc patch that describes the supported behavior.
> I'd disagree.  A traditional asm has to be considered an opaque blob 
> that read/write/clobber any register or memory location.

When I first encountered basic asm, my expectation was that of course it 
clobbers.  It HAS to, right?  But that said, let me give my best devil's 
advocate impersonation and ask: Why?

- There is no standard that says it must do this.
- I'm only aware of 1 person who has ever asked for this change. And the 
request has been deemed so unimportant it has languished for a very long 
time.
- There is a plausible work-around with extended asm, which (mostly) has 
clear semantics regarding clobbers.
- While the change probably won't introduce bad code, if it does it will 
be in ways that are going to be difficult to track down, in an area 
where few have the expertise to debug.
- Existing code that currently does things 'right' (ie push/pop any 
modified registers) will suddenly be doing things 'wrong,' or at least 
wastefully.
- Other than top-level asm, it seems like every existing basic asm will 
(probably) get a new performance penalty (memory usage + code size + 
cycles) to allow for situations they may already be handling correctly 
or that don't apply.

True, these aren't particularly compelling reasons to not make the 
change.  But I also don't see any compelling benefits to offset them.

For existing users, presumably they have already found whatever solution 
they need and will just be annoyed that they have to revisit their code 
to see the impact of this change.  Will they need to #if to ensure 
consistent performance/function between gcc versions?  For future users, 
they will have the docs telling them the behavior, and pointing them to 
the (now well documented) extended asm.  Where's the benefit?

If someone were proposing basic asm as a new feature, I'd absolutely be 
arguing that it should clobber everything.  Or I might argue that basic 
asm should only be allowed at top-level (where I don't believe 
clobbering matters?) and everything else should be extended asm so we 
KNOW what to clobber (hmm...).

But changing this so gcc tries (probably futilely) to emulate other 
implementations of asm...  That seems like a weak case to support a 
change to this long-time behavior.  Unless there are other benefits I'm 
just not seeing?

--------------
Ok, that's my best shot.  You have way more expertise and experience 
here than I do, so I expect that after you think it over, you'll make 
the right call.  And despite my attempt here to defend the opposite 
side, I'm not entirely sure what the right call is.  But these seem like 
the right questions.

Either way, let me know if I can help.

> It's also the case that assuming an old style asm can read or clobber 
> any memory location is the safe, conservative thing to do. 

Well, safe-r.  Even if you make this change, embedding basic asm in C 
routines still seems risky.  Well, riskier than extended which is risky 
enough.

> So the right thing in my mind is to ensure that behaviour 

The right thing in my mind is to find ways to prod people into using 
extended asm instead of basic.  Then they explicitly specify their 
requirements rather than depending on clunky all-or-nothing defaults.

Maybe to the extent of gcc deprecating (non-top level) basic over time 
(-fallow-basic-asm=[none|top|any] where v6 defaults to 'any' and v7 
defaults to 'top').  I'd be surprised if gcc went this way, but that 
doesn't mean it wouldn't be better.

> and document it.

and to document it.

> Andrew's logic is just plain wrong in that BZ.
>
>
>>
>>> Whether that means clobbering memory or not, I don't much care -- with
>>> the status quo, if you want your asm to clobber memory you have to use
>>> extended asm; if basic asm is made to clobber memory, if you want your
>>> asm to *not* clobber memory you have to use extended asm (which you
>>> can with no operands by writing e.g.  asm("bork" : );  ).  So both
>>> behaviours are available whether we make a change or not.
>>>
>>> But changing things now will likely break user code.
> Having an traditional asm clobber memory should not break user code.  
> It may pessimize it slightly, but if it does, that code was already 
> broken.

How much pessimism are we talking here?  Wouldn't clobbering everything 
effectively force the reloading of (some? most? all?) registers?  And 
more memory will be needed to store things that used to just require 
registers?  Along with a few more memory writes?  A single line of basic 
asm, even a comment, could have a non-trivial impact on the code that 
gets generated.

One common use I've seen for basic asm is "int $3" on x86 to break into 
the debugger (the basic asm docs use this as a sample). Changing this to 
a clobber-everything will make what used to be a minimally intrusive way 
to debug code into a high impact operation that may obscure the very 
thing being debugged.

I see how this change might save users (at least the ones who don't read 
the docs) some confusion.  Especially ones porting from other compilers 
that have a similar format for asm.  But it's not going to help people 
who come from compilers that allow the asm to directly access C 
variables.  Or that don't use strings and just embed the asm between 
braces.  And if I weren't already using extended asm, the performance 
questions this introduces to basic would probably be enough to push me 
there.

Or is that the intent?

>>> (dot space space).
>>>
>>>> +Basic @code{asm} statements are not treated as though they used a
>>>> "memory"
>>>> +clobber, although they do implicitly perform a clobber of the flags
>>>> +(@pxref{Clobbers}).
>>> They do not clobber the flags.  Observe:
>>
>> Ouch.  i386 shows the same thing for basic asm.
> Sadly, I suspect this isn't consistent across targets.

Bigger ouch.  I'll follow up on this after the discussion about changing 
basic asm is complete (which may render this moot).

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17  5:56       ` David Wohlferd
@ 2015-11-17  9:27         ` Andrew Haley
  2015-11-17 21:31         ` Jeff Law
  1 sibling, 0 replies; 58+ messages in thread
From: Andrew Haley @ 2015-11-17  9:27 UTC (permalink / raw)
  To: gcc

On 17/11/15 05:55, David Wohlferd wrote:
> How much pessimism are we talking here?  Wouldn't clobbering everything 
> effectively force the reloading of (some? most? all?) registers?  And 
> more memory will be needed to store things that used to just require 
> registers?

No, really not.  It only affects locals whose address has been taken
and is live at that point.

> Along with a few more memory writes?  A single line of basic asm,
> even a comment, could have a non-trivial impact on the code that
> gets generated.
> 
> One common use I've seen for basic asm is "int $3" on x86 to break into 
> the debugger (the basic asm docs use this as a sample). Changing this to 
> a clobber-everything will make what used to be a minimally intrusive way 
> to debug code into a high impact operation that may obscure the very 
> thing being debugged.

I think that's really pretty unlikely.  Besides, if you need a
breakpoint for debugging you really don't want operations to move
across that breakpoint.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17  5:56       ` David Wohlferd
  2015-11-17  9:27         ` Andrew Haley
@ 2015-11-17 21:31         ` Jeff Law
  2015-11-17 22:07           ` Andrew Pinski
                             ` (2 more replies)
  1 sibling, 3 replies; 58+ messages in thread
From: Jeff Law @ 2015-11-17 21:31 UTC (permalink / raw)
  To: David Wohlferd, Segher Boessenkool; +Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/16/2015 10:55 PM, David Wohlferd wrote:
>
> - There is no standard that says it must do this.
True.  But these after all are extensions and extensions have been 
notoriously under-documented through the years.

> - I'm only aware of 1 person who has ever asked for this change. And the
> request has been deemed so unimportant it has languished for a very long
> time.
True.  But I'd say for this case it means it just hasn't been high 
enough on anyone's priority list to get resolved.   I wouldn't be at all 
surprised if Richard filed this bug to ensure that it didn't get lost. 
That's standard development procedure for items we notice, but aren't 
actively working on.

It's unfortunate that Andrew muddied the waters.  Andrew's conclusions, 
particularly in c#6 are simply wrong.


> - There is a plausible work-around with extended asm, which (mostly) has
> clear semantics regarding clobbers.
Converting an old-style asm to extended asm can be painful.  ANd in the 
case of legacy code the conversion process itself is a potential source 
of bugs.




> - While the change probably won't introduce bad code, if it does it will
> be in ways that are going to be difficult to track down, in an area
> where few have the expertise to debug.
> - Existing code that currently does things 'right' (ie push/pop any
> modified registers) will suddenly be doing things 'wrong,' or at least
> wastefully.
> - Other than top-level asm, it seems like every existing basic asm will
> (probably) get a new performance penalty (memory usage + code size +
> cycles) to allow for situations they may already be handling correctly
> or that don't apply.
> True, these aren't particularly compelling reasons to not make the
> change.  But I also don't see any compelling benefits to offset them.
The benefit is traditional asms do the expected thing.  With no way to 
describe dataflow, the only rational behaviour for a traditional asm is 
that it has to be considered a use/clobber of memory and hard registers.

The fact that it wasn't documented that way eons ago is simply a 
documentation bug -- likely due to the fact that back when the 
documentation for traditional asms was written, there were virtually no 
optimizations of memory referencing instructions -- essentially folks 
didn't ponder (much less document) how these asms would interact with 
memory.

In fact, if you go back to the change I made back in 1999 referenced by 
this BZ, you'll find that we had a mis-compilation of code around an ASM 
by a pass to remove redundant stores that had just been significantly 
improved.



>
> For existing users, presumably they have already found whatever solution
> they need and will just be annoyed that they have to revisit their code
> to see the impact of this change.  Will they need to #if to ensure
> consistent performance/function between gcc versions?  For future users,
> they will have the docs telling them the behavior, and pointing them to
> the (now well documented) extended asm.  Where's the benefit?
Existing users have to change nothing when we fix 24414.  The whole 
point behind 24414 is to point out a case where we are not honoring the 
uses/clobbers all hard regs and memory semantics of traditional asms.


>
> But changing this so gcc tries (probably futilely) to emulate other
> implementations of asm...  That seems like a weak case to support a
> change to this long-time behavior.  Unless there are other benefits I'm
> just not seeing?
When we fix 24414 by honoring the "uses/clobbers all hard registers and 
memory" semantics for old-style asms, those old-style asms will be 
*less* likely to cause problems in the presence of ever-improving 
optimization techniques.


>
> --------------
> Ok, that's my best shot.  You have way more expertise and experience
> here than I do, so I expect that after you think it over, you'll make
> the right call.  And despite my attempt here to defend the opposite
> side, I'm not entirely sure what the right call is.  But these seem like
> the right questions.
>
> Either way, let me know if I can help.
About the only immediate task would be to ensure that the documentation 
for traditional asms clearly documents the desired semantics and somehow 
note that there are known bugs in the implementation (ie 24414, handling 
of flags registers, and probably other oddities)

>>>> Whether that means clobbering memory or not, I don't much care -- with
>>>> the status quo, if you want your asm to clobber memory you have to use
>>>> extended asm; if basic asm is made to clobber memory, if you want your
>>>> asm to *not* clobber memory you have to use extended asm (which you
>>>> can with no operands by writing e.g.  asm("bork" : );  ).  So both
>>>> behaviours are available whether we make a change or not.
>>>>
>>>> But changing things now will likely break user code.
>> Having an traditional asm clobber memory should not break user code.
>> It may pessimize it slightly, but if it does, that code was already
>> broken.
>
> How much pessimism are we talking here?  Wouldn't clobbering everything
> effectively force the reloading of (some? most? all?) registers?  And
> more memory will be needed to store things that used to just require
> registers?  Along with a few more memory writes?  A single line of basic
> asm, even a comment, could have a non-trivial impact on the code that
> gets generated.
Essentially it means that old style asms become a point where the 
compiler has  to assume that memory and hard registers are 
read/clobbered.   Without going into all the details the asm essentially 
invalidates information the compiler might be tracking about the value 
in memory locations or hard registers.

So given two stores to the same memory location on opposite sides of the 
traditional asm, the compiler is _not_ allowed to remove the first store 
(because the traditional asm might read the value).  Nor is the compiler 
allowed to remove the second store (because the asm might have stored a 
value into that location).

Similar situations occur when reading memory locations.

>
> One common use I've seen for basic asm is "int $3" on x86 to break into
> the debugger (the basic asm docs use this as a sample). Changing this to
> a clobber-everything will make what used to be a minimally intrusive way
> to debug code into a high impact operation that may obscure the very
> thing being debugged.
Actually in that specific case, ensuring everything is consistent is 
actually a *good* thing.  And I suspect it's still a lot less intrusive 
than you might think.

>>>> +Basic @code{asm} statements are not treated as though they used a
>>>>> "memory"
>>>>> +clobber, although they do implicitly perform a clobber of the flags
>>>>> +(@pxref{Clobbers}).
>>>> They do not clobber the flags.  Observe:
>>>
>>> Ouch.  i386 shows the same thing for basic asm.
>> Sadly, I suspect this isn't consistent across targets.
>
> Bigger ouch.  I'll follow up on this after the discussion about changing
> basic asm is complete (which may render this moot).
It likely depends on how the target models the flags.

jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17 21:31         ` Jeff Law
@ 2015-11-17 22:07           ` Andrew Pinski
  2015-11-18 22:04             ` Jeff Law
  2015-11-18  1:28           ` Segher Boessenkool
  2015-11-20  1:24           ` David Wohlferd
  2 siblings, 1 reply; 58+ messages in thread
From: Andrew Pinski @ 2015-11-17 22:07 UTC (permalink / raw)
  To: Jeff Law; +Cc: David Wohlferd, Segher Boessenkool, gcc, rth, Sandra Loosemore

On Wed, Nov 18, 2015 at 5:31 AM, Jeff Law <law@redhat.com> wrote:
> On 11/16/2015 10:55 PM, David Wohlferd wrote:
>>
>>
>> - There is no standard that says it must do this.
>
> True.  But these after all are extensions and extensions have been
> notoriously under-documented through the years.
>
>> - I'm only aware of 1 person who has ever asked for this change. And the
>> request has been deemed so unimportant it has languished for a very long
>> time.
>
> True.  But I'd say for this case it means it just hasn't been high enough on
> anyone's priority list to get resolved.   I wouldn't be at all surprised if
> Richard filed this bug to ensure that it didn't get lost. That's standard
> development procedure for items we notice, but aren't actively working on.
>
> It's unfortunate that Andrew muddied the waters.  Andrew's conclusions,
> particularly in c#6 are simply wrong.


Sorry about that.  I have since changed my views on this matter to say
old-style asm should clobber memory.  I should have written this
sooner but I have been busy with other things.

Thanks,
Andrew

>
>
>> - There is a plausible work-around with extended asm, which (mostly) has
>> clear semantics regarding clobbers.
>
> Converting an old-style asm to extended asm can be painful.  ANd in the case
> of legacy code the conversion process itself is a potential source of bugs.
>
>
>
>
>> - While the change probably won't introduce bad code, if it does it will
>> be in ways that are going to be difficult to track down, in an area
>> where few have the expertise to debug.
>> - Existing code that currently does things 'right' (ie push/pop any
>> modified registers) will suddenly be doing things 'wrong,' or at least
>> wastefully.
>> - Other than top-level asm, it seems like every existing basic asm will
>> (probably) get a new performance penalty (memory usage + code size +
>> cycles) to allow for situations they may already be handling correctly
>> or that don't apply.
>> True, these aren't particularly compelling reasons to not make the
>> change.  But I also don't see any compelling benefits to offset them.
>
> The benefit is traditional asms do the expected thing.  With no way to
> describe dataflow, the only rational behaviour for a traditional asm is that
> it has to be considered a use/clobber of memory and hard registers.
>
> The fact that it wasn't documented that way eons ago is simply a
> documentation bug -- likely due to the fact that back when the documentation
> for traditional asms was written, there were virtually no optimizations of
> memory referencing instructions -- essentially folks didn't ponder (much
> less document) how these asms would interact with memory.
>
> In fact, if you go back to the change I made back in 1999 referenced by this
> BZ, you'll find that we had a mis-compilation of code around an ASM by a
> pass to remove redundant stores that had just been significantly improved.
>
>
>
>>
>> For existing users, presumably they have already found whatever solution
>> they need and will just be annoyed that they have to revisit their code
>> to see the impact of this change.  Will they need to #if to ensure
>> consistent performance/function between gcc versions?  For future users,
>> they will have the docs telling them the behavior, and pointing them to
>> the (now well documented) extended asm.  Where's the benefit?
>
> Existing users have to change nothing when we fix 24414.  The whole point
> behind 24414 is to point out a case where we are not honoring the
> uses/clobbers all hard regs and memory semantics of traditional asms.
>
>
>>
>> But changing this so gcc tries (probably futilely) to emulate other
>> implementations of asm...  That seems like a weak case to support a
>> change to this long-time behavior.  Unless there are other benefits I'm
>> just not seeing?
>
> When we fix 24414 by honoring the "uses/clobbers all hard registers and
> memory" semantics for old-style asms, those old-style asms will be *less*
> likely to cause problems in the presence of ever-improving optimization
> techniques.
>
>
>>
>> --------------
>> Ok, that's my best shot.  You have way more expertise and experience
>> here than I do, so I expect that after you think it over, you'll make
>> the right call.  And despite my attempt here to defend the opposite
>> side, I'm not entirely sure what the right call is.  But these seem like
>> the right questions.
>>
>> Either way, let me know if I can help.
>
> About the only immediate task would be to ensure that the documentation for
> traditional asms clearly documents the desired semantics and somehow note
> that there are known bugs in the implementation (ie 24414, handling of flags
> registers, and probably other oddities)
>
>>>>> Whether that means clobbering memory or not, I don't much care -- with
>>>>> the status quo, if you want your asm to clobber memory you have to use
>>>>> extended asm; if basic asm is made to clobber memory, if you want your
>>>>> asm to *not* clobber memory you have to use extended asm (which you
>>>>> can with no operands by writing e.g.  asm("bork" : );  ).  So both
>>>>> behaviours are available whether we make a change or not.
>>>>>
>>>>> But changing things now will likely break user code.
>>>
>>> Having an traditional asm clobber memory should not break user code.
>>> It may pessimize it slightly, but if it does, that code was already
>>> broken.
>>
>>
>> How much pessimism are we talking here?  Wouldn't clobbering everything
>> effectively force the reloading of (some? most? all?) registers?  And
>> more memory will be needed to store things that used to just require
>> registers?  Along with a few more memory writes?  A single line of basic
>> asm, even a comment, could have a non-trivial impact on the code that
>> gets generated.
>
> Essentially it means that old style asms become a point where the compiler
> has  to assume that memory and hard registers are read/clobbered.   Without
> going into all the details the asm essentially invalidates information the
> compiler might be tracking about the value in memory locations or hard
> registers.
>
> So given two stores to the same memory location on opposite sides of the
> traditional asm, the compiler is _not_ allowed to remove the first store
> (because the traditional asm might read the value).  Nor is the compiler
> allowed to remove the second store (because the asm might have stored a
> value into that location).
>
> Similar situations occur when reading memory locations.
>
>>
>> One common use I've seen for basic asm is "int $3" on x86 to break into
>> the debugger (the basic asm docs use this as a sample). Changing this to
>> a clobber-everything will make what used to be a minimally intrusive way
>> to debug code into a high impact operation that may obscure the very
>> thing being debugged.
>
> Actually in that specific case, ensuring everything is consistent is
> actually a *good* thing.  And I suspect it's still a lot less intrusive than
> you might think.
>
>>>>> +Basic @code{asm} statements are not treated as though they used a
>>>>>>
>>>>>> "memory"
>>>>>> +clobber, although they do implicitly perform a clobber of the flags
>>>>>> +(@pxref{Clobbers}).
>>>>>
>>>>> They do not clobber the flags.  Observe:
>>>>
>>>>
>>>> Ouch.  i386 shows the same thing for basic asm.
>>>
>>> Sadly, I suspect this isn't consistent across targets.
>>
>>
>> Bigger ouch.  I'll follow up on this after the discussion about changing
>> basic asm is complete (which may render this moot).
>
> It likely depends on how the target models the flags.
>
> jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17 21:31         ` Jeff Law
  2015-11-17 22:07           ` Andrew Pinski
@ 2015-11-18  1:28           ` Segher Boessenkool
  2015-11-18 22:08             ` Jeff Law
  2015-11-20  1:24           ` David Wohlferd
  2 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-18  1:28 UTC (permalink / raw)
  To: Jeff Law; +Cc: David Wohlferd, gcc, rth, pinskia, Sandra Loosemore

On Tue, Nov 17, 2015 at 02:31:29PM -0700, Jeff Law wrote:
> >- There is a plausible work-around with extended asm, which (mostly) has
> >clear semantics regarding clobbers.
> Converting an old-style asm to extended asm can be painful.  ANd in the 
> case of legacy code the conversion process itself is a potential source 
> of bugs.

> >- While the change probably won't introduce bad code, if it does it will
> >be in ways that are going to be difficult to track down, in an area
> >where few have the expertise to debug.
> >- Existing code that currently does things 'right' (ie push/pop any
> >modified registers) will suddenly be doing things 'wrong,' or at least
> >wastefully.

Basic asm does not do this, and hasn't for a very long time.  So there
simply cannot be existing users that rely on this behaviour.  fwprop1
removes the save/restore already, in most cases.

> The fact that it wasn't documented that way eons ago is simply a 
> documentation bug -- likely due to the fact that back when the 
> documentation for traditional asms was written, there were virtually no 
> optimizations of memory referencing instructions -- essentially folks 
> didn't ponder (much less document) how these asms would interact with 
> memory.

_Does_ basic asm as currently implemented have a memory clobber?  If not,
it seems we can just remove basic asm completely and everything would
still work the same!


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17 22:07           ` Andrew Pinski
@ 2015-11-18 22:04             ` Jeff Law
  0 siblings, 0 replies; 58+ messages in thread
From: Jeff Law @ 2015-11-18 22:04 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: David Wohlferd, Segher Boessenkool, gcc, rth, Sandra Loosemore

On 11/17/2015 03:07 PM, Andrew Pinski wrote:
> On Wed, Nov 18, 2015 at 5:31 AM, Jeff Law <law@redhat.com> wrote:
>> On 11/16/2015 10:55 PM, David Wohlferd wrote:
>>>
>>>
>>> - There is no standard that says it must do this.
>>
>> True.  But these after all are extensions and extensions have been
>> notoriously under-documented through the years.
>>
>>> - I'm only aware of 1 person who has ever asked for this change. And the
>>> request has been deemed so unimportant it has languished for a very long
>>> time.
>>
>> True.  But I'd say for this case it means it just hasn't been high enough on
>> anyone's priority list to get resolved.   I wouldn't be at all surprised if
>> Richard filed this bug to ensure that it didn't get lost. That's standard
>> development procedure for items we notice, but aren't actively working on.
>>
>> It's unfortunate that Andrew muddied the waters.  Andrew's conclusions,
>> particularly in c#6 are simply wrong.
>
>
> Sorry about that.  I have since changed my views on this matter to say
> old-style asm should clobber memory.  I should have written this
> sooner but I have been busy with other things.
I certainly understand being busy with other things.  Thanks for chiming 
in and clarifying your current thoughts.

Jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-18  1:28           ` Segher Boessenkool
@ 2015-11-18 22:08             ` Jeff Law
  0 siblings, 0 replies; 58+ messages in thread
From: Jeff Law @ 2015-11-18 22:08 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: David Wohlferd, gcc, rth, pinskia, Sandra Loosemore

On 11/17/2015 06:28 PM, Segher Boessenkool wrote:
>
> _Does_ basic asm as currently implemented have a memory clobber?  If not,
> it seems we can just remove basic asm completely and everything would
> still work the same!
You'd have to dig into the various optimizers -- I know that it has a 
memory use in DSE, but I haven't audited the optimizers thoroughly.  In 
fact, the whole point behind the PR in question is there's at least one 
optimizer that is missing that check.

Jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-17 21:31         ` Jeff Law
  2015-11-17 22:07           ` Andrew Pinski
  2015-11-18  1:28           ` Segher Boessenkool
@ 2015-11-20  1:24           ` David Wohlferd
  2015-11-20  1:53             ` Sandra Loosemore
                               ` (2 more replies)
  2 siblings, 3 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-20  1:24 UTC (permalink / raw)
  To: Jeff Law, Segher Boessenkool; +Cc: gcc, rth, pinskia, Sandra Loosemore


>> Unless there are other benefits I'm just not seeing?
> When we fix 24414 by honoring the "uses/clobbers all hard registers 
> and memory" semantics for old-style asms, those old-style asms will be 
> *less* likely to cause problems in the presence of ever-improving 
> optimization techniques.

Ok, this is a good point.  In fact, it may resolve existing problems 
that people don't know they have.

However I still have concerns that people might be surprised by the 
change in behavior.  Looking thru the linux kernel source (a significant 
collection of inline asm containing both basic (~878) and extended 
(4833) statements), it seems there are places where they really are 
going to want the "clobber nothing" semantics.

For that reason, I'd like to propose adding 2 new clobbers to extended 
asm as part of this work:

"clobberall" - This gives extended the same semantics as whatever the 
new basic asm will be using.
"clobbernone" - This gives the same semantics as the current basic asm.

Clobbernone may seem redundant, since not specifying any clobbers should 
do the same thing.  But actually it doesn't, at least on i386.  At 
present, there is no way for extended asm to not clobber "cc".  I don't 
know if other platforms have similar issues.

When basic asm changes, I expect that having a way to "just do what it 
used to do" is going to be useful for some people.

>> Either way, let me know if I can help.
> About the only immediate task would be to ensure that the 
> documentation for traditional asms clearly documents the desired 
> semantics and somehow note that there are known bugs in the 
> implementation (ie 24414, handling of flags registers, and probably 
> other oddities)

Given that gcc is at phase 3, I'm guessing this work won't be in v6?  Or 
would this be considered "general bugfixing?"

The reason I ask is I want to clearly document what the current behavior 
is as well as informing them about what's coming.  If this isn't 
changing until v7, the text can be updated then to reflect the new behavior.

> And I suspect it's still a lot less intrusive than you might think.

I tried to picture the most basic case I can think of that uses 
something clobber-able:

    for (int x=0; x < 1000; x++)
       asm("#stuff");

This generates very simple and highly performant code:

         movl    $1000, %eax
.L2:
         #stuff
         subl    $1, %eax
         jne     .L2

Using extended asm to simulate the clobberall gives:

         movl    $1000, 44(%rsp)
.L2:
         #stuff
         subl    $1, 44(%rsp)
         jne     .L2

It allocates an extra 4 bytes, and changed everything to memory accesses 
instead of using a register.  Obviously not a huge performance impact on 
this tiny sample, but it does suggest to me that sometimes there could be.

My point being simply that people may want the old behavior, so we need 
to be sure there's a way to get it (ie "clobbernone").

>>>>> +Basic @code{asm} statements are not treated as though they used a
>>>>>> "memory"
>>>>>> +clobber, although they do implicitly perform a clobber of the flags
>>>>>> +(@pxref{Clobbers}).
>>>>> They do not clobber the flags.  Observe:
>>>>
>>>> Ouch.  i386 shows the same thing for basic asm.
>>> Sadly, I suspect this isn't consistent across targets.
>>
>> Bigger ouch.  I'll follow up on this after the discussion about changing
>> basic asm is complete (which may render this moot).
> It likely depends on how the target models the flags.

I'm not quite sure how to proceed here.  I'm pretty sure no one wants me 
to write "basic asm doesn't clobber flags, except that maybe it does on 
some (unspecified) platforms."

I've tried to follow the code, but without any particular success. I was 
hoping to see decode_reg_name_and_count (or decode_reg_name) being 
called from platform-specific routines and handling -3, but not so much.

Using users as beta testers is normally frowned upon (outside of 
Microsoft), but perhaps the solution here is to just say that it doesn't 
clobber flags (currently the most common case?), and update the docs if 
and when people complain?  Yes, that's bad, but saying nothing at all 
isn't any better.  And we know it's true for at least 2 platforms.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20  1:24           ` David Wohlferd
@ 2015-11-20  1:53             ` Sandra Loosemore
  2015-11-22  5:09               ` David Wohlferd
  2015-11-20  3:14             ` Segher Boessenkool
  2015-11-20 10:17             ` Andrew Haley
  2 siblings, 1 reply; 58+ messages in thread
From: Sandra Loosemore @ 2015-11-20  1:53 UTC (permalink / raw)
  To: David Wohlferd, Jeff Law, Segher Boessenkool; +Cc: gcc, rth, pinskia

On 11/19/2015 06:23 PM, David Wohlferd wrote:

>> About the only immediate task would be to ensure that the
>> documentation for traditional asms clearly documents the desired
>> semantics and somehow note that there are known bugs in the
>> implementation (ie 24414, handling of flags registers, and probably
>> other oddities)
>
> Given that gcc is at phase 3, I'm guessing this work won't be in v6?  Or
> would this be considered "general bugfixing?"
>
> The reason I ask is I want to clearly document what the current behavior
> is as well as informing them about what's coming.  If this isn't
> changing until v7, the text can be updated then to reflect the new
> behavior.

Documentation fixes are accepted all the way through Stage 4, since 
there's less risk of introducing regressions in user programs from 
accidental documentation mistakes than code errors.

OTOH, I'd discourage adding anything to the docs about anticipated 
changes in future releases, except possibly to note that certain 
features or behavior are deprecated and may be removed in future 
releases (with a suggestion about what you should do instead).  We've 
already got too many "maybe someday this will be fixed" notes in the 
manual that are not terribly useful to users.

-Sandra

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20  1:24           ` David Wohlferd
  2015-11-20  1:53             ` Sandra Loosemore
@ 2015-11-20  3:14             ` Segher Boessenkool
  2015-11-20 10:45               ` David Wohlferd
  2015-11-20 10:17             ` Andrew Haley
  2 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-20  3:14 UTC (permalink / raw)
  To: David Wohlferd; +Cc: Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On Thu, Nov 19, 2015 at 05:23:55PM -0800, David Wohlferd wrote:
> For that reason, I'd like to propose adding 2 new clobbers to extended 
> asm as part of this work:
> 
> "clobberall" - This gives extended the same semantics as whatever the 
> new basic asm will be using.
> "clobbernone" - This gives the same semantics as the current basic asm.

I don't think this is necessary or useful.  They are also awful names:
"clobberall" cannot clobber everything (think of the stack pointer),
and "clobbernone" does clobber some (those clobbered by any asm),

> Clobbernone may seem redundant, since not specifying any clobbers should 
> do the same thing.  But actually it doesn't, at least on i386.  At 
> present, there is no way for extended asm to not clobber "cc".  I don't 
> know if other platforms have similar issues.

Some do.  The purpose is to stay compatible with asm written for older
versions of the compiler.

> When basic asm changes, I expect that having a way to "just do what it 
> used to do" is going to be useful for some people.

24414 says the documented behaviour hasn't been true for at least
fourteen years.  It isn't likely anyone is relying on that behaviour.

> but perhaps the solution here is to just say that it doesn't 
> clobber flags (currently the most common case?), and update the docs if 
> and when people complain?  Yes, that's bad, but saying nothing at all 
> isn't any better.  And we know it's true for at least 2 platforms.

Saying nothing at all at least is *correct*.

It isn't necessary for users to know what registers the compiler
considers to be clobbered by an asm, unless they actually clobber
something in the assembler code themselves.  They can write extended
asm in that case.

Maybe you can put that in the doc?  "If you modify any register or
memory, use an extended asm"?  Jeff, do you agree with that?


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20  1:24           ` David Wohlferd
  2015-11-20  1:53             ` Sandra Loosemore
  2015-11-20  3:14             ` Segher Boessenkool
@ 2015-11-20 10:17             ` Andrew Haley
  2015-11-20 10:38               ` David Wohlferd
  2 siblings, 1 reply; 58+ messages in thread
From: Andrew Haley @ 2015-11-20 10:17 UTC (permalink / raw)
  To: David Wohlferd, Jeff Law, Segher Boessenkool
  Cc: gcc, rth, pinskia, Sandra Loosemore

On 20/11/15 01:23, David Wohlferd wrote:
> I tried to picture the most basic case I can think of that uses 
> something clobber-able:
> 
>     for (int x=0; x < 1000; x++)
>        asm("#stuff");
> 
> This generates very simple and highly performant code:
> 
>          movl    $1000, %eax
> .L2:
>          #stuff
>          subl    $1, %eax
>          jne     .L2
> 
> Using extended asm to simulate the clobberall gives:
> 
>          movl    $1000, 44(%rsp)
> .L2:
>          #stuff
>          subl    $1, 44(%rsp)
>          jne     .L2
> 
> It allocates an extra 4 bytes, and changed everything to memory accesses 
> instead of using a register.

Can you show us your code?  I get

xx:
	movl	$1000, %eax
.L2:
	#stuff
	subl	$1, %eax
	jne	.L2
	rep; ret

for

void xx() {
  for (int x=0; x < 1000; x++)
    asm volatile("#stuff" : : : "memory");
}

What you're describing looks like a bug: x doesn't have its address
taken.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 10:17             ` Andrew Haley
@ 2015-11-20 10:38               ` David Wohlferd
  2015-11-20 11:14                 ` Andrew Haley
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-20 10:38 UTC (permalink / raw)
  To: Andrew Haley, Jeff Law, Segher Boessenkool
  Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 2:17 AM, Andrew Haley wrote:
> On 20/11/15 01:23, David Wohlferd wrote:
>> I tried to picture the most basic case I can think of that uses
>> something clobber-able:
>>
>>      for (int x=0; x < 1000; x++)
>>         asm("#stuff");
>>
>> This generates very simple and highly performant code:
>>
>>           movl    $1000, %eax
>> .L2:
>>           #stuff
>>           subl    $1, %eax
>>           jne     .L2
>>
>> Using extended asm to simulate the clobberall gives:
>>
>>           movl    $1000, 44(%rsp)
>> .L2:
>>           #stuff
>>           subl    $1, 44(%rsp)
>>           jne     .L2
>>
>> It allocates an extra 4 bytes, and changed everything to memory accesses
>> instead of using a register.
> Can you show us your code?  I get
>
> xx:
> 	movl	$1000, %eax
> .L2:
> 	#stuff
> 	subl	$1, %eax
> 	jne	.L2
> 	rep; ret
>
> for
>
> void xx() {
>    for (int x=0; x < 1000; x++)
>      asm volatile("#stuff" : : : "memory");
> }
>
> What you're describing looks like a bug: x doesn't have its address
> taken.

The intent for 24414 is to change basic asm such that it will become 
(quoting jeff) "an opaque blob that read/write/clobber any register or 
memory location."  Such being the case, "memory" is not sufficient:

#define CLOBBERALL "eax", "ebx", "ecx", "edx", "r8", "r9", "r10", "r11", 
"r12", "r13", "r14", "r15", "edi", "esi", "ebp", "cc", "memory"

int main()
{
    for (int x=0; x < 1000; x++)
       asm("#":::CLOBBERALL);
}

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20  3:14             ` Segher Boessenkool
@ 2015-11-20 10:45               ` David Wohlferd
  2015-11-20 14:56                 ` Segher Boessenkool
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-20 10:45 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On 11/19/2015 7:14 PM, Segher Boessenkool wrote:
> On Thu, Nov 19, 2015 at 05:23:55PM -0800, David Wohlferd wrote:
>> For that reason, I'd like to propose adding 2 new clobbers to extended
>> asm as part of this work:
>>
>> "clobberall" - This gives extended the same semantics as whatever the
>> new basic asm will be using.
>> "clobbernone" - This gives the same semantics as the current basic asm.
> I don't think this is necessary or useful.  They are also awful names:
> "clobberall" cannot clobber everything (think of the stack pointer),

I'm not emotionally attached to the names.  But providing the same 
capability to extended that we are proposing for basic doesn't seem so 
odd.  Shouldn't extended be able to do (at least) everything basic does?

My first thought is that it allows people to incrementally start 
migrating from (new) basic to extended (something I think we should 
encourage).  Or use it as a debug tool to see if the failure you are 
experiencing from your asm is due to a missing clobber.  Since the 
capability will already be implemented for basic, providing a way to 
access it from extended seems trivial (if we can agree on a name).

As you say, clobbering the stack pointer presents special challenges 
(although gcc has a specific way of dealing with stack register 
clobbers, see 52813).  This is why I described the feature as having 
"the same semantics as whatever the new basic asm will be using."

> and "clobbernone" does clobber some (those clobbered by any asm),

Seems like a quibble.  Those other things (I assume you mean things like 
pipelining?) most users aren't even aware of (or they wouldn't be so 
eager to use inline asm in the first place).  Would it be more palatable 
if we called it "v5BasicAsmMode"?  "ClobberMin"?

>> Clobbernone may seem redundant, since not specifying any clobbers should
>> do the same thing.  But actually it doesn't, at least on i386.  At
>> present, there is no way for extended asm to not clobber "cc".  I don't
>> know if other platforms have similar issues.
> Some do.  The purpose is to stay compatible with asm written for older
> versions of the compiler.

Backward compatibility is important.  I understand that due to the cc0 
change in x86, existing code may have broken without always clobbering 
cc.  This was seen as the safest way to ensure that didn't happen.  
However no solution was/is available for people who correctly knew 
whether their asm clobbers the flags.

Mostly I'm ok with that.  All the ways that I can think of to try to 
re-allow people to start using the cc clobber are just not worth it.  I 
simply can't believe there are many cases where there's going to be a 
benefit.

But as I said: backward compatibility is important.  Providing a way for 
people who need/want the old basic asm semantics seems useful. And I 
don't believe we can (quite) do that without clobbernone.

>> When basic asm changes, I expect that having a way to "just do what it
>> used to do" is going to be useful for some people.
> 24414 says the documented behaviour hasn't been true for at least
> fourteen years.  It isn't likely anyone is relying on that behaviour.

?

To my knowledge, there was no documentation of any sort about what basic 
asm clobbered until I added it.  But what people are (presumably) 
relying on is that whatever it did in the last version, it's going to 
continue to do that in the next.  And albeit with good intentions, we 
are planning on changing that.

>> but perhaps the solution here is to just say that it doesn't
>> clobber flags (currently the most common case?), and update the docs if
>> and when people complain?  Yes, that's bad, but saying nothing at all
>> isn't any better.  And we know it's true for at least 2 platforms.
> Saying nothing at all at least is *correct*.

We don't know that saying "it doesn't clobber flags" is wrong either.  
All we know is that jeff said "I suspect this isn't consistent across 
targets."

But that's neither here nor there.  The real question is, if we can't 
say that, what can we say?

- If 24414 is going in v6, then we can doc that it does the clobber and 
be vague about the old behavior.
- If 24414 isn't going in v6, then what?  I suppose we can say that it 
can vary by platform.  We could even provide your sample code as a means 
for people to discover their platform's behavior.

> It isn't necessary for users to know what registers the compiler
> considers to be clobbered by an asm, unless they actually clobber
> something in the assembler code themselves.

I'm not sure I follow.

If someone has code that uses a register, currently they must restore 
the value before exiting the asm or risk disaster.  So they might write 
asm("push eax ; DoSomethingWith eax ; pop eax"). However if you know 
that the compiler is going to clobber eax, then the push/pop is just a 
waste of cycles and memory.

To write efficient code, it seems like you do need to know what the 
compiler clobbers.

> They can write extended asm in that case.

I agree that if they did that it would solve the problem.  But...

> Maybe you can put that in the doc?  "If you modify any register or
> memory, use an extended asm"?  Jeff, do you agree with that?

Well, I'm already on record as saying I think any asm that isn't top 
level should be extended, so I'm pretty much ok with that.

But that raises the question:

- If this is the requirement for using basic asm, why do we need to 
change its behavior at all?  Yes, code that uses registers or memory 
might fail due to optimizations, but such code would be in violation of 
supported usage.
- If registers and memory access are still supported in basic asm, 
what's the point of doc'ing that you can't?

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 10:38               ` David Wohlferd
@ 2015-11-20 11:14                 ` Andrew Haley
  2015-11-20 12:38                   ` David Wohlferd
  2015-11-20 16:41                   ` Jeff Law
  0 siblings, 2 replies; 58+ messages in thread
From: Andrew Haley @ 2015-11-20 11:14 UTC (permalink / raw)
  To: David Wohlferd, Jeff Law, Segher Boessenkool
  Cc: gcc, rth, pinskia, Sandra Loosemore

On 20/11/15 10:37, David Wohlferd wrote:
> The intent for 24414 is to change basic asm such that it will become 
> (quoting jeff) "an opaque blob that read/write/clobber any register or 
> memory location."  Such being the case, "memory" is not sufficient:
> 
> #define CLOBBERALL "eax", "ebx", "ecx", "edx", "r8", "r9", "r10", "r11", 
> "r12", "r13", "r14", "r15", "edi", "esi", "ebp", "cc", "memory"

Hmm.  I would not be at all surprised to see this cause reload
failures.  You certainly shouldn't clobber the frame pointer on
any machine which needs one.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 11:14                 ` Andrew Haley
@ 2015-11-20 12:38                   ` David Wohlferd
  2015-11-20 13:05                     ` Richard Henderson
  2015-11-20 16:41                   ` Jeff Law
  1 sibling, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-20 12:38 UTC (permalink / raw)
  To: Andrew Haley
  Cc: Jeff Law, Segher Boessenkool, gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 3:14 AM, Andrew Haley wrote:
> On 20/11/15 10:37, David Wohlferd wrote:
>> The intent for 24414 is to change basic asm such that it will become
>> (quoting jeff) "an opaque blob that read/write/clobber any register or
>> memory location."  Such being the case, "memory" is not sufficient:
>>
>> #define CLOBBERALL "eax", "ebx", "ecx", "edx", "r8", "r9", "r10", "r11",
>> "r12", "r13", "r14", "r15", "edi", "esi", "ebp", "cc", "memory"
> Hmm.  I would not be at all surprised to see this cause reload
> failures.  You certainly shouldn't clobber the frame pointer on
> any machine which needs one.

If I don't clobber ebp, gcc just uses it:

         movl    $1000, %ebp
.L2:
         #
         subl    $1, %ebp
         jne     .L2

The original purpose of this code was to attempt to show that this kind 
of "clobbering everything" behavior (the proposed new behavior for basic 
asm) could have non-trivial impact on existing routines. While I've been 
told that changing the existing "clobber nothing" approach to this kind 
of "clobber everything" is "less intrusive than you might think," I'm 
struggling to believe it.  It seems to me that one asm("nop") thrown 
into a driver routine to fix a timing problem could end up making a real 
mess.

But actually we're kind of past that.  When Jeff, Segher, (other) Andrew 
and Richard all say "this is how it's going to work," it's time for me 
to set aside my reservations and move on.

So now I'm just trying my best to make sure that if it *is* an issue, 
people have a viable solution readily available.  And to make sure it's 
all correctly doc'ed (which is what started this whole mess).

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 12:38                   ` David Wohlferd
@ 2015-11-20 13:05                     ` Richard Henderson
  2015-11-20 15:20                       ` Segher Boessenkool
                                         ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Richard Henderson @ 2015-11-20 13:05 UTC (permalink / raw)
  To: David Wohlferd, Andrew Haley
  Cc: Jeff Law, Segher Boessenkool, gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 01:38 PM, David Wohlferd wrote:
> On 11/20/2015 3:14 AM, Andrew Haley wrote:
>> On 20/11/15 10:37, David Wohlferd wrote:
>>> The intent for 24414 is to change basic asm such that it will become
>>> (quoting jeff) "an opaque blob that read/write/clobber any register or
>>> memory location."  Such being the case, "memory" is not sufficient:
>>>
>>> #define CLOBBERALL "eax", "ebx", "ecx", "edx", "r8", "r9", "r10", "r11",
>>> "r12", "r13", "r14", "r15", "edi", "esi", "ebp", "cc", "memory"
>> Hmm.  I would not be at all surprised to see this cause reload
>> failures.  You certainly shouldn't clobber the frame pointer on
>> any machine which needs one.
>
> If I don't clobber ebp, gcc just uses it:
>
>          movl    $1000, %ebp
> .L2:
>          #
>          subl    $1, %ebp
>          jne     .L2

I believe you'd have to have magic in there to conditionally clobber the 
register if it isn't being used as a frame pointer.

That said...

> The original purpose of this code was to attempt to show that this kind of
> "clobbering everything" behavior (the proposed new behavior for basic asm)
> could have non-trivial impact on existing routines. While I've been told that
> changing the existing "clobber nothing" approach to this kind of "clobber
> everything" is "less intrusive than you might think," I'm struggling to believe
> it.  It seems to me that one asm("nop") thrown into a driver routine to fix a
> timing problem could end up making a real mess.
>
> But actually we're kind of past that.  When Jeff, Segher, (other) Andrew and
> Richard all say "this is how it's going to work," it's time for me to set aside
> my reservations and move on.
>
> So now I'm just trying my best to make sure that if it *is* an issue, people
> have a viable solution readily available.  And to make sure it's all correctly
> doc'ed (which is what started this whole mess).

I'd be perfectly happy to deprecate and later completely remove basic asm 
within functions.

Because IMO it's essentially useless.  It has no inputs, no outputs, and no way 
to tell the compiler what machine state has been changed.  We can say that "it 
clobbers everything", but that's not actually useful, and quite difficult as 
you're finding out.

It seems to me that it would be better to remove the feature, forcing what must 
be an extremely small number of users to audit and update to extended asm.



r~

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 10:45               ` David Wohlferd
@ 2015-11-20 14:56                 ` Segher Boessenkool
  2015-11-20 20:01                   ` Jeff Law
  0 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-20 14:56 UTC (permalink / raw)
  To: David Wohlferd; +Cc: Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On Fri, Nov 20, 2015 at 02:45:05AM -0800, David Wohlferd wrote:
> On 11/19/2015 7:14 PM, Segher Boessenkool wrote:
> >On Thu, Nov 19, 2015 at 05:23:55PM -0800, David Wohlferd wrote:
> >>For that reason, I'd like to propose adding 2 new clobbers to extended
> >>asm as part of this work:
> >>
> >>"clobberall" - This gives extended the same semantics as whatever the
> >>new basic asm will be using.
> >>"clobbernone" - This gives the same semantics as the current basic asm.
> >I don't think this is necessary or useful.  They are also awful names:
> >"clobberall" cannot clobber everything (think of the stack pointer),
> 
> I'm not emotionally attached to the names.

Names should be succinct, clear, and give a good indication of what the
thing named does.  If it is hard to make a good name it is likely that
the interface isn't so well designed.

> But providing the same 
> capability to extended that we are proposing for basic doesn't seem so 
> odd.  Shouldn't extended be able to do (at least) everything basic does?

But that would be logical!  Can't have that.  Heh.

> As you say, clobbering the stack pointer presents special challenges 
> (although gcc has a specific way of dealing with stack register 
> clobbers, see 52813).

Yeah.  Actually, basic asm is handled specially in many places, too.

> >and "clobbernone" does clobber some (those clobbered by any asm),
> 
> Seems like a quibble.  Those other things (I assume you mean things like 
> pipelining?) most users aren't even aware of (or they wouldn't be so 
> eager to use inline asm in the first place).  Would it be more palatable 
> if we called it "v5BasicAsmMode"?  "ClobberMin"?

I meant things like x86 "cc".

> >>Clobbernone may seem redundant, since not specifying any clobbers should
> >>do the same thing.  But actually it doesn't, at least on i386.  At
> >>present, there is no way for extended asm to not clobber "cc".  I don't
> >>know if other platforms have similar issues.
> >Some do.  The purpose is to stay compatible with asm written for older
> >versions of the compiler.
> 
> Backward compatibility is important.  I understand that due to the cc0 
> change in x86, existing code may have broken without always clobbering 
> cc.  This was seen as the safest way to ensure that didn't happen.  
> However no solution was/is available for people who correctly knew 
> whether their asm clobbers the flags.
> 
> Mostly I'm ok with that.  All the ways that I can think of to try to 
> re-allow people to start using the cc clobber are just not worth it.  I 
> simply can't believe there are many cases where there's going to be a 
> benefit.

Exactly.  The asm still can be moved "over" other uses of CC, it does
not limit transformations much at all.

> But as I said: backward compatibility is important.  Providing a way for 
> people who need/want the old basic asm semantics seems useful. And I 
> don't believe we can (quite) do that without clobbernone.
> 
> >>When basic asm changes, I expect that having a way to "just do what it
> >>used to do" is going to be useful for some people.
> >24414 says the documented behaviour hasn't been true for at least
> >fourteen years.  It isn't likely anyone is relying on that behaviour.
> 
> ?

24414 says these things haven't worked since at least 2.95.3, which is
fourteen years old now.

> >It isn't necessary for users to know what registers the compiler
> >considers to be clobbered by an asm, unless they actually clobber
> >something in the assembler code themselves.
> 
> I'm not sure I follow.

If the assembler code does not clobber some register, but GCC treats it
as if it does, things will work correctly.


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 13:05                     ` Richard Henderson
@ 2015-11-20 15:20                       ` Segher Boessenkool
  2015-11-20 15:30                         ` Richard Henderson
  2015-11-20 18:24                       ` Jeff Law
  2015-11-26 10:30                       ` Hans-Peter Nilsson
  2 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-20 15:20 UTC (permalink / raw)
  To: Richard Henderson
  Cc: David Wohlferd, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On Fri, Nov 20, 2015 at 02:05:01PM +0100, Richard Henderson wrote:
> I'd be perfectly happy to deprecate and later completely remove basic asm 
> within functions.
> 
> Because IMO it's essentially useless.  It has no inputs, no outputs, and no 
> way to tell the compiler what machine state has been changed.  We can say 
> that "it clobbers everything", but that's not actually useful, and quite 
> difficult as you're finding out.
> 
> It seems to me that it would be better to remove the feature, forcing what 
> must be an extremely small number of users to audit and update to extended 
> asm.

Should  asm("bla");  then be an extended asm with no input, no outputs,
no (non-automatic) clobbers?  That would be the most straightforward and
logical semantics, but will it break user code?


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 15:20                       ` Segher Boessenkool
@ 2015-11-20 15:30                         ` Richard Henderson
  2015-11-20 15:34                           ` Jakub Jelinek
                                             ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Richard Henderson @ 2015-11-20 15:30 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: David Wohlferd, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On 11/20/2015 04:20 PM, Segher Boessenkool wrote:
> On Fri, Nov 20, 2015 at 02:05:01PM +0100, Richard Henderson wrote:
>> I'd be perfectly happy to deprecate and later completely remove basic asm
>> within functions.
>>
>> Because IMO it's essentially useless.  It has no inputs, no outputs, and no
>> way to tell the compiler what machine state has been changed.  We can say
>> that "it clobbers everything", but that's not actually useful, and quite
>> difficult as you're finding out.
>>
>> It seems to me that it would be better to remove the feature, forcing what
>> must be an extremely small number of users to audit and update to extended
>> asm.
>
> Should  asm("bla");  then be an extended asm with no input, no outputs,
> no (non-automatic) clobbers?  That would be the most straightforward and
> logical semantics, but will it break user code?

I'm suggesting that we don't accept that at all inside a function.  One must 
audit the source and make a conscious decision to write asm("bla" : ); instead.

Accepting basic asm outside of a function is perfectly ok, since that's just a 
mechanism by which one can inject complete assembly routines into a C 
translation unit.


r~

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 15:30                         ` Richard Henderson
@ 2015-11-20 15:34                           ` Jakub Jelinek
  2015-11-20 16:14                             ` Richard Henderson
  2015-11-20 16:21                           ` Segher Boessenkool
  2015-11-27 17:45                           ` Segher Boessenkool
  2 siblings, 1 reply; 58+ messages in thread
From: Jakub Jelinek @ 2015-11-20 15:34 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Segher Boessenkool, David Wohlferd, Andrew Haley, Jeff Law, gcc,
	rth, pinskia, Sandra Loosemore

On Fri, Nov 20, 2015 at 04:29:50PM +0100, Richard Henderson wrote:
> On 11/20/2015 04:20 PM, Segher Boessenkool wrote:
> >On Fri, Nov 20, 2015 at 02:05:01PM +0100, Richard Henderson wrote:
> >>I'd be perfectly happy to deprecate and later completely remove basic asm
> >>within functions.
> >>
> >>Because IMO it's essentially useless.  It has no inputs, no outputs, and no
> >>way to tell the compiler what machine state has been changed.  We can say
> >>that "it clobbers everything", but that's not actually useful, and quite
> >>difficult as you're finding out.
> >>
> >>It seems to me that it would be better to remove the feature, forcing what
> >>must be an extremely small number of users to audit and update to extended
> >>asm.
> >
> >Should  asm("bla");  then be an extended asm with no input, no outputs,
> >no (non-automatic) clobbers?  That would be the most straightforward and
> >logical semantics, but will it break user code?
> 
> I'm suggesting that we don't accept that at all inside a function.  One must
> audit the source and make a conscious decision to write asm("bla" : );
> instead.
> 
> Accepting basic asm outside of a function is perfectly ok, since that's just
> a mechanism by which one can inject complete assembly routines into a C
> translation unit.

Isn't that going to break too much code though?  I mean, e.g. including
libgcc...

	Jakub

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 15:34                           ` Jakub Jelinek
@ 2015-11-20 16:14                             ` Richard Henderson
  2015-11-20 23:56                               ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Richard Henderson @ 2015-11-20 16:14 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Segher Boessenkool, David Wohlferd, Andrew Haley, Jeff Law, gcc,
	rth, pinskia, Sandra Loosemore

On 11/20/2015 04:34 PM, Jakub Jelinek wrote:
> Isn't that going to break too much code though?  I mean, e.g. including
> libgcc...

I don't know.  My suspicion is very little.

But that's actually what I'd like to know before we start adjusting code in 
other ways wrt basic asms.


r~

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 15:30                         ` Richard Henderson
  2015-11-20 15:34                           ` Jakub Jelinek
@ 2015-11-20 16:21                           ` Segher Boessenkool
  2015-11-27 17:45                           ` Segher Boessenkool
  2 siblings, 0 replies; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-20 16:21 UTC (permalink / raw)
  To: Richard Henderson
  Cc: David Wohlferd, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On Fri, Nov 20, 2015 at 04:29:50PM +0100, Richard Henderson wrote:
> >>It seems to me that it would be better to remove the feature, forcing what
> >>must be an extremely small number of users to audit and update to extended
> >>asm.
> >
> >Should  asm("bla");  then be an extended asm with no input, no outputs,
> >no (non-automatic) clobbers?  That would be the most straightforward and
> >logical semantics, but will it break user code?
> 
> I'm suggesting that we don't accept that at all inside a function.  One 
> must audit the source and make a conscious decision to write asm("bla" : ); 
> instead.

Ah, or excepting asm("bla") and treating it just like asm("bla" : ), but
giving a warning?  That will get people to migrate at least.

> Accepting basic asm outside of a function is perfectly ok, since that's 
> just a mechanism by which one can inject complete assembly routines into a 
> C translation unit.

Of course.  You cannot have extended asm outside of functions at all.


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 11:14                 ` Andrew Haley
  2015-11-20 12:38                   ` David Wohlferd
@ 2015-11-20 16:41                   ` Jeff Law
  1 sibling, 0 replies; 58+ messages in thread
From: Jeff Law @ 2015-11-20 16:41 UTC (permalink / raw)
  To: Andrew Haley, David Wohlferd, Segher Boessenkool
  Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 04:14 AM, Andrew Haley wrote:
> On 20/11/15 10:37, David Wohlferd wrote:
>> The intent for 24414 is to change basic asm such that it will become
>> (quoting jeff) "an opaque blob that read/write/clobber any register or
>> memory location."  Such being the case, "memory" is not sufficient:
>>
>> #define CLOBBERALL "eax", "ebx", "ecx", "edx", "r8", "r9", "r10", "r11",
>> "r12", "r13", "r14", "r15", "edi", "esi", "ebp", "cc", "memory"
>
> Hmm.  I would not be at all surprised to see this cause reload
> failures.  You certainly shouldn't clobber the frame pointer on
> any machine which needs one.
Right.  It'll cause other issues as well.  It's the only reason why I 
didn't change the code internally to stomp every hard register back in 1999.

jeff


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 13:05                     ` Richard Henderson
  2015-11-20 15:20                       ` Segher Boessenkool
@ 2015-11-20 18:24                       ` Jeff Law
  2015-11-20 19:39                         ` Paul_Koning
  2015-11-26 10:30                       ` Hans-Peter Nilsson
  2 siblings, 1 reply; 58+ messages in thread
From: Jeff Law @ 2015-11-20 18:24 UTC (permalink / raw)
  To: Richard Henderson, David Wohlferd, Andrew Haley
  Cc: Segher Boessenkool, gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 06:05 AM, Richard Henderson wrote:

>
> I'd be perfectly happy to deprecate and later completely remove basic
> asm within functions.
>
> Because IMO it's essentially useless.  It has no inputs, no outputs, and
> no way to tell the compiler what machine state has been changed.  We can
> say that "it clobbers everything", but that's not actually useful, and
> quite difficult as you're finding out.
And even more difficult to document exactly what happens, largely 
because the implementation in GCC isn't consistent across passes and 
there's differences in behaviour that are dependent on the target 
implementation as well.

Unfortunately there's not a single place where we can ensure consistent 
behaviour, so each pass has had to handle ASMs independently, and I'm 
pretty sure they all get it wrong to varying degrees.


>
> It seems to me that it would be better to remove the feature, forcing
> what must be an extremely small number of users to audit and update to
> extended asm.
That might be a little drastic.  Though if we want to go this direction, 
the first step is to deprecate for a major release cycle.  It would be 
interesting to see how much stuff would complain/break.

jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 18:24                       ` Jeff Law
@ 2015-11-20 19:39                         ` Paul_Koning
  0 siblings, 0 replies; 58+ messages in thread
From: Paul_Koning @ 2015-11-20 19:39 UTC (permalink / raw)
  To: law; +Cc: gcc


> On Nov 20, 2015, at 1:24 PM, Jeff Law <law@redhat.com> wrote:
> 
> On 11/20/2015 06:05 AM, Richard Henderson wrote:
> 
>> ...
>> It seems to me that it would be better to remove the feature, forcing
>> what must be an extremely small number of users to audit and update to
>> extended asm.
> That might be a little drastic.  Though if we want to go this direction, the first step is to deprecate for a major release cycle.  It would be interesting to see how much stuff would complain/break.

I would expect: a lot.  I've seen plenty of people writing asm statements (in small quantities, admittedly) who have never heard of extended asm.

	paul

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 14:56                 ` Segher Boessenkool
@ 2015-11-20 20:01                   ` Jeff Law
  2015-11-20 22:07                     ` Paul_Koning
  0 siblings, 1 reply; 58+ messages in thread
From: Jeff Law @ 2015-11-20 20:01 UTC (permalink / raw)
  To: Segher Boessenkool, David Wohlferd; +Cc: gcc, rth, pinskia, Sandra Loosemore

On 11/20/2015 07:56 AM, Segher Boessenkool wrote:

>>>> When basic asm changes, I expect that having a way to "just do what it
>>>> used to do" is going to be useful for some people.
>>> 24414 says the documented behaviour hasn't been true for at least
>>> fourteen years.  It isn't likely anyone is relying on that behaviour.
>>
>> ?
>
> 24414 says these things haven't worked since at least 2.95.3, which is
> fourteen years old now.
That's not a good reason to leave things as-is.

The problem is that optimizers continue to improve.   So an old-style 
asm that worked in the past may mysteriously start failing as folks move 
forward with their compiler -- because we haven't properly implemented 
the right semantics of old-style asms, which is in part because certain 
aspects were never documented properly and partly because of reload 
issues :(

If we keep old style asms, then we need to properly document what their 
behaviour is supposed to be, and continue to fix bugs where we do not 
honor that behaviour.

The latter is somewhat painful because we don't have a single place 
where we can audit & fix any semantic problems.  It's scattered in 
various optimizers throughout GCC.  And I suspect most are getting it 
wrong in one way or another.


Jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 20:01                   ` Jeff Law
@ 2015-11-20 22:07                     ` Paul_Koning
  0 siblings, 0 replies; 58+ messages in thread
From: Paul_Koning @ 2015-11-20 22:07 UTC (permalink / raw)
  To: law; +Cc: segher, dw, gcc, rth, pinskia, sandra


> On Nov 20, 2015, at 3:01 PM, Jeff Law <law@redhat.com> wrote:
> 
> On 11/20/2015 07:56 AM, Segher Boessenkool wrote:
> 
>>>>> When basic asm changes, I expect that having a way to "just do what it
>>>>> used to do" is going to be useful for some people.
>>>> 24414 says the documented behaviour hasn't been true for at least
>>>> fourteen years.  It isn't likely anyone is relying on that behaviour.
>>> 
>>> ?
>> 
>> 24414 says these things haven't worked since at least 2.95.3, which is
>> fourteen years old now.
> That's not a good reason to leave things as-is.
> 
> The problem is that optimizers continue to improve.   So an old-style asm that worked in the past may mysteriously start failing as folks move forward with their compiler -- because we haven't properly implemented the right semantics of old-style asms, which is in part because certain aspects were never documented properly and partly because of reload issues :(
> 
> If we keep old style asms, then we need to properly document what their behaviour is supposed to be, and continue to fix bugs where we do not honor that behaviour.

Yes.  I know I've run into cases before where certain documented properties were not honored. I can't find the details right now; I think it was "old style asm always behaves as if marked 'volatile'. "

	paul

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 16:14                             ` Richard Henderson
@ 2015-11-20 23:56                               ` David Wohlferd
  2015-11-21 12:57                                 ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-20 23:56 UTC (permalink / raw)
  To: Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On 11/20/2015 8:14 AM, Richard Henderson wrote:
> On 11/20/2015 04:34 PM, Jakub Jelinek wrote:
>> Isn't that going to break too much code though?  I mean, e.g. including
>> libgcc...
>
> I don't know.  My suspicion is very little.
>
> But that's actually what I'd like to know before we start adjusting 
> code in other ways wrt basic asms.

I can provide a little data here.

In an effort to gain some perspective, I've been looking at inline asm 
usage in the linux kernel (4.3).  Clearly this isn't "typical usage," 
but it is probably one of the biggest users of inline asm, and likely 
has the best justifications for doing so (being an OS and all).

There are ~5,711 instances of inline asm in use.  Of those, ~4,833 are 
extended and ~878 are basic.

I don't have any numbers about how many are top level vs in function, 
but let me see what I can do.

A quick look at libgcc shows that there are 109 extended and 45 basic 
asm statements.  I'll see how many end up being top-level, but it looks 
like most of them.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 23:56                               ` David Wohlferd
@ 2015-11-21 12:57                                 ` David Wohlferd
  2015-11-23  9:56                                   ` Joseph Myers
  2015-11-23 10:04                                   ` Andrew Haley
  0 siblings, 2 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-21 12:57 UTC (permalink / raw)
  To: Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On 11/20/2015 3:55 PM, David Wohlferd wrote:
> On 11/20/2015 8:14 AM, Richard Henderson wrote:
>> On 11/20/2015 04:34 PM, Jakub Jelinek wrote:
>>> Isn't that going to break too much code though?  I mean, e.g. including
>>> libgcc...
>>
>> I don't know.  My suspicion is very little.
>>
>> But that's actually what I'd like to know before we start adjusting 
>> code in other ways wrt basic asms.
>
> I can provide a little data here.
>
> In an effort to gain some perspective, I've been looking at inline asm 
> usage in the linux kernel (4.3).  Clearly this isn't "typical usage," 
> but it is probably one of the biggest users of inline asm, and likely 
> has the best justifications for doing so (being an OS and all).
>
> There are ~5,678 instances of inline asm in use.  Of those, ~4,833 are 
> extended and ~845 are basic.
>
> I don't have any numbers about how many are top level vs in function, 
> but let me see what I can do.

Ok, the news here is mixed.  Of those 845:

- Only 50 of them look like top level asm.  I was hoping for more.
- 457 are in 6 files in the lib/raid6 directory, so there's a bunch that 
can be done quickly.
- That leaves 338 miscellaneous other uses spread throughout some 200 
files across multiple platforms.  That seems like a lot.

Despite the concerns expressed by Jeff about the difficulties in 
changing from basic to extended, it looks to me like they don't need any 
conversion (other s/%/%%/).  Adding the trailing colon should be 
sufficient to provide the semantics they have now, which apparently is 
deemed sufficient.

> A quick look at libgcc shows that there are 109 extended and 45 basic 
> asm statements.  I'll see how many end up being top-level, but it 
> looks like most of them.

Of the 45 basic asm statements, only 9 aren't top-level.  They all 
appear to be trivial to change to extended.

To sum up:

- Some projects (like libgcc) are going to be simple to update. Maybe an 
hour's work all told.
- Some projects (like testsuite) are going to take longer.  While the 
changes are mostly straight-forward, the number of files involved will 
be a factor.
- I took a look at the Mingw-w64 project.  It has ~20 non-top level 
asms, so also pretty simple to update.
- But some projects (like linux kernel) are going to be more 
challenging.  Not so much making the changes (although that will take a 
while) as convincing yourself that the change was harmless and still 
compiles on all supported platforms.

Yes, this represents a very limited sample.  And one weighted towards 
projects that are more likely to use asm.  But it does give some sense 
of the scale.

So, what now?

While I'd like to take the big step and start kicking out warnings for 
non-top-level right now, that may be too bold for phase 3.  A more 
modest step for v6 would just provide a way to find them (maybe 
something like -Wnon-top-basic-asm or -Wonly-top-basic-asm) and doc the 
current behavior as well as the upcoming change.

Adding the warning is not something I can do.  But I'll create the doc 
patch once someone confirms that this is the plan.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20  1:53             ` Sandra Loosemore
@ 2015-11-22  5:09               ` David Wohlferd
  0 siblings, 0 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-22  5:09 UTC (permalink / raw)
  To: Sandra Loosemore; +Cc: Jeff Law, Segher Boessenkool, gcc, rth, pinskia

On 11/19/2015 5:53 PM, Sandra Loosemore wrote:
> On 11/19/2015 06:23 PM, David Wohlferd wrote:
>
>>> About the only immediate task would be to ensure that the
>>> documentation for traditional asms clearly documents the desired
>>> semantics and somehow note that there are known bugs in the
>>> implementation (ie 24414, handling of flags registers, and probably
>>> other oddities)
>>
>> Given that gcc is at phase 3, I'm guessing this work won't be in v6?  Or
>> would this be considered "general bugfixing?"
>>
>> The reason I ask is I want to clearly document what the current behavior
>> is as well as informing them about what's coming.  If this isn't
>> changing until v7, the text can be updated then to reflect the new
>> behavior.
>
> Documentation fixes are accepted all the way through Stage 4, since 
> there's less risk of introducing regressions in user programs from 
> accidental documentation mistakes than code errors.

The code change isn't yet finalized.  I'm hoping to doc something 
vaguely like:

"basic asm (other than at top level) is being deprecated because <blah 
blah> potentially unsafe due to optimizations <blah blah blah>.  You can 
locate the statements that will no longer be supported using 
-Wonly-top-basic-asm.  Change them to use extended asm instead."

What's your take on having the user guide link to the gcc wiki?  If we 
do make this change, I'd kinda like to create a "how to convert basic 
asm to extended."  But it doesn't seem like a good fit for the user 
docs.  But if the user docs don't reference the wiki, I doubt anyone 
would ever find it.

> OTOH, I'd discourage adding anything to the docs about anticipated 
> changes in future releases, except possibly to note that certain 
> features or behavior are deprecated and may be removed in future 
> releases (with a suggestion about what you should do instead). 

I'd love to see the doc folks make a pass and remove every "some day 
this won't work" text that doesn't include this.  If there is no way for 
users to prepare, you aren't helping.

And remove all the "some day there might be a new feature" stuff too.  
It just wastes users' time trying to figure out if "some day" has 
arrived yet.  And it makes them cry when the new feature, which is 
exactly what they need, isn't there yet.

> We've already got too many "maybe someday this will be fixed" notes in 
> the manual that are not terribly useful to users.

You'd get my vote to remove them all.  If I got a vote.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-21 12:57                                 ` David Wohlferd
@ 2015-11-23  9:56                                   ` Joseph Myers
  2015-11-23 10:04                                   ` Andrew Haley
  1 sibling, 0 replies; 58+ messages in thread
From: Joseph Myers @ 2015-11-23  9:56 UTC (permalink / raw)
  To: David Wohlferd
  Cc: Richard Henderson, Jakub Jelinek, Segher Boessenkool,
	Andrew Haley, Jeff Law, gcc, rth, pinskia, Sandra Loosemore

[-- Attachment #1: Type: text/plain, Size: 394 bytes --]

Note that basic asm is part of the standard C++ syntax.  "An asm 
declaration has the form
asm-definition:
asm ( string-literal ) ;
The asm declaration is conditionally-supported; its meaning is 
implementation-defined. [ Note: Typically
it is used to pass information through the implementation to an assembler. 
— end note ]" (7.4 [dcl.asm]).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-21 12:57                                 ` David Wohlferd
  2015-11-23  9:56                                   ` Joseph Myers
@ 2015-11-23 10:04                                   ` Andrew Haley
  2015-11-23 20:37                                     ` Jeff Law
  2015-11-23 21:03                                     ` David Wohlferd
  1 sibling, 2 replies; 58+ messages in thread
From: Andrew Haley @ 2015-11-23 10:04 UTC (permalink / raw)
  To: David Wohlferd, Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On 21/11/15 12:56, David Wohlferd wrote:
> So, what now?
> 
> While I'd like to take the big step and start kicking out warnings for 
> non-top-level right now, that may be too bold for phase 3.  A more 
> modest step for v6 would just provide a way to find them (maybe 
> something like -Wnon-top-basic-asm or -Wonly-top-basic-asm) and doc the 
> current behavior as well as the upcoming change.

Warnings would be good.

My warning still holds: there are modes of compilation on some
machines where you can't clobber all registers without causing reload
failures.  This is why Jeff didn't fix this in 1999.  So, if we really
do want to clobber "all" registers in basic asm it'll take a lot of
work.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 10:04                                   ` Andrew Haley
@ 2015-11-23 20:37                                     ` Jeff Law
  2015-11-23 21:36                                       ` David Wohlferd
  2015-11-23 21:03                                     ` David Wohlferd
  1 sibling, 1 reply; 58+ messages in thread
From: Jeff Law @ 2015-11-23 20:37 UTC (permalink / raw)
  To: Andrew Haley, David Wohlferd, Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, gcc, rth, pinskia, Sandra Loosemore

On 11/23/2015 03:04 AM, Andrew Haley wrote:
> On 21/11/15 12:56, David Wohlferd wrote:
>> So, what now?
>>
>> While I'd like to take the big step and start kicking out warnings for
>> non-top-level right now, that may be too bold for phase 3.  A more
>> modest step for v6 would just provide a way to find them (maybe
>> something like -Wnon-top-basic-asm or -Wonly-top-basic-asm) and doc the
>> current behavior as well as the upcoming change.
>
> Warnings would be good.
>
> My warning still holds: there are modes of compilation on some
> machines where you can't clobber all registers without causing reload
> failures.  This is why Jeff didn't fix this in 1999.  So, if we really
> do want to clobber "all" registers in basic asm it'll take a lot of
> work.
Exactly.  In retrospect, I probably should have generated more tests for 
those conditions back in '99.  Essentially they'd document a class of 
problems we'd like to fix over time.

I know some have been addressed in various forms, but it hasn't been 
systematic.

My recommendation here is to:

   1. Note in the docs what the behaviour should be.  This guides where
   we want to go from an implementation standpoint.  I think it'd be fine
   to *suggest* only using old style asms at the toplevel, but I'm less
   convinced that mandating that restriction is wise.

   2. As we come across failures for adhere to the desired behaviour,
   fix or document them as known inconsistencies.  If we find that some
   are inherently un-fixable, then we'll need to tighten the docs around
   those.


The more I think about it, I'm just not keen on forcing all those 
old-style asms to change.

jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 10:04                                   ` Andrew Haley
  2015-11-23 20:37                                     ` Jeff Law
@ 2015-11-23 21:03                                     ` David Wohlferd
  2015-11-24  9:48                                       ` Andrew Haley
  1 sibling, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-23 21:03 UTC (permalink / raw)
  To: Andrew Haley, Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On 11/23/2015 2:04 AM, Andrew Haley wrote:
> On 21/11/15 12:56, David Wohlferd wrote:
>> So, what now?
>>
>> While I'd like to take the big step and start kicking out warnings for
>> non-top-level right now, that may be too bold for phase 3.  A more
>> modest step for v6 would just provide a way to find them (maybe
>> something like -Wnon-top-basic-asm or -Wonly-top-basic-asm) and doc the
>> current behavior as well as the upcoming change.
> Warnings would be good.

Richard's suggestion was:

 > I'm suggesting that we don't accept [basic asm] at all inside a 
function.  One must audit the source and make a conscious decision to 
write asm("bla" : ); instead.  Accepting basic asm outside of a function 
is perfectly ok.

I'm really not a compiler-writer, but I've taken a shot at implementing 
this.  While Richard is talking about completely deprecating this 
feature (a direction I support), I've started by emitting warnings, and 
by having the warnings disabled by default. This allows people to 
experiment with the new direction without getting clobbered by it.  My 
intent is something like this:

-Wonly-top-basic-asm
Warn if basic @code{asm} statements are used inside a function (ie not
at file scope/top level).  Due to the potential for unsafe optimizations,
always use extended instead of basic asm inside functions.  This
warning is disabled by default and is not enabled by -Wall or -Wextra.

I probably won't include the bits about Wall or Wextra in the actual doc 
patch.  They're here more to provoke comments in case someone thinks 
this behavior should change.  I'm open to suggestions about alternate 
names, too.

I've got this working for both c and c++.  It doesn't affect other 
places that use "asm" like "explicit register variables," "asm labels," 
"extended asm" or "top level basic asm."  It is also pleasantly small.  
As written, it should be useful to find places in current code that are 
at risk.

However (there's always a 'however'), it doesn't correctly handle 
"naked" functions (ie __attribute__((naked)) ).  By definition, naked 
functions can *only* include basic asm 
(https://gcc.gnu.org/ml/gcc/2014-05/msg00172.html).  So generating a 
warning for them is incorrect.

I'll need help fixing that.

I don't know if it is possible from within the parsers (where my current 
code is being added) to walk back up and get the attributes for the 
function.  I assume not.  In that case, I'll need some help finding some 
place up the call stack where you can.  Suggestions welcome.

The patch is at http://www.LimeGreenSocks.com/gcc/24414f.zip and 
includes test code.

> My warning still holds: there are modes of compilation on some
> machines where you can't clobber all registers without causing reload
> failures.  This is why Jeff didn't fix this in 1999.  So, if we really
> do want to clobber "all" registers in basic asm it'll take a lot of
> work.

I was always reluctant to see this change made.  In addition to the 
issues you mention, I had questions about the impact on the surrounding 
code.  I like Richard's direction much better.  We can start with a 
disabled warning, then upgrade as seems warranted.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 20:37                                     ` Jeff Law
@ 2015-11-23 21:36                                       ` David Wohlferd
  2015-11-23 21:44                                         ` Paul_Koning
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-23 21:36 UTC (permalink / raw)
  To: Jeff Law, Andrew Haley, Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, gcc, rth, pinskia, Sandra Loosemore

On 11/23/2015 12:37 PM, Jeff Law wrote:
> On 11/23/2015 03:04 AM, Andrew Haley wrote:
>> On 21/11/15 12:56, David Wohlferd wrote:
>>> So, what now?
>>>
>>> While I'd like to take the big step and start kicking out warnings for
>>> non-top-level right now, that may be too bold for phase 3.  A more
>>> modest step for v6 would just provide a way to find them (maybe
>>> something like -Wnon-top-basic-asm or -Wonly-top-basic-asm) and doc the
>>> current behavior as well as the upcoming change.
>>
>> Warnings would be good.
>>
>> My warning still holds: there are modes of compilation on some
>> machines where you can't clobber all registers without causing reload
>> failures.  This is why Jeff didn't fix this in 1999.  So, if we really
>> do want to clobber "all" registers in basic asm it'll take a lot of
>> work.
> Exactly.  In retrospect, I probably should have generated more tests 
> for those conditions back in '99.  Essentially they'd document a class 
> of problems we'd like to fix over time.
>
> I know some have been addressed in various forms, but it hasn't been 
> systematic.
>
> My recommendation here is to:
>
>   1. Note in the docs what the behaviour should be.  This guides where
>   we want to go from an implementation standpoint.  I think it'd be fine
>   to *suggest* only using old style asms at the toplevel, but I'm less
>   convinced that mandating that restriction is wise.

I hear your concerns about mandating this.  Perhaps starting by 
providing an option to find them, then (someday) enabling that option by 
default?

>   2. As we come across failures for adhere to the desired behaviour,
>   fix or document them as known inconsistencies.  If we find that some
>   are inherently un-fixable, then we'll need to tighten the docs around
>   those.

It's your expectation that extended asm won't be sufficient to resolve 
these issues?

> The more I think about it, I'm just not keen on forcing all those 
> old-style asms to change.

If you mean you aren't keen to change them to "clobber all," I'm with 
you.  If you are worried about changing them from basic to extended, 
what kinds of problems do you foresee?  I've been reading a lot of basic 
asm lately, and it seems to me that most of it would be fine with a 
simple colon.  Certainly no worse than the current behavior.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 21:36                                       ` David Wohlferd
@ 2015-11-23 21:44                                         ` Paul_Koning
  2015-11-24  1:39                                           ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Paul_Koning @ 2015-11-23 21:44 UTC (permalink / raw)
  To: dw; +Cc: law, aph, rth, jakub, segher, gcc, rth, pinskia, sandra


> On Nov 23, 2015, at 4:36 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
> 
> ...
>> The more I think about it, I'm just not keen on forcing all those old-style asms to change.
> 
> If you mean you aren't keen to change them to "clobber all," I'm with you.  If you are worried about changing them from basic to extended, what kinds of problems do you foresee?  I've been reading a lot of basic asm lately, and it seems to me that most of it would be fine with a simple colon.  Certainly no worse than the current behavior.

I'm not sure.  I have some asm("sync") which I think assume that this means asm("sync"::"memory")

	paul

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 21:44                                         ` Paul_Koning
@ 2015-11-24  1:39                                           ` David Wohlferd
  2015-11-24  2:22                                             ` Segher Boessenkool
  2015-11-24 17:13                                             ` Paul_Koning
  0 siblings, 2 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-24  1:39 UTC (permalink / raw)
  To: Paul_Koning; +Cc: law, aph, rth, jakub, segher, gcc, rth, pinskia, sandra

On 11/23/2015 1:44 PM, Paul_Koning@Dell.com wrote:
>> On Nov 23, 2015, at 4:36 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
>>
>> ...
>>> The more I think about it, I'm just not keen on forcing all those old-style asms to change.
>> If you mean you aren't keen to change them to "clobber all," I'm with you.  If you are worried about changing them from basic to extended, what kinds of problems do you foresee?  I've been reading a lot of basic asm lately, and it seems to me that most of it would be fine with a simple colon.  Certainly no worse than the current behavior.
> I'm not sure.  I have some asm("sync") which I think assume that this means asm("sync"::"memory")

Another excellent reason to nudge people towards using extended asm.  If 
you saw asm("sync":::"memory"), you would *know* what it did, without 
having to read the docs (which don't say anyway).

I'm pretty confident that asm("") doesn't clobber memory on i386, but 
maybe that behavior is platform-specific.  Since i386 doesn't have 
"sync", I assume you are on something else?

If you have a chance to experiment, I'd love confirmation from other 
platforms that asm("blah") is the same as asm("blah":).  Feel free to 
email me off list to discuss.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24  1:39                                           ` David Wohlferd
@ 2015-11-24  2:22                                             ` Segher Boessenkool
  2015-11-24  4:48                                               ` Jeff Law
  2015-11-24 17:13                                             ` Paul_Koning
  1 sibling, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-24  2:22 UTC (permalink / raw)
  To: David Wohlferd
  Cc: Paul_Koning, law, aph, rth, jakub, gcc, rth, pinskia, sandra

On Mon, Nov 23, 2015 at 05:39:17PM -0800, David Wohlferd wrote:
> On 11/23/2015 1:44 PM, Paul_Koning@Dell.com wrote:
> >>On Nov 23, 2015, at 4:36 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
> >>
> >>...
> >>>The more I think about it, I'm just not keen on forcing all those 
> >>>old-style asms to change.
> >>If you mean you aren't keen to change them to "clobber all," I'm with 
> >>you.  If you are worried about changing them from basic to extended, what 
> >>kinds of problems do you foresee?  I've been reading a lot of basic asm 
> >>lately, and it seems to me that most of it would be fine with a simple 
> >>colon.  Certainly no worse than the current behavior.
> >I'm not sure.  I have some asm("sync") which I think assume that this 
> >means asm("sync"::"memory")
> 
> Another excellent reason to nudge people towards using extended asm.  If 
> you saw asm("sync":::"memory"), you would *know* what it did, without 
> having to read the docs (which don't say anyway).
> 
> I'm pretty confident that asm("") doesn't clobber memory on i386, but 
> maybe that behavior is platform-specific.  Since i386 doesn't have 
> "sync", I assume you are on something else?
> 
> If you have a chance to experiment, I'd love confirmation from other 
> platforms that asm("blah") is the same as asm("blah":).  Feel free to 
> email me off list to discuss.

The extended asm one is "asm_operands", the basic asm one is "asm_input".
There are places where those are handled differently.  If any of that
matters, who knows.

Here is a test that shows that on at least PowerPC the basic asm is
identical to the extended asm without clobber (compile with -O2 -S and
-fno-ipa-icf if you want to have it easier to read).  In this case,
the basic asm is treated as not clobbering memory at the tree level
already, before expanding to RTL.


Segher


===
int a;

void ext_m(void)
{
        int t = a;
        a = 42;
        asm("lolz" : : : "memory");
        a = t;
}

void ext(void)
{
        int t = a;
        a = 42;
        asm("lolz" :);
        a = t;
}

void bas(void)
{
        int t = a;
        a = 42;
        asm("lolz");
        a = t;
}
===

PowerPC output (-m32, redacted):

ext_m:
        lis 9,a@ha
        li 8,42
        lwz 10,a@l(9)
        stw 8,a@l(9)
        lolz
        stw 10,a@l(9)
        blr

ext:
        lolz
        blr

bas:
        lolz
        blr

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24  2:22                                             ` Segher Boessenkool
@ 2015-11-24  4:48                                               ` Jeff Law
  2015-11-24  5:12                                                 ` Segher Boessenkool
  0 siblings, 1 reply; 58+ messages in thread
From: Jeff Law @ 2015-11-24  4:48 UTC (permalink / raw)
  To: Segher Boessenkool, David Wohlferd
  Cc: Paul_Koning, aph, rth, jakub, gcc, rth, pinskia, sandra

On 11/23/2015 07:22 PM, Segher Boessenkool wrote:
>
> Here is a test that shows that on at least PowerPC the basic asm is
> identical to the extended asm without clobber (compile with -O2 -S and
> -fno-ipa-icf if you want to have it easier to read).  In this case,
> the basic asm is treated as not clobbering memory at the tree level
> already, before expanding to RTL.
And that IMHO, ought to be considered a bug.

Jeff

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24  4:48                                               ` Jeff Law
@ 2015-11-24  5:12                                                 ` Segher Boessenkool
  2015-11-24  5:25                                                   ` Jeff Law
  0 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-24  5:12 UTC (permalink / raw)
  To: Jeff Law
  Cc: David Wohlferd, Paul_Koning, aph, rth, jakub, gcc, rth, pinskia, sandra

On Mon, Nov 23, 2015 at 09:48:42PM -0700, Jeff Law wrote:
> On 11/23/2015 07:22 PM, Segher Boessenkool wrote:
> >
> >Here is a test that shows that on at least PowerPC the basic asm is
> >identical to the extended asm without clobber (compile with -O2 -S and
> >-fno-ipa-icf if you want to have it easier to read).  In this case,
> >the basic asm is treated as not clobbering memory at the tree level
> >already, before expanding to RTL.
> And that IMHO, ought to be considered a bug.

I agree.  Almost everyone does, as far as I can see.

The question is if we want to retain this functionality.  No one has
depended on this in a long time -- they couldn't, it has been broken
since forever -- and there is another mechanism that does reliably
give this functionality (extended asm).

The first pass that goes wrong for this testcase is fre2, fwiw.


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24  5:12                                                 ` Segher Boessenkool
@ 2015-11-24  5:25                                                   ` Jeff Law
  0 siblings, 0 replies; 58+ messages in thread
From: Jeff Law @ 2015-11-24  5:25 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: David Wohlferd, Paul_Koning, aph, rth, jakub, gcc, rth, pinskia, sandra

On 11/23/2015 10:12 PM, Segher Boessenkool wrote:
> On Mon, Nov 23, 2015 at 09:48:42PM -0700, Jeff Law wrote:
>> On 11/23/2015 07:22 PM, Segher Boessenkool wrote:
>>>
>>> Here is a test that shows that on at least PowerPC the basic asm is
>>> identical to the extended asm without clobber (compile with -O2 -S and
>>> -fno-ipa-icf if you want to have it easier to read).  In this case,
>>> the basic asm is treated as not clobbering memory at the tree level
>>> already, before expanding to RTL.
>> And that IMHO, ought to be considered a bug.
>
> I agree.  Almost everyone does, as far as I can see.
>
> The question is if we want to retain this functionality.  No one has
> depended on this in a long time -- they couldn't, it has been broken
> since forever -- and there is another mechanism that does reliably
> give this functionality (extended asm).
>
> The first pass that goes wrong for this testcase is fre2, fwiw.
I think that's the wrong way to look at things -- it's not that nobody 
is depending on this behaviour, it's nobody has had a problem due to 
this bug.

I've seen some amazing things through the years where you'd think 
there's absolutely no way they could work -- but they did for a long 
time with nobody noticing some absolutely horridly wrong code, that when 
tickled just right would wreck havoc.

So again, I would suggest we document the desired behaviour and work 
towards fixing any deviations from that behaviour.

jeff


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-23 21:03                                     ` David Wohlferd
@ 2015-11-24  9:48                                       ` Andrew Haley
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Haley @ 2015-11-24  9:48 UTC (permalink / raw)
  To: David Wohlferd, Richard Henderson, Jakub Jelinek
  Cc: Segher Boessenkool, Jeff Law, gcc, rth, pinskia, Sandra Loosemore

On 23/11/15 21:02, David Wohlferd wrote:
>> On 11/23/2015 2:04 AM, Andrew Haley wrote:
>> > My warning still holds: there are modes of compilation on some
>> > machines where you can't clobber all registers without causing reload
>> > failures.  This is why Jeff didn't fix this in 1999.  So, if we really
>> > do want to clobber "all" registers in basic asm it'll take a lot of
>> > work.
>
> I was always reluctant to see this change made.  In addition to the 
> issues you mention, I had questions about the impact on the surrounding 
> code.  I like Richard's direction much better.  We can start with a 
> disabled warning, then upgrade as seems warranted.

I don't see any problem with unconditionally clobbering memory.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24  1:39                                           ` David Wohlferd
  2015-11-24  2:22                                             ` Segher Boessenkool
@ 2015-11-24 17:13                                             ` Paul_Koning
  2015-11-24 17:49                                               ` Ian Lance Taylor
  2015-11-25  2:11                                               ` David Wohlferd
  1 sibling, 2 replies; 58+ messages in thread
From: Paul_Koning @ 2015-11-24 17:13 UTC (permalink / raw)
  To: dw; +Cc: gcc


> On Nov 23, 2015, at 8:39 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
> 
> On 11/23/2015 1:44 PM, Paul_Koning@Dell.com wrote:
>>> On Nov 23, 2015, at 4:36 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
>>> 
>>> ...
>>>> The more I think about it, I'm just not keen on forcing all those old-style asms to change.
>>> If you mean you aren't keen to change them to "clobber all," I'm with you.  If you are worried about changing them from basic to extended, what kinds of problems do you foresee?  I've been reading a lot of basic asm lately, and it seems to me that most of it would be fine with a simple colon.  Certainly no worse than the current behavior.
>> I'm not sure.  I have some asm("sync") which I think assume that this means asm("sync"::"memory")
> 
> Another excellent reason to nudge people towards using extended asm.  If you saw asm("sync":::"memory"), you would *know* what it did, without having to read the docs (which don't say anyway).
> 
> I'm pretty confident that asm("") doesn't clobber memory on i386, but maybe that behavior is platform-specific.  Since i386 doesn't have "sync", I assume you are on something else?

Yes, MIPS.
> 
> If you have a chance to experiment, I'd love confirmation from other platforms that asm("blah") is the same as asm("blah":).  Feel free to email me off list to discuss.

I'm really concerned with loosening the meaning of basic asm.  I wish I could find the documentation that says, or implies, that it is a memory clobber.  And/or that it is implicitly volatile.

The problem is that it's clear from existing code that this assumption was made, and that defining it otherwise would break such code.  For example, the code I quoted clearly won't work if stores are moved across the asm("sync").

Given the ever improving optimizers, these things are time bombs -- code that worked for years might suddenly break when the compiler is upgraded.

If such breakage is to be done, it must at least come with a warning (which must default to ON).  But I'd prefer to see the more conservative approach (more clobbers) taken.

	paul

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24 17:13                                             ` Paul_Koning
@ 2015-11-24 17:49                                               ` Ian Lance Taylor
  2015-11-24 18:00                                                 ` Paul_Koning
  2015-11-25  2:11                                               ` David Wohlferd
  1 sibling, 1 reply; 58+ messages in thread
From: Ian Lance Taylor @ 2015-11-24 17:49 UTC (permalink / raw)
  To: Paul_Koning; +Cc: David Wohlferd, GCC Development

On Tue, Nov 24, 2015 at 8:58 AM,  <Paul_Koning@dell.com> wrote:
>
> I'm really concerned with loosening the meaning of basic asm.  I
> wish I could find the documentation that says, or implies, that it
> is a memory clobber.  And/or that it is implicitly volatile.

The volatile one is right there in the current docs.

https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm

"All basic asm blocks are implicitly volatile."

Even back in GCC 2.95.3, the docs say
(https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC93) "If you
write an asm instruction with no outputs, GNU CC will know the
instruction has side-effects and will not delete the instruction or
move it outside of loops" and "An asm instruction without any operands
or clobbers (and "old style" asm) will not be deleted or moved
significantly, regardless, unless it is unreachable, the same wasy as
if you had written a volatile keyword."

However, I'm not aware that basic asm's were ever implicitly memory
clobbers.  Again, back in GCC 2.95.3: "If your assembler instruction
modifies memory in an unpredictable fashion, add `memory' to the list
of clobbered registers."

Ian

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24 17:49                                               ` Ian Lance Taylor
@ 2015-11-24 18:00                                                 ` Paul_Koning
  0 siblings, 0 replies; 58+ messages in thread
From: Paul_Koning @ 2015-11-24 18:00 UTC (permalink / raw)
  To: iant; +Cc: dw, gcc


> On Nov 24, 2015, at 12:49 PM, Ian Lance Taylor <iant@google.com> wrote:
> 
> On Tue, Nov 24, 2015 at 8:58 AM,  <Paul_Koning@dell.com> wrote:
>> 
>> I'm really concerned with loosening the meaning of basic asm.  I
>> wish I could find the documentation that says, or implies, that it
>> is a memory clobber.  And/or that it is implicitly volatile.
> 
> The volatile one is right there in the current docs.
> 
> https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm
> 
> "All basic asm blocks are implicitly volatile."

Ok, that's what I remembered.  I reported finding that this was not implemented correctly, some number of versions ago.

	paul

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-24 17:13                                             ` Paul_Koning
  2015-11-24 17:49                                               ` Ian Lance Taylor
@ 2015-11-25  2:11                                               ` David Wohlferd
  2015-11-25  9:09                                                 ` Andrew Haley
  1 sibling, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-25  2:11 UTC (permalink / raw)
  To: Paul_Koning; +Cc: gcc, Ian Lance Taylor

On 11/24/2015 8:58 AM, Paul_Koning@Dell.com wrote:
>> On Nov 23, 2015, at 8:39 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
>>
>> On 11/23/2015 1:44 PM, Paul_Koning@Dell.com wrote:
>>>> On Nov 23, 2015, at 4:36 PM, David Wohlferd <dw@LimeGreenSocks.com> wrote:
>>>>
>>>> ...
>>>>> The more I think about it, I'm just not keen on forcing all those old-style asms to change.
>>>> If you mean you aren't keen to change them to "clobber all," I'm with you.  If you are worried about changing them from basic to extended, what kinds of problems do you foresee?  I've been reading a lot of basic asm lately, and it seems to me that most of it would be fine with a simple colon.  Certainly no worse than the current behavior.
>>> I'm not sure.  I have some asm("sync") which I think assume that this means asm("sync"::"memory")
>> Another excellent reason to nudge people towards using extended asm.  If you saw asm("sync":::"memory"), you would *know* what it did, without having to read the docs (which don't say anyway).
>>
>> I'm pretty confident that asm("") doesn't clobber memory on i386, but maybe that behavior is platform-specific.  Since i386 doesn't have "sync", I assume you are on something else?
> Yes, MIPS.
>> If you have a chance to experiment, I'd love confirmation from other platforms that asm("blah") is the same as asm("blah":).  Feel free to email me off list to discuss.
> I'm really concerned with loosening the meaning of basic asm.  I wish I could find the documentation that says, or implies, that it is a memory clobber.  And/or that it is implicitly volatile.
>
> The problem is that it's clear from existing code that this assumption was made, and that defining it otherwise would break such code.  For example, the code I quoted clearly won't work if stores are moved across the asm("sync").
>
> Given the ever improving optimizers, these things are time bombs -- code that worked for years might suddenly break when the compiler is upgraded.
>
> If such breakage is to be done, it must at least come with a warning (which must default to ON).  But I'd prefer to see the more conservative approach (more clobbers) taken.

It looks like Ian has already addressed most of your concerns.  Just to 
emphasize one point:

The current behavior of basic asm is to NOT clobber memory.  So your 
existing code that performs asm("sync") is already at risk.

The 'fix' I am proposing is to give warnings for every use of basic asm 
inside functions (top-level asm is not a problem).  Users should change 
all such code to use extended so that they can (must) explicitly specify 
what their asm clobbers (if anything).  Armed with this information, the 
optimizers can do their work safely.  And people maintaining the code 
can finally be clear about what the asm really does.

And the code change should be simple.  They can get the same "clobber 
nothing" behavior that basic asm has always performed by simply adding a 
colon on the end ( asm("sync":) ).  Or they can use any of extended 
asm's features to get different behavior ( asm("sync":::"memory") ).

Or to put that another way, correctly written basic asm can be converted 
to extended by just adding a colon.  Incorrect code may require a bit 
more work.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-25  2:11                                               ` David Wohlferd
@ 2015-11-25  9:09                                                 ` Andrew Haley
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Haley @ 2015-11-25  9:09 UTC (permalink / raw)
  To: David Wohlferd, Paul_Koning; +Cc: gcc, Ian Lance Taylor

On 25/11/15 02:11, David Wohlferd wrote:
> The 'fix' I am proposing is to give warnings for every use of basic asm 
> inside functions (top-level asm is not a problem).

I'm not sure that's such a great idea on its own.

My suggestion:

1.  Clobber memory.

2.  Document a rule which says that all registers which are used must be
    saved and restored.

This won't break any existing usages, and is AFAICS entirely in the spirit
of what was originally intended and with the ISO C specification.

Andrew.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 13:05                     ` Richard Henderson
  2015-11-20 15:20                       ` Segher Boessenkool
  2015-11-20 18:24                       ` Jeff Law
@ 2015-11-26 10:30                       ` Hans-Peter Nilsson
  2015-11-26 12:35                         ` Segher Boessenkool
  2 siblings, 1 reply; 58+ messages in thread
From: Hans-Peter Nilsson @ 2015-11-26 10:30 UTC (permalink / raw)
  To: Richard Henderson
  Cc: David Wohlferd, Andrew Haley, Jeff Law, Segher Boessenkool, gcc,
	rth, pinskia, Sandra Loosemore

On Fri, 20 Nov 2015, Richard Henderson wrote:
> I'd be perfectly happy to deprecate and later completely remove basic asm
> within functions.

We've explictly promised (directed to kernel people IIRC) that
the empty basic asm; 'asm ("")', has forward-compatible
outlining magic, so people would not have to keep adding
ever-new attributes like noinline,noclone to avoid finding their
functions "spilling over", so please exclude that.  To wit, from
extend.texi:

@item noinline
@cindex @code{noinline} function attribute
This function attribute prevents a function from being considered for
inlining.
@c Don't enumerate the optimizations by name here; we try to be
@c future-compatible with this mechanism.
If the function does not have side-effects, there are optimizations
other than inlining that cause function calls to be optimized away,
although the function call is live.  To keep such calls from being
optimized away, put
@smallexample
asm ("");
@end smallexample

@noindent
(@pxref{Extended Asm}) in the called function, to serve as a
special
side-effect.

brgds, H-P

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-26 10:30                       ` Hans-Peter Nilsson
@ 2015-11-26 12:35                         ` Segher Boessenkool
  2015-11-26 16:26                           ` Hans-Peter Nilsson
  0 siblings, 1 reply; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-26 12:35 UTC (permalink / raw)
  To: Hans-Peter Nilsson
  Cc: Richard Henderson, David Wohlferd, Andrew Haley, Jeff Law, gcc,
	rth, pinskia, Sandra Loosemore

On Thu, Nov 26, 2015 at 05:30:48AM -0500, Hans-Peter Nilsson wrote:
> On Fri, 20 Nov 2015, Richard Henderson wrote:
> > I'd be perfectly happy to deprecate and later completely remove basic asm
> > within functions.
> 
> We've explictly promised (directed to kernel people IIRC) that
> the empty basic asm; 'asm ("")', has forward-compatible
> outlining magic, so people would not have to keep adding
> ever-new attributes like noinline,noclone to avoid finding their
> functions "spilling over", so please exclude that.  To wit, from
> extend.texi:
> 
> @item noinline
> @cindex @code{noinline} function attribute
> This function attribute prevents a function from being considered for
> inlining.
> @c Don't enumerate the optimizations by name here; we try to be
> @c future-compatible with this mechanism.
> If the function does not have side-effects, there are optimizations
> other than inlining that cause function calls to be optimized away,
> although the function call is live.  To keep such calls from being
> optimized away, put
> @smallexample
> asm ("");
> @end smallexample
> 
> @noindent
> (@pxref{Extended Asm}) in the called function, to serve as a
> special
> side-effect.

Any asm without outputs (including basic asm) is volatile, so it can
not be optimised away.  Putting an empty asm in a noinline function
should always work as you want, it's not because it is basic asm.


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-26 12:35                         ` Segher Boessenkool
@ 2015-11-26 16:26                           ` Hans-Peter Nilsson
  2015-11-26 21:54                             ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Hans-Peter Nilsson @ 2015-11-26 16:26 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Richard Henderson, David Wohlferd, Andrew Haley, Jeff Law, gcc,
	rth, pinskia, Sandra Loosemore

On Thu, 26 Nov 2015, Segher Boessenkool wrote:
> On Thu, Nov 26, 2015 at 05:30:48AM -0500, Hans-Peter Nilsson wrote:
> > On Fri, 20 Nov 2015, Richard Henderson wrote:
> > > I'd be perfectly happy to deprecate and later completely remove basic asm
> > > within functions.
> >
> > We've explictly promised (directed to kernel people IIRC) that
> > the empty basic asm; 'asm ("")', has forward-compatible
> > outlining magic, so people would not have to keep adding
> > ever-new attributes like noinline,noclone to avoid finding their
> > functions "spilling over", so please exclude that.  To wit, from
> > extend.texi:
> >
> > @item noinline
> > @cindex @code{noinline} function attribute
> > This function attribute prevents a function from being considered for
> > inlining.
> > @c Don't enumerate the optimizations by name here; we try to be
> > @c future-compatible with this mechanism.
> > If the function does not have side-effects, there are optimizations
> > other than inlining that cause function calls to be optimized away,
> > although the function call is live.  To keep such calls from being
> > optimized away, put
> > @smallexample
> > asm ("");
> > @end smallexample
> >
> > @noindent
> > (@pxref{Extended Asm}) in the called function, to serve as a
> > special
> > side-effect.
>
> Any asm without outputs (including basic asm) is volatile, so it can
> not be optimised away.  Putting an empty asm in a noinline function
> should always work as you want, it's not because it is basic asm.

I know, the point is that we've promised the above and we
shouldn't back down on this mechanism to instead deprecate and
warn about it, as seems to be the direction.

This happens to be expressed as a basic asm and was chosen
because the right things happen regarding backwards-
compatibility.  More care has to be taken for forward-
compatibility.  I'm a bit worried that it still works only
because of happenstance.

I know what (I hope) you're thinking but it's hard to produce a
test-case that fails when a future yet unknown optimization
causes "spill-over", but I can imagine a quick return-path
seeming inlinable in LTO.

brgds, H-P

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-26 16:26                           ` Hans-Peter Nilsson
@ 2015-11-26 21:54                             ` David Wohlferd
  2015-11-26 23:39                               ` Hans-Peter Nilsson
  0 siblings, 1 reply; 58+ messages in thread
From: David Wohlferd @ 2015-11-26 21:54 UTC (permalink / raw)
  To: Hans-Peter Nilsson, Segher Boessenkool
  Cc: Richard Henderson, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On 11/26/2015 8:26 AM, Hans-Peter Nilsson wrote:
> On Thu, 26 Nov 2015, Segher Boessenkool wrote:
>> On Thu, Nov 26, 2015 at 05:30:48AM -0500, Hans-Peter Nilsson wrote:
>>> On Fri, 20 Nov 2015, Richard Henderson wrote:
>>>> I'd be perfectly happy to deprecate and later completely remove basic asm
>>>> within functions.
>>> We've explictly promised (directed to kernel people IIRC) that
>>> the empty basic asm; 'asm ("")', has forward-compatible
>>> outlining magic, so people would not have to keep adding
>>> ever-new attributes like noinline,noclone to avoid finding their
>>> functions "spilling over", so please exclude that.  To wit, from
>>> extend.texi:
>>>
>>> @item noinline
>>> @cindex @code{noinline} function attribute
>>> This function attribute prevents a function from being considered for
>>> inlining.
>>> @c Don't enumerate the optimizations by name here; we try to be
>>> @c future-compatible with this mechanism.
>>> If the function does not have side-effects, there are optimizations
>>> other than inlining that cause function calls to be optimized away,
>>> although the function call is live.  To keep such calls from being
>>> optimized away, put
>>> @smallexample
>>> asm ("");
>>> @end smallexample
>>>
>>> @noindent
>>> (@pxref{Extended Asm}) in the called function, to serve as a
>>> special
>>> side-effect.
>> Any asm without outputs (including basic asm) is volatile, so it can
>> not be optimised away.  Putting an empty asm in a noinline function
>> should always work as you want, it's not because it is basic asm.
> I know, the point is that we've promised the above and we
> shouldn't back down on this mechanism to instead deprecate and
> warn about it, as seems to be the direction.

That is indeed the direction I am heading unless someone stops me.

I was not aware of this magic.  Thanks for pointing it out.  To be 
clear, wouldn't asm("":) have the same effect?

Since we have committed to this, we don't want to change it lightly.  
Also, looking at existing inline asm, this is probably one of the most 
common uses.  Allowing this exception will probably ease the migration, 
even if it makes the docs a little clunkier.

So how about this:

1) Change the docs to say asm("":), so future coders will do "the right 
thing."
2) Allow the exception for v6.
3) Re-evaluate if-and-when we continue with the deprecation process.

> This happens to be expressed as a basic asm and was chosen
> because the right things happen regarding backwards-
> compatibility.  More care has to be taken for forward-
> compatibility.  I'm a bit worried that it still works only
> because of happenstance.
>
> I know what (I hope) you're thinking but it's hard to produce a
> test-case that fails when a future yet unknown optimization
> causes "spill-over", but I can imagine a quick return-path
> seeming inlinable in LTO.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-26 21:54                             ` David Wohlferd
@ 2015-11-26 23:39                               ` Hans-Peter Nilsson
  2015-11-27  1:04                                 ` David Wohlferd
  0 siblings, 1 reply; 58+ messages in thread
From: Hans-Peter Nilsson @ 2015-11-26 23:39 UTC (permalink / raw)
  To: David Wohlferd
  Cc: Segher Boessenkool, Richard Henderson, Andrew Haley, Jeff Law,
	gcc, rth, pinskia, Sandra Loosemore

On Thu, 26 Nov 2015, David Wohlferd wrote:
> On 11/26/2015 8:26 AM, Hans-Peter Nilsson wrote:
> > On Thu, 26 Nov 2015, Segher Boessenkool wrote:
> > > On Thu, Nov 26, 2015 at 05:30:48AM -0500, Hans-Peter Nilsson wrote:
> > > > @item noinline
...
> > > > asm ("");
...
> > I know, the point is that we've promised the above and we
> > shouldn't back down on this mechanism to instead deprecate and
> > warn about it, as seems to be the direction.
>
> That is indeed the direction I am heading unless someone stops me.
>
> I was not aware of this magic.  Thanks for pointing it out.  To be clear,
> wouldn't asm("":) have the same effect?

That does not matter.  It'd require source-code changes to
users' code.  BTW, does that syntax work for really olden gcc
(say 2.95 era)?  Either way, we promised 'asm("")'.  I'm pretty
sure the empty string is identifiable.  Whatever happens to
register-clobbering effects (wrt. this being expressed as a
"basic asm") is less interesting; it can be made the same as
'asm("":)' whenever any actual-basic-asm-deprecation is
complete, IIUC.

I have no issue with any *actual* basic asm changes.  That might
be a good idea, modulo standards issues of course (IIUC it's
optional in *some* ISO/ANSI standards, but better check all
applicable versions).

> Since we have committed to this, we don't want to change it lightly.

Right.  I don't understand why we couldn't except this
particular thing from actual-basic-asm-deprecation.  FWIW, I see
the point in making sure 'asm("":)' does the same, for syntax
consistency, but I wouldn't call that syntax "the right thing".

brgds, H-P

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-26 23:39                               ` Hans-Peter Nilsson
@ 2015-11-27  1:04                                 ` David Wohlferd
  0 siblings, 0 replies; 58+ messages in thread
From: David Wohlferd @ 2015-11-27  1:04 UTC (permalink / raw)
  To: Hans-Peter Nilsson
  Cc: Segher Boessenkool, Richard Henderson, Andrew Haley, Jeff Law,
	gcc, rth, pinskia, Sandra Loosemore

 >> To be clear, wouldn't asm("":) have the same effect?
 >
 > That does not matter.  It'd require source-code changes to
 > users' code.

My suggestion was to allow the exception to the "basic asm in a 
function" warning, but change the docs to show using the new syntax.  
This does not require any user code change.  But it kinda does matter 
whether or not it will work.

Copy/pasting my suggestion:

1) Change the docs to say asm("":), so future coders will do "the right 
thing."
2) Allow the exception for v6.
3) Re-evaluate if-and-when we continue with the deprecation process.

It may not be clear from this, but I don't expect step 3 to happen until 
at least v7.

And saying "the right thing" may be a bit flip.  But if deprecating 
basic asm is the path we are choosing, then telling users to use this 
syntax is how the text should read.  Assuming it works.

 > BTW, does that syntax work for really olden gcc
 > (say 2.95 era)?

The oldest docs I can find are 2.95.3, and they talk about the extended 
asm syntax, so I assume so: 
https://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC93

 > Either way, we promised 'asm("")'.  I'm pretty
 > sure the empty string is identifiable.

It is.  I've already updated my code to support this exception.

dw

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: basic asm and memory clobbers
  2015-11-20 15:30                         ` Richard Henderson
  2015-11-20 15:34                           ` Jakub Jelinek
  2015-11-20 16:21                           ` Segher Boessenkool
@ 2015-11-27 17:45                           ` Segher Boessenkool
  2 siblings, 0 replies; 58+ messages in thread
From: Segher Boessenkool @ 2015-11-27 17:45 UTC (permalink / raw)
  To: Richard Henderson
  Cc: David Wohlferd, Andrew Haley, Jeff Law, gcc, rth, pinskia,
	Sandra Loosemore

On Fri, Nov 20, 2015 at 04:29:50PM +0100, Richard Henderson wrote:
> On 11/20/2015 04:20 PM, Segher Boessenkool wrote:
> >Should  asm("bla");  then be an extended asm with no input, no outputs,
> >no (non-automatic) clobbers?  That would be the most straightforward and
> >logical semantics, but will it break user code?
> 
> I'm suggesting that we don't accept that at all inside a function.  One 
> must audit the source and make a conscious decision to write asm("bla" : ); 
> instead.

I have now audited all code involving RTL's ASM_INPUT (i.e. the basic asm),
and those work identically to zero-operand no-clobber volatile ASM_OPERANDS
(i.e., extended asm) everywhere.  Well, two exceptions: the mep port does
not handle that second form (which can never happen currently), and the
ia64 port treats the two forms differently for its placing of stop bits.

So as far as RTL is concerned, we do not need to force users' source code
changes for transitioning to "no more basic asm".

Now looking at what happens before RTL...  probably more exciting ;-)


Segher

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2015-11-27 17:45 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-09  0:10 basic asm and memory clobbers David Wohlferd
2015-11-09  9:32 ` Segher Boessenkool
2015-11-16  1:23   ` David Wohlferd
2015-11-16 21:29     ` Jeff Law
2015-11-17  5:56       ` David Wohlferd
2015-11-17  9:27         ` Andrew Haley
2015-11-17 21:31         ` Jeff Law
2015-11-17 22:07           ` Andrew Pinski
2015-11-18 22:04             ` Jeff Law
2015-11-18  1:28           ` Segher Boessenkool
2015-11-18 22:08             ` Jeff Law
2015-11-20  1:24           ` David Wohlferd
2015-11-20  1:53             ` Sandra Loosemore
2015-11-22  5:09               ` David Wohlferd
2015-11-20  3:14             ` Segher Boessenkool
2015-11-20 10:45               ` David Wohlferd
2015-11-20 14:56                 ` Segher Boessenkool
2015-11-20 20:01                   ` Jeff Law
2015-11-20 22:07                     ` Paul_Koning
2015-11-20 10:17             ` Andrew Haley
2015-11-20 10:38               ` David Wohlferd
2015-11-20 11:14                 ` Andrew Haley
2015-11-20 12:38                   ` David Wohlferd
2015-11-20 13:05                     ` Richard Henderson
2015-11-20 15:20                       ` Segher Boessenkool
2015-11-20 15:30                         ` Richard Henderson
2015-11-20 15:34                           ` Jakub Jelinek
2015-11-20 16:14                             ` Richard Henderson
2015-11-20 23:56                               ` David Wohlferd
2015-11-21 12:57                                 ` David Wohlferd
2015-11-23  9:56                                   ` Joseph Myers
2015-11-23 10:04                                   ` Andrew Haley
2015-11-23 20:37                                     ` Jeff Law
2015-11-23 21:36                                       ` David Wohlferd
2015-11-23 21:44                                         ` Paul_Koning
2015-11-24  1:39                                           ` David Wohlferd
2015-11-24  2:22                                             ` Segher Boessenkool
2015-11-24  4:48                                               ` Jeff Law
2015-11-24  5:12                                                 ` Segher Boessenkool
2015-11-24  5:25                                                   ` Jeff Law
2015-11-24 17:13                                             ` Paul_Koning
2015-11-24 17:49                                               ` Ian Lance Taylor
2015-11-24 18:00                                                 ` Paul_Koning
2015-11-25  2:11                                               ` David Wohlferd
2015-11-25  9:09                                                 ` Andrew Haley
2015-11-23 21:03                                     ` David Wohlferd
2015-11-24  9:48                                       ` Andrew Haley
2015-11-20 16:21                           ` Segher Boessenkool
2015-11-27 17:45                           ` Segher Boessenkool
2015-11-20 18:24                       ` Jeff Law
2015-11-20 19:39                         ` Paul_Koning
2015-11-26 10:30                       ` Hans-Peter Nilsson
2015-11-26 12:35                         ` Segher Boessenkool
2015-11-26 16:26                           ` Hans-Peter Nilsson
2015-11-26 21:54                             ` David Wohlferd
2015-11-26 23:39                               ` Hans-Peter Nilsson
2015-11-27  1:04                                 ` David Wohlferd
2015-11-20 16:41                   ` Jeff Law

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).