From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx.kolabnow.com (mx.kolabnow.com [212.103.80.154]) by sourceware.org (Postfix) with ESMTPS id B2AA93858C54 for ; Fri, 2 Sep 2022 09:49:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B2AA93858C54 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=lambda.is Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=lambda.is Received: from localhost (unknown [127.0.0.1]) by mx.kolabnow.com (Postfix) with ESMTP id 65CD11511; Fri, 2 Sep 2022 11:49:53 +0200 (CEST) Authentication-Results: ext-mx-out002.mykolab.com (amavisd-new); dkim=pass (4096-bit key) reason="pass (just generated, assumed good)" header.d=kolabnow.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kolabnow.com; h= content-transfer-encoding:content-type:content-type:subject :subject:from:from:content-language:mime-version:date:date :message-id:received:received:received; s=dkim20160331; t= 1662112192; x=1663926593; bh=VTAT9WYn3RrOetnyve3DiCatcSdbZ7cN/uk rEKzfghI=; b=FSxQUyM8wMaNqquU/DNhdwXFv6PyorvfPvEcLRfWnXK0ASICUyY cbefXWLc036goSpGrMfijgb+X0Y3iYYTZBeRN7m2LSmkN174Xynj+IzpgwYq0py9 UVBB8BTow+ZeJSUz92Z0cZnHyvg6BBitnbBkoDVNUsqU7hNt3HW/fuzJ2MjW5LXC vw/KVexONCDEE4goKbV/QE6QDYkqhgM0YbuiEyeZgLpevZUnGaWyLwbOn/HzRrEx VXRF/zq/sJRu6r17ya1Fx0ngiLM6xJPnbCJ2a0JF1rLqJ00ya2xNAwcApmJrQaE+ Sgu0vXmbem296SLcf9cGxwVg6AZAiVwzyA6lhvg5AA7xqkRwtnyQNRkd+f2Z6jDE q5jrVJRkujBEnWGyHvext/fv97FijG8Kk+cLx53uZOhbdMCXh83eQPwT6VEBhX87 tscCr4LeK6nkOO5CksAYV+YPUbI/n5+lFZcIJStmCJEaX2K23eRucS+unsdcDP0+ WREX8aVrYZVTgG3/YimhNtHgS42zmk+Ug2vZdo5MG3vlntUJMadW5Snj9S63bo15 I3mGzauhlKdHKVmp66HsxKB3cDWUSZ8nXctUI3Ph78WPHeaM6+GWaIKkRvMzaNEY OAUbWWGZXIwyAlicEigs+g9q4A0RBAahHFvRvSo7UNC/aa3ws0eLSino= X-Virus-Scanned: amavisd-new at mykolab.com X-Spam-Score: -1.899 X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,HOSTED_IMG_MULTI_PUB_01,KAM_SHORT,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 Received: from mx.kolabnow.com ([127.0.0.1]) by localhost (ext-mx-out002.mykolab.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6siDqsvfShFA; Fri, 2 Sep 2022 11:49:52 +0200 (CEST) Received: from int-mx001.mykolab.com (unknown [10.9.13.1]) by mx.kolabnow.com (Postfix) with ESMTPS id CC0747B7; Fri, 2 Sep 2022 11:49:51 +0200 (CEST) Received: from ext-subm001.mykolab.com (unknown [10.9.6.1]) by int-mx001.mykolab.com (Postfix) with ESMTPS id 6141F15D4; Fri, 2 Sep 2022 11:49:51 +0200 (CEST) Message-ID: Date: Fri, 2 Sep 2022 11:49:49 +0200 MIME-Version: 1.0 Content-Language: en-US From: =?UTF-8?Q?J=c3=b8rgen_Kvalsvik?= Subject: Surprising CFG construction with goto from then to else To: gcc@gcc.gnu.org Cc: mliska@suse.cz, sebastian.huber@embedded-brains.de Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hello, I played some more with odd programs and the effect on control flow graph construction (as a part of condition coverage support [1]) and came across this: int fn (int a, int b, int c) { int x = 0; if (a && b) { if (c) { goto a_; } else { x = a; } } else { a_: x = (a - b); } return x; } Run through gcov --conditions I get: 4: 5: if (a && b) { condition outcomes covered 2/2 condition outcomes covered 2/2 2: 6: if (c) { condition outcomes covered 2/2 Which is clearly not correct. So I started digging into why and dump the CFG as the coverage profiling sees it https://i.imgur.com/d0q72rA.png [2]. I apologize for the labeling, but A2 = a, A3 = b, A5 = c and A9 the else block. The problem, which is what confuses the algorithm, is that a and b don't share A9 as a successor (on false) as I would expect. If I add some operation before the label the problem disappears and a and b share false-destination again https://i.imgur.com/PSrfaLC.png [3]. } else { x++; a_: x = (a - b); } 4: 5: if (a && b) { condition outcomes covered 4/4 2: 6: if (c) { condition outcomes covered 2/2 When dumping the cfg in the former case with -fdump-tree-cfg-graph I get a CFG without the split destinations in a and b https://i.imgur.com/05MCjzp.png [3]. I would assume from this that the graph dump happens after _more_ CFG transformations than the branch profiling. So my questions are: 1. Is the control flow graph expected to be constructed as such where a and b don't share outcome, or is it to be considered a bug? 2. If yes, would it be problematic to push the branch coverage and condition profiling to a later stage where the cfg has been fixed? Thanks, Jørgen [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598165.html [2] dot file: digraph { A0 -> A2 A2 -> A3 A2 -> A8 A3 -> A5 A3 -> A4 A8 -> A9 A9 -> A10 A10 -> A11 A11 -> A1 A5 -> A6 A5 -> A7 A4 -> A9 A6 -> A9 A7 -> A10 } [3] dot file: digraph { A0 -> A2 A2 -> A3 A2 -> A7 A3 -> A4 A3 -> A7 A7 -> A8 A8 -> A9 A9 -> A10 A10 -> A1 A4 -> A5 A4 -> A6 A5 -> A8 A6 -> A9 } [3] dot file: overlap=false; subgraph "cluster_fn" { style="dashed"; color="black"; label="fn ()"; fn_0_basic_block_0 [shape=Mdiamond,style=filled,fillcolor=white,label="ENTRY"]; fn_0_basic_block_1 [shape=Mdiamond,style=filled,fillcolor=white,label="EXIT"]; fn_0_basic_block_2 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |x\ =\ 0;\l\ |if\ (a\ !=\ 0)\l\ \ \ goto\ \;\ [INV]\l\ else\l\ \ \ goto\ \;\ [INV]\l\ }"]; fn_0_basic_block_3 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |if\ (b\ !=\ 0)\l\ \ \ goto\ \;\ [INV]\l\ else\l\ \ \ goto\ \;\ [INV]\l\ }"]; fn_0_basic_block_4 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |if\ (c\ !=\ 0)\l\ \ \ goto\ \;\ [INV]\l\ else\l\ \ \ goto\ \;\ [INV]\l\ }"]; fn_0_basic_block_5 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |//\ predicted\ unlikely\ by\ goto\ predictor.\l\ goto\ \;\ [INV]\l\ }"]; fn_0_basic_block_6 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |x\ =\ a;\l\ goto\ \;\ [INV]\l\ }"]; fn_0_basic_block_7 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |a_:\l\ |x\ =\ a\ -\ b;\l\ }"]; fn_0_basic_block_8 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |D.2398\ =\ x;\l\ }"]; fn_0_basic_block_9 [shape=record,style=filled,fillcolor=lightgrey,label="{\:\l\ |\:\l\ |return\ D.2398;\l\ }"]; fn_0_basic_block_0:s -> fn_0_basic_block_2:n [style="solid,bold",color=black,weight=100,constraint=true]; fn_0_basic_block_2:s -> fn_0_basic_block_3:n [style="solid,bold",color=forestgreen,weight=10,constraint=true]; fn_0_basic_block_2:s -> fn_0_basic_block_7:n [style="solid,bold",color=darkorange,weight=10,constraint=true]; fn_0_basic_block_3:s -> fn_0_basic_block_4:n [style="solid,bold",color=forestgreen,weight=10,constraint=true]; fn_0_basic_block_3:s -> fn_0_basic_block_7:n [style="solid,bold",color=darkorange,weight=10,constraint=true]; fn_0_basic_block_4:s -> fn_0_basic_block_5:n [style="solid,bold",color=forestgreen,weight=10,constraint=true]; fn_0_basic_block_4:s -> fn_0_basic_block_6:n [style="solid,bold",color=darkorange,weight=10,constraint=true]; fn_0_basic_block_5:s -> fn_0_basic_block_7:n [style="solid,bold",color=black,weight=100,constraint=true]; fn_0_basic_block_6:s -> fn_0_basic_block_8:n [style="solid,bold",color=black,weight=100,constraint=true]; fn_0_basic_block_7:s -> fn_0_basic_block_8:n [style="solid,bold",color=black,weight=100,constraint=true]; fn_0_basic_block_8:s -> fn_0_basic_block_9:n [style="solid,bold",color=black,weight=100,constraint=true]; fn_0_basic_block_9:s -> fn_0_basic_block_1:n [style="solid,bold",color=black,weight=10,constraint=true]; fn_0_basic_block_0:s -> fn_0_basic_block_1:n [style="invis",constraint=true]; } }