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

Reply via email to