https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90420

            Bug ID: 90420
           Summary: [GCOV] wrong coverage with "-O3" or "-O2"
                    optimizations for function call
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: gcov-profile
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yangyibiao at nju dot edu.cn
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/9.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-trunk/configure --enable-languages=c,c++
--disable-multilib --prefix=/usr/local/gcc-trunk
Thread model: posix
gcc version 9.0.1 20190414 (experimental) (GCC)

$ cat small.c
#define N 1000

int argc = 1;

int func (int *p, int *q) {
  int x = 0;
  for (int i = 0; i < N; i++) { 
    x += (q[i] + p[i]);
  }
  return x;
}

int main ()
{
  int x = 0;
  int A1[N], A2[N];

  for (int i = 0; i < N; i++) {
    A1[i] = 5 + argc;
    A2[i] = 1;
  }

  x = func (A1, A2);

  if (x != N * 7)
    return 1;

  return 0;
}


$ gcc -O3 -g --coverage small.c; ./a.out; gcov small.c; cat small.c.gcov
File 'small.c'
Lines executed:78.57% of 14
Creating 'small.c.gcov'

        -:    0:Source:small.c
        -:    0:Graph:small.gcno
        -:    0:Data:small.gcda
        -:    0:Runs:1
        -:    1:#define N 1000
        -:    2:
        -:    3:int argc = 1;
        -:    4:
    #####:    5:int func (int *p, int *q) {
    1001*:    6:  int x = 0;
    #####:    7:  for (int i = 0; i < N; i++) { 
    1000*:    8:    x += (q[i] + p[i]);
        -:    9:  }
       1*:   10:  return x;
        -:   11:}
        -:   12:
        1:   13:int main ()
        -:   14:{
        1:   15:  int x = 0;
        1:   16:  int A1[N], A2[N];
        -:   17:
     1001:   18:  for (int i = 0; i < N; i++) {
     1000:   19:    A1[i] = 5 + argc;
     1000:   20:    A2[i] = 1;
        -:   21:  }
        -:   22:  
     1001:   23:  x = func (A1, A2);
        -:   24:
        1:   25:  if (x != N * 7)
    #####:   26:    return 1;
        -:   27:
        -:   28:  return 0;
        -:   29:}


When using "-O3" optimization, Line #6 and Line #22 are wrongly marked as
executed about 1000 times. When using "-O2" optimization, the coverage result
is incorrect as well. 

When Line #26 is removed, the result seems correct as follows:

$ gcc -O3 -g --coverage small.c; ./a.out; gcov small.c; cat small.c.gcov
File 'small.c'
Lines executed:75.00% of 12
Creating 'small.c.gcov'

        -:    0:Source:small.c
        -:    0:Graph:small.gcno
        -:    0:Data:small.gcda
        -:    0:Runs:1
        -:    1:#define N 1000
        -:    2:
        -:    3:int argc = 1;
        -:    4:
    #####:    5:int func (int *p, int *q) {
       1*:    6:  int x = 0;
    #####:    7:  for (int i = 0; i < N; i++) { 
    #####:    8:    x += (q[i] + p[i]);
        -:    9:  }
       1*:   10:  return x;
        -:   11:}
        -:   12:
        1:   13:int main ()
        -:   14:{
        1:   15:  int x = 0;
        1:   16:  int A1[N], A2[N];
        -:   17:
        1:   18:  for (int i = 0; i < N; i++) {
        -:   19:    A1[i] = 5 + argc;
        -:   20:    A2[i] = 1;
        -:   21:  }
        -:   22:
        1:   23:  x = func (A1, A2);
        -:   24:
        1:   25:  if (x != N * 7)
        -:   26:    ; // return 1;
        -:   27:
        1:   28:  return 0;
        -:   29:}

Reply via email to