From: Xionghu Luo <yinyuefengyi@gmail.com>
To: Richard Biener <richard.guenther@gmail.com>,
Xionghu Luo <xionghuluo@tencent.com>
Cc: gcc-patches@gcc.gnu.org, luoxhu@gcc.gnu.org, rguenther@suse.de,
hubicka@ucw.cz
Subject: Re: [PATCH 1/2] gcov: Fix "do-while" structure in case statement leads to incorrect code coverage [PR93680]
Date: Thu, 2 Mar 2023 18:22:40 +0800 [thread overview]
Message-ID: <00510a56-1fe5-a556-21cf-fa869f70800b@gmail.com> (raw)
In-Reply-To: <CAFiYyc2vdA3R_mBhNwktmjm0_5SJD7egGwoQMy3vgVBP5iD3+w@mail.gmail.com>
On 2023/3/2 16:41, Richard Biener wrote:
> On Thu, Mar 2, 2023 at 3:31 AM Xionghu Luo via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>>
>> When spliting edge with self loop, the split edge should be placed just next to
>> the edge_in->src, otherwise it may generate different position latch bbs for
>> two consecutive self loops. For details, please refer to:
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93680#c4
>>
>> Regression tested pass on x86_64-linux-gnu and aarch64-linux-gnu, OK for
>> master?
>>
>> gcc/ChangeLog:
>>
>> PR gcov/93680
>> * tree-cfg.cc (split_edge_bb_loc): Return edge_in->src for self loop.
>>
>> gcc/testsuite/ChangeLog:
>>
>> PR gcov/93680
>> * gcc.misc-tests/gcov-pr93680.c: New test.
>>
>> Signed-off-by: Xionghu Luo <xionghuluo@tencent.com>
>> ---
>> gcc/testsuite/gcc.misc-tests/gcov-pr93680.c | 24 +++++++++++++++++++++
>> gcc/tree-cfg.cc | 2 +-
>> 2 files changed, 25 insertions(+), 1 deletion(-)
>> create mode 100644 gcc/testsuite/gcc.misc-tests/gcov-pr93680.c
>>
>> diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c b/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c
>> new file mode 100644
>> index 00000000000..b2bf9e626fc
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr93680.c
>> @@ -0,0 +1,24 @@
>> +/* { dg-options "-fprofile-arcs -ftest-coverage" } */
>> +/* { dg-do run { target native } } */
>> +
>> +int f(int s, int n)
>> +{
>> + int p = 0;
>> +
>> + switch (s)
>> + {
>> + case 0: /* count(5) */
>> + do { p++; } while (--n); /* count(5) */
>> + return p; /* count(1) */
>> +
>> + case 1: /* count(5) */
>> + do { p++; } while (--n); /* count(5) */
>> + return p; /* count(1) */
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +int main() { f(0, 5); f(1, 5); return 0; }
>> +
>> +/* { dg-final { run-gcov gcov-pr93680.c } } */
>> diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
>> index a9fcc7fd050..6fa1d83d366 100644
>> --- a/gcc/tree-cfg.cc
>> +++ b/gcc/tree-cfg.cc
>> @@ -3009,7 +3009,7 @@ split_edge_bb_loc (edge edge_in)
>> if (dest_prev)
>> {
>> edge e = find_edge (dest_prev, dest);
>> - if (e && !(e->flags & EDGE_COMPLEX))
>> + if ((e && !(e->flags & EDGE_COMPLEX)) || edge_in->src == edge_in->dest)
>
> I think this should eventually apply to all backedge edge_in, correct?
> But of course
> we cannot easily test for this here.
>
> Still since this affects ordering in the {next,prev}_bb chain only but not CFG
> semantics I wonder how it can affect coverage? Isn't it only by chance that
> this block order survives?
For case:
1 int f(int s, int n)
2 {
3 int p = 0;
4 int q = 0;
5
6 switch (s)
7 {
8 case 0:
9 do { p++; } while (--n);
10 return p;
11
12 case 1:
13 do { p++; } while (--n);
14 return p;
15 }
16
17 return 0;
18 }
19
20 int main() { f(0, 5); f(1, 5);}
current GCC generates:
<bb 2> :
...
<bb 3> : <= first loop
...
goto <bb 4>; [INV]
else
goto <bb 5>; [INV]
<bb 4> : <= first latch bb
goto <bb 3>; [100.00%]
<bb 5> :
...
goto <bb 10>; [INV]
<bb 6> : <= second latch bb
<bb 7> : <= second loop
...
goto <bb 6>; [INV]
else
goto <bb 8>; [INV]
<bb 4> and <bb 6> are created by split_edge->split_edge_bb_loc, <bb 4>
is located after the loop, but <bb 6> is located before the loop.
First call of split_edge_bb_loc, the dest_prev is <bb 2>, and find_edge
did find a edge from <bb 2> to <bb 3>, the returned afte_bb is <bb 3>, so
latch <bb 4> is put after the loop
but second call of split_edge_bb_loc, the dest_prev is <bb 5>, so find_edge
return 0, and the returned after_bb is <bb 5>, then the created latch <bb 6>
is put before the loop...
Different latch bb position caused different gcno, while gcov has poor
information and not that smart to recognize it:(, is it reasonable to keep
this kind of loops same order?
small.gcno: 648: block 2:`small.c':1, 3, 4, 6
small.gcno: 688: 01450000: 36:LINES
small.gcno: 700: block 3:`small.c':8, 9
small.gcno: 732: 01450000: 32:LINES
small.gcno: 744: block 5:`small.c':10
-small.gcno: 772: 01450000: 32:LINES
-small.gcno: 784: block 6:`small.c':12
-small.gcno: 812: 01450000: 36:LINES
-small.gcno: 824: block 7:`small.c':12, 13
+small.gcno: 772: 01450000: 36:LINES
+small.gcno: 784: block 6:`small.c':12, 13
+small.gcno: 816: 01450000: 32:LINES
+small.gcno: 828: block 8:`small.c':14
small.gcno: 856: 01450000: 32:LINES
-small.gcno: 868: block 8:`small.c':14
-small.gcno: 896: 01450000: 32:LINES
-small.gcno: 908: block 9:`small.c':17
+small.gcno: 868: block 9:`small.c':17
>
> For the case when both edge_in->src has more than one successor and
> edge_in->dest has more than one predecessor there isn't any good heuristic
> to make printing the blocks in chain order "nice" (well, the backedge
> one maybe).
>
> But as said - this order shouldn't have any effect on semantics ...
>
>> return edge_in->src;
>> }
>> return dest_prev;
>> --
>> 2.27.0
>>
next prev parent reply other threads:[~2023-03-02 10:22 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-02 2:29 Xionghu Luo
2023-03-02 2:29 ` [PATCH 2/2] gcov: Fix incorrect gimple line LOCATION [PR97923] Xionghu Luo
2023-03-02 8:16 ` Richard Biener
2023-03-02 9:43 ` Xionghu Luo
2023-03-02 10:02 ` Richard Biener
2023-03-02 8:41 ` [PATCH 1/2] gcov: Fix "do-while" structure in case statement leads to incorrect code coverage [PR93680] Richard Biener
2023-03-02 10:22 ` Xionghu Luo [this message]
2023-03-02 10:45 ` Richard Biener
2023-03-06 7:22 ` Xionghu Luo
2023-03-06 8:11 ` Richard Biener
2023-03-07 7:41 ` Xionghu Luo
2023-03-07 8:53 ` Richard Biener
2023-03-07 10:26 ` Xionghu Luo
2023-03-07 11:25 ` Richard Biener
2023-03-08 13:07 ` [PATCH v3] " Xionghu Luo
2023-03-09 12:02 ` Richard Biener
2023-03-14 2:06 ` [PATCH v4] " Xionghu Luo
2023-03-21 11:18 ` Richard Biener
2023-03-15 10:07 ` Xionghu Luo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=00510a56-1fe5-a556-21cf-fa869f70800b@gmail.com \
--to=yinyuefengyi@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=luoxhu@gcc.gnu.org \
--cc=rguenther@suse.de \
--cc=richard.guenther@gmail.com \
--cc=xionghuluo@tencent.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).