This is hard to name correctly, since there's really a bigger bug here, and I'm focusing on the lesser bug because it's easier for me to build a minimized test case. First the explanation: for whatever reason, sometimes gcov produces counts with negative edges (that's a bug by itself). An minimized example of such a case will be attached to the bug. In this scenario, the graph looks like this: 1147 +-+ -42 /----->|B|------\ +-+ +-+ +-+ />|A| V 1189 |D| \ | +-+ +-+ +-+ | | \----->|C|------/ | \ 0 +-+ 1189 / \-------------------/ 23 (This is a result of an optimized loop, I don't have the corresponding code on hand, sorry :-( ). In this scenario, the loop detection code finds the following loops: D -> A -> B -> C -> D: loop count = 23 D -> A -> B -> D: loop count = -42 D -> A -> C -> D: loop count = 0 A -> B -> C -> D -> A: loop count = 42 A -> B -> D -> A: loop count = 0 B -> C -> D -> A -> B: loop count = 0 C -> D -> A -> B -> C: loop count = 0 The last four loops are finding permutations of the three simple loops, which is wrong (of course, the fact that one edge has a count of -42 in the first place is wrong in the first place.
Created attachment 36485 [details] test-case.gcda (It's a 4.7 test case, but the file format can still be read with trunk gcov the last I checked. Since the originating issue comes from "compile Firefox", I haven't tried preparing .gcda/.gcno files from newer gcc).
Created attachment 36486 [details] test-case.gcno And the corresponding .gcno file. The testcase was minimized by bisecting the original .gcda/.gcno files by dropping functions and seeing where my attempt to write a new implementation that matched gcov's output failed. The attempt (I did several!) that failed this time was using Boost graph library's hawick_circuits detector, which matched the input incorrectly since this is double-counting loop edges if one of them is negative.
Most interesting would be a C testcase that produces the CFG with the bogus counters ;)
(In reply to Richard Biener from comment #3) > Most interesting would be a C testcase that produces the CFG with the bogus > counters ;) Yeah, I know, but doing the minimization on a 5MLOC program takes time.
I will take a look.
We can have negative counters on fake edges in case the code uses abnormal edges that we can't instrument correctly. setjmp/longjmp is one of examples. If you profile kernel, you will have inconsistencies in profile because of race conditions.