On Wed, Nov 18, 2015 at 5:31 AM, Jeff Law <l...@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