GDC optimizations bug ?
Maor via D.gnu
d.gnu at puremagic.com
Sun Nov 9 06:20:56 PST 2014
On Sunday, 9 November 2014 at 11:50:24 UTC, Iain Buclaw via D.gnu
wrote:
> On 9 November 2014 08:54, Iain Buclaw <ibuclaw at gdcproject.org>
> wrote:
>>
>> On 9 Nov 2014 08:40, "Maor via D.gnu" <d.gnu at puremagic.com>
>> wrote:
>>>
>>> Hi,
>>>
>>> I'm trying to compile a program using inline asm with
>>> optimizations and I
>>> got my inline asm functions thrown out by the optimizer
>>> although I declared
>>> them as having side effects (by stating a memory clobber).
>>> I wrote the following toy program to demonstrate the problem:
>>>
>>> ----------------------------------------------
>>>
>>> import std.stdio;
>>> import gcc.attribute;
>>>
>>> @attribute("forceinline") ulong exchangeAndAdd(shared ulong
>>> *counter,
>>> ulong addition) {
>>> ulong retVal = void; // we don't want it initialized
>>> when dmd is
>>> used
>>> asm {
>>> "
>>> mov %2, %0 ;
>>> lock ;
>>> xadd %0, (%1) ;
>>> ":
>>> "=&r"(retVal) :
>>> "r"(counter), "r"(addition) :
>>
>> Maybe try: "=m"(*counter)
>>
>> The bug is likely in your input/output clobbers, gcc will
>> always optimise
>> against you unless you get the input/output/clobbers precisely
>> correct.
>
> Yep, it looks like using (%1) -> "r"(counter) creates a
> temporary in
> the register but never binds back. The optimiser sees that
> memory is
> clobbered, but non of the operands have memory side effects.
>
> Telling gcc that this is a memory operand fixes it - %1 ->
> "m"(counter). But I think that having counter as an input
> operand is
> wrong, as it *has* infact a new value written to it. You can
> also
> omit the 'mov' instruction by telling gcc the "0" register
> should be
> loaded with the input "addition"
>
> Your fixed (and simplified) assembler statement now becomes:
>
>
> @attribute("forceinline") ulong exchangeAndAdd(shared ulong
> *counter,
> ulong addition) {
> ulong retVal = void; // we don't want it initialized when
> dmd is used
> asm {
> "
> lock ;
> xadd %0, %1 ;
> " :
> "=r"(retVal), "=m"(*counter) :
> "0"(addition) :
> "memory";
> }
> return retVal;
> }
Hi,
Thanks for the tip!
Indeed, it solves the problem (which uncovered another one, but
one which deserves a different subject :)
Cheers,
Maor
More information about the D.gnu
mailing list