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