[Bug 185] New: Wrong codegen is used for <OP>= expressions when there is a function as part of the rvalue.

via D.gnu d.gnu at puremagic.com
Fri May 15 03:03:35 PDT 2015


http://bugzilla.gdcproject.org/show_bug.cgi?id=185

            Bug ID: 185
           Summary: Wrong codegen is used for <OP>= expressions when there
                    is a function as part of the rvalue.
           Product: GDC
           Version: 4.9.x
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: blocker
          Priority: Normal
         Component: gdc
          Assignee: ibuclaw at gdcproject.org
          Reporter: liran at weka.io

Initially issue was found in a large Fiber based application, and narrowed down
to use the += operation around functions that later call yield.
The code was:

-----------------
import std.stdio;
import core.thread;

enum numAddition = 3;
long globalSum = 0;

class DerivedFiber : Fiber
{
   int index;
   this(int _index)
   {
       index = _index;
       super( &run );
   }

private :
   void run()
   {
       foreach(int k; 0 .. numAddition) {
           globalSum += otherFunc();
           writefln("DerivedFiber(%d) iteration %d globalSum is %d", index, k,
globalSum);
       }
   }

   long otherFunc() {
       yield();
       return index;
   }
}

int main()
{
   Fiber derived1 = new DerivedFiber(1);
   Fiber derived2 = new DerivedFiber(2);

   foreach(j; 0 .. (numAddition+1)) {
       derived1.call();
       derived2.call();
   }

   assert(globalSum == (1+2)*numAddition);
   return 0;
}
-------------------------
And the problem was that the compiler cached the globalSum value before the
yield, so concurrent changes were not possible.

Later, Johannes Pfau showed that generally <OP>= caches the "origin" even if
calling functions from other modules that may change the value without use of
fibers and yield at all.

"""
Iain: I think our codegen might be wrong. -fdump-tree-original:

@61     var_decl         name: @76      mngl: @77      type: @60     
                        scpe: @54      srcp: test.d:5      
                        size: @39      algn: 64       used: 1 
@62     plus_expr        type: @60      op 0: @61      op 1: @78
@78     call_expr        type: @60      fn  : @96      0   : @23

Does GCC guarantee an evaluation order for plus_expr? This is
kinda weird btw. The rewrite might already happen in the frontend. If we
rewrite
globalSum += otherFunc();
to
globalSum = globalSum + otherFunc();
and follow strict LTR evaluation the code we generate is correct and
the code DMD generates is incorrect.

OTOH I don't know the exact rules for += but intuitively it should
first evaluate the RHS, then load the LHS.

"""


Then Iain Buclaw added:
"""
I can confirm that C codegen does infact emit 'foo += bar()'  as  'foo
= bar() + foo'

Which only strengthens the reasoning to change it.
.
.
.
For commutative operations we can simply change the operands. For
non-commutative operations we'll have to explicitly evaluate the side
effects of the RHS before assigning. (-=, ...)
"""

-- 
You are receiving this mail because:
You are watching all bug changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/d.gnu/attachments/20150515/f29f0cb9/attachment.html>


More information about the D.gnu mailing list