<story><title>Cmd/compile: Go 1.8 regression: sync/atomic loop elided</title><url>https://github.com/golang/go/issues/19182</url></story><parent_chain><item><author>vessenes</author><text>This is interesting, actually.&lt;p&gt;As the language is specified, it&amp;#x27;s not wrong to just ignore that add completely -- the variable isn&amp;#x27;t used inside the goroutine, and you&amp;#x27;re not guaranteed a goroutine will run at any particular time.&lt;p&gt;So, code executed right after that routine is spawned will be hitting the &amp;#x27;old&amp;#x27; value anyway; hence Dvyukov&amp;#x27;s comments that this is arguably to spec, or within spec.&lt;p&gt;Think if you actually wrote this code; you&amp;#x27;d have some weird behavior if the compiler did what you &amp;#x27;expect&amp;#x27; - a couple outputs of low integers then some high ones as the goroutine gets scheduled in. So it&amp;#x27;s almost certainly just &amp;#x27;wrong&amp;#x27; to write something like this, under most (all?) circumstances.&lt;p&gt;Because sync.Wait() isn&amp;#x27;t used, there&amp;#x27;s no guarantee the goroutine will execute at all before program halt.&lt;p&gt;That said, I bet there&amp;#x27;s some related more reasonable scenario where you could argue the compiler should at least do the adding. I&amp;#x27;m not sure why atomic.Add* should get special treatment though, and it looks like the fix is to remove some escape-analysis type code, so I&amp;#x27;m curious how this will get fixed.</text></item></parent_chain><comment><author>alecrn</author><text>Yeah, this particular instance seems ok to me.  This one makes the example feel weirder:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  func main() {
  	runtime.GOMAXPROCS(runtime.NumCPU())
  	fmt.Println(runtime.NumCPU(), runtime.GOMAXPROCS(0))
  	started := make(chan bool)
  
  	go func() {
  		started &amp;lt;- true
  		for {
  			atomic.AddUint64(&amp;amp;a, uint64(1))
  		}
  	}()
  
  	&amp;lt;-started
  	for {
  		fmt.Println(atomic.LoadUint64(&amp;amp;a))
  		time.Sleep(time.Second)
  	}
  }
&lt;/code&gt;&lt;/pre&gt;
Here we explicitly wait until the goroutine is started, so we know it&amp;#x27;s scheduled by the time our other loop runs.  Here on my computer with go1.8 linux&amp;#x2F;amd64 it still optimizes out the while loop, which makes sense as nothing changed that would convince the optimizer the loop should remain given the compiler&amp;#x27;s current logic.&lt;p&gt;If you add time.Sleep(time.Millisecond) to the goroutine loop or any other synchronization it works fine.  I&amp;#x27;m having trouble thinking of a real world example where you&amp;#x27;d want an atomic operation going ham in a loop without any sort of time or synchronization.  At the very least a channel indicating when the loop is done would cause the loop to compile.</text></comment>
<story><title>Cmd/compile: Go 1.8 regression: sync/atomic loop elided</title><url>https://github.com/golang/go/issues/19182</url></story><parent_chain><item><author>vessenes</author><text>This is interesting, actually.&lt;p&gt;As the language is specified, it&amp;#x27;s not wrong to just ignore that add completely -- the variable isn&amp;#x27;t used inside the goroutine, and you&amp;#x27;re not guaranteed a goroutine will run at any particular time.&lt;p&gt;So, code executed right after that routine is spawned will be hitting the &amp;#x27;old&amp;#x27; value anyway; hence Dvyukov&amp;#x27;s comments that this is arguably to spec, or within spec.&lt;p&gt;Think if you actually wrote this code; you&amp;#x27;d have some weird behavior if the compiler did what you &amp;#x27;expect&amp;#x27; - a couple outputs of low integers then some high ones as the goroutine gets scheduled in. So it&amp;#x27;s almost certainly just &amp;#x27;wrong&amp;#x27; to write something like this, under most (all?) circumstances.&lt;p&gt;Because sync.Wait() isn&amp;#x27;t used, there&amp;#x27;s no guarantee the goroutine will execute at all before program halt.&lt;p&gt;That said, I bet there&amp;#x27;s some related more reasonable scenario where you could argue the compiler should at least do the adding. I&amp;#x27;m not sure why atomic.Add* should get special treatment though, and it looks like the fix is to remove some escape-analysis type code, so I&amp;#x27;m curious how this will get fixed.</text></item></parent_chain><comment><author>fmstephe</author><text>Unfortunately this miscompilation probably is within spec, given that the atomic package has no documented ordering.&lt;p&gt;But it&amp;#x27;s coming.&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;golang&amp;#x2F;go&amp;#x2F;issues&amp;#x2F;5045&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;golang&amp;#x2F;go&amp;#x2F;issues&amp;#x2F;5045&lt;/a&gt;</text></comment>