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:}