This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: basic asm and memory clobbers


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]