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?

Reply via email to