GDC optimizations bug ?

Iain Buclaw via D.gnu d.gnu at puremagic.com
Sun Nov 9 03:50:08 PST 2014


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;
}


More information about the D.gnu mailing list