https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79891
Martin Liška <marxin at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at ucw dot cz --- Comment #3 from Martin Liška <marxin at gcc dot gnu.org> --- Ok, there's a bit simplified test-case: #include <stdlib.h> /* for exit() */ unsigned int UuT (void) { unsigned int true_var = 1; unsigned int false_var = 0; unsigned int ret = 0; if (true_var) { if (false_var) ret = 111; /* issue */ } else ret = 999; return ret; } int main (int argc, char **argv) { UuT (); return 0; } IPA profile outputs following CFG: <bb 2> [0.00%]: true_var_3 = 1; false_var_4 = 0; ret_5 = 0; if (true_var_3 != 0) goto <bb 3>; [0.00%] else goto <bb 6>; [0.00%] <bb 3> [0.00%]: if (false_var_4 != 0) goto <bb 4>; [0.00%] else goto <bb 5>; [0.00%] <bb 4> [0.00%]: ret_7 = 111; PROF_edge_counter_10 = __gcov0.UuT[0]; PROF_edge_counter_11 = PROF_edge_counter_10 + 1; __gcov0.UuT[0] = PROF_edge_counter_11; <bb 5> [0.00%]: # ret_1 = PHI <ret_5(3), ret_7(4)> goto <bb 7>; [0.00%] <bb 6> [0.00%]: ret_6 = 999; PROF_edge_counter_12 = __gcov0.UuT[1]; PROF_edge_counter_13 = PROF_edge_counter_12 + 1; __gcov0.UuT[1] = PROF_edge_counter_13; <bb 7> [0.00%]: # ret_2 = PHI <ret_1(5), ret_6(6)> _8 = ret_2; <L5> [0.00%]: PROF_edge_counter_14 = __gcov0.UuT[2]; PROF_edge_counter_15 = PROF_edge_counter_14 + 1; __gcov0.UuT[2] = PROF_edge_counter_15; return _8; Problem is that BB 7 is used for both false_var == false and as a fallthru block for BB 6. Thus line 13 contains 2 blocks: ./gcov pr79891.c -a --debug GCOV function: UuT line 4: 1 BB 1 (0xfae1b8): 1 line 10: 1 BB 2 (0xfae200): 1 arc 0xfae200->0xfae248: 1 arc 0xfae200->0xfae320: 0 line 12: 1 BB 3 (0xfae248): 1 arc 0xfae248->0xfae290: 0 arc 0xfae248->0xfae2d8: 1 line 13: 0 BB 5 (0xfae2d8): 1 arc 0xfae2d8->0xfae368: 1 BB 4 (0xfae290): 0 arc 0xfae290->0xfae2d8: 0 line 16: 0 BB 6 (0xfae320): 0 arc 0xfae320->0xfae368: 0 line 17: 1 BB 7 (0xfae368): 1 arc 0xfae368->0xfae3b0: 1 And behavior with -a (all-blocks) behaves as described here: /* The user expects the line count to be the number of times a line has been executed. Simply summing the block count will give an artificially high number. The Right Thing is to sum the entry counts to the graph of blocks on this line, then find the elementary cycles of the local graph and add the transition counts of those cycles. */ That's why we end up with the wrong number. Thoughts?