Summary: incorrect code generation for asm{ inc eax }
           Product: D
           Version: 2.022
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: DMD

The following code fails to assert.

import tango.core.Atomic;
void main(){
  int j;
  foreach (i; 1..500_000){
    atomicIncrement!(msync.raw, int)(j);
    assert(j == (i%256));

Digging deeper, this is a problem because the atomicIncrement is translated to
the following assembly.  Note the critical line of "lock incb" which should be
"lock inc"

 80496b4:       55                      push   %ebp
 80496b5:       8b ec                   mov    %esp,%ebp
 80496b7:       50                      push   %eax
 80496b8:       8b 45 fc                mov    -0x4(%ebp),%eax
 80496bb:       f0 fe 00                lock incb (%eax)
 80496be:       8b 00                   mov    (%eax),%eax
 80496c0:       8b e5                   mov    %ebp,%esp
 80496c2:       5d                      pop    %ebp
 80496c3:       c3                      ret    

Here's the original assembly in the Tango module:
  mov EAX, val;
  lock; // lock always needed to make this op atomic
  inc [EAX];
  mov EAX, [EAX];

This problem appears in both D1 and D2 and prevents lockless algorithms.


Reply via email to