GDC generates invalid assembly around fiber yield operations (Not re-reading data from clobberedd memory to registers)
Johannes Pfau via D.gnu
d.gnu at puremagic.com
Thu May 14 10:02:48 PDT 2015
Am Thu, 14 May 2015 15:52:05 +0000
schrieb "Liran Zvibel" <liran at weka.io>:
> Hi,
>
> I forgot to mention is before, I'm running with GDC commit
> b022dd4cac195d85e9c3a6a37f2501a07ade455a from April 7th based on
> GCC 4.9.
>
> Does anyone have experience compiling (and then running) Fiber
> based applications with GDC?
> What are you doing?
>
> Is there a plan to add support for @attribute("returns_twice") to
> GDC?
>
> Thanks!
I can reproduce this using the latest master branch. This exact issue
is kinda weird: GCC can't cache the globalSum across a call to
otherFunc. otherFunc calls yield which is in a different module. yield
could modify the globalSum value and the generated code would be
invalid even without Fibers.
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.
Note: The issue the OP assumed is also worth discussing. It can't
happen with global variables, but a second Fiber could modify a local
variable. I'm not sure if it's possible to construct a case where GCC
legitimately assumes a variable can't escape and we modify it through
yield.
More information about the D.gnu
mailing list