gccgo: regression in gcc 5.2.1 in gccgo testcase 235.go on ppc64le, ppc64 #13662
This regression has been around since 5.2.1, and started failing with r227785 on the gcc release 5 branch. You can see the failures in the gcc-testresults output for ppc64le and ppc64 consistently since then. If I remove that change the testcase passes. It does not fail on trunk.
Here is the information from go.log:
goroutine 16 [running]:
goroutine 19 [chan receive]:
goroutine 20 [chan receive]:
goroutine 21 [chan receive]:
The text was updated successfully, but these errors were encountered:
I've tried various experiments. It does appear to be a GC issue with freeing something too early. I can't get it to fail on gcc6; on gcc5 it passes without optimization, passes at -O2 if I set GOGC=off. After adding print statements I see that 'F' gets trashed before it gets in the case where it fails.
If I add a print statement right after F is initialized, then the values are good and the test passes.
I don't know enough about what GC does or how it decides it shouldn't free something. Must be something unique about this testcase or else we'd be seeing lots of GC problems?
I've done some investigation on this and there are two things that don't seem right for the gcc 5 branch with gccgo on Power.
First, the failure started happening with commit 227785, with the change to subtract off the value of runtime_stacks_sys from the next_gc value.
On Power in gcc5, split stack support was not backported so the value of runtime_stacks_sys is a large value, which means next_gc is not being set to a high value as described in the comments. (In other words, the value of runtime_stacks_sys is likely to be a large portion of the total heap at the beginning). Instead the next run of GC is done soon. The problem doesn't happen on gcc6 because of the split stack implementation or the effect of this patch https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03503.html, both of which keep runtime_stacks_sys as a low value.
But as was noted above, running GC more frequently shouldn't cause a failure so there also seems to be a problem related to the use of GC with optimized code. I found that if the pointer returned from a heap allocation is kept in a register and never stored then it is being freed too early by GC causing the failure in this test. When next_gc is a low value and the next GC is done soon this problem is more likely to occur.
By the time the call is made to memcpy, the storage containing the values that should be copied have been garbage collected and the values are 0. When compiled without optimization, the pointer is stored and the failure does not occur.
Thanks for looking into this. It shouldn't matter that r3 is not stored, because the value was copied into r27. Presumably the fmt.Printf, where the problem appears, is using r27 to retrieve the values.
What puzzles me, looking at the partial disassembly, is the
Original problem was reported on gccgo from gcc 5.2.1, and did not fail
If I build the test with gccgo from trunk using -O2 and use GOGC=10 then
On 01/06/2016 09:19 AM, Ian Lance Taylor wrote: