<html>
    <head>
      <base href="http://bugzilla.gdcproject.org/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Wrong codegen is used for <OP>= expressions when there is a function as part of the rvalue."
   href="http://bugzilla.gdcproject.org/show_bug.cgi?id=185">185</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Wrong codegen is used for <OP>= expressions when there is a function as part of the rvalue.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>GDC
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>4.9.x
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>x86_64
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>blocker
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>Normal
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>gdc
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>ibuclaw@gdcproject.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>liran@weka.io
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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. (-=, ...)
"""</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are watching all bug changes.</li>
      </ul>
    </body>
</html>