From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id AE0E53858D1E for ; Wed, 10 Aug 2022 11:30:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AE0E53858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.cz Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id AF1111FF6F; Wed, 10 Aug 2022 11:30:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1660131005; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2LkFuFXzi+9mbbLQgB+zRm8QWdvWTMtEo37tYrJWQbY=; b=Gy56d5swg4SYmfrpLtQaW0YzgWJE9+yUhh+c3580DCbK3E22P14OiuL6eXvnwHseb0tGRC 3PWXascPzdYPBtJzaJoVRMEX69/1XljV0aERjkicwjWAA2U6mDJu44ToFf90lUh0kY5oFb L8XDpR+dx/upGYDExLDgp/z1kCKpvhM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1660131005; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2LkFuFXzi+9mbbLQgB+zRm8QWdvWTMtEo37tYrJWQbY=; b=5miWhhqECjZ0275Edu667NW913bAnDb3fZ7DmZgnUqz15mI3zCRh/59/lr1HTKUCbX91c3 JGVXDJyNo7+4rqBw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 91E4A13AB3; Wed, 10 Aug 2022 11:30:05 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id en9/Ir2W82IKWgAAMHmgww (envelope-from ); Wed, 10 Aug 2022 11:30:05 +0000 Message-ID: Date: Wed, 10 Aug 2022 13:30:05 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.1.0 Subject: Re: gccgo emits GIMPLE with temporaries for boolean expressions unlike gcc, gdc Content-Language: en-US To: j , gcc@gcc.gnu.org References: <4ba7b262-ee0b-905f-ba0a-611ee6749184@lambda.is> Cc: Ian Lance Taylor From: =?UTF-8?Q?Martin_Li=c5=a1ka?= In-Reply-To: <4ba7b262-ee0b-905f-ba0a-611ee6749184@lambda.is> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, NICE_REPLY_A, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Aug 2022 11:30:09 -0000 CCing Go maintainer. Martin On 8/3/22 15:25, j wrote: > > Hello, > > I've proposed a patch [1] for condition coverage profiling in gcc, implemented in the middle-end alongside the branch coverage. I've written most of the tests for C and a few for C++ and finally got around to try it with a toy example for D and go and noticed something odd about Go's CFG construction. > > abc.c: >     int fn (int a, int b, int c) { >         if (a && (b || c)) >             return a; >         else >             return b * c; >     } > > abc.d: >     int fn (int a, int b, int c) { >         if (a && (b || c)) >             return a; >         else >             return b * c; >     } > > abc.go: >     func fn (a int, b int, c int) int { >         a_ := a != 0; >         b_ := b != 0; >         c_ := c != 0; > >         if a_ && (b_ || c_) { >             return 1; >         } else { >             return 0; >         } >     } > > All were built with gcc --coverage -fprofile-conditions (my patch, but it does not affect this) and no optimization. The C and D programs behaved as expected: > > gcov --conditions abc.d: > >         3:    3:int fn (int a, int b, int c) { >        3*:    4:    if (a && (b || c)) > conditions outcomes covered 3/6 > condition  1 not covered (false) > condition  2 not covered (true) > condition  2 not covered (false) >         1:    5:        return a; >         -:    6:    else >         2:    7:        return b * c; > > > gcov --conditions abc.go: >         3:    5:func fn (a int, b int, c int) int { >         3:    6:        a_ := a != 0; >         3:    7:        b_ := b != 0; >         3:    8:        c_ := c != 0; >         -:    9: >        3*:   10:        if a_ && (b_ || c_) { > condition outcomes covered 2/2 > condition outcomes covered 1/2 > condition  0 not covered (true) > condition outcomes covered 2/2 >         1:   11:            return 1; >         -:   12:        } else { >         2:   13:            return 0; >         -:   14:        } >         -:   15:} > > So I dumped the gimple gcc -fdump-tree-gimple abc.go: > > int main.fn (int a, int b, int c) > { >   int D.2725; >   int $ret0; > >   $ret0 = 0; >   { >     bool a_; >     bool b_; >     bool c_; > >     a_ = a != 0; >     b_ = b != 0; >     c_ = c != 0; >     { >       { >         GOTMP.0 = a_; >         if (GOTMP.0 != 0) goto ; else goto ; >         : >         { >           { >             GOTMP.1 = b_; >             _1 = ~GOTMP.1; >             if (_1 != 0) goto ; else goto ; >             : >             { >               GOTMP.1 = c_; >             } >             : >           } >           GOTMP.2 = GOTMP.1; >           GOTMP.0 = GOTMP.2; >         } >         : >       } >       if (GOTMP.0 != 0) goto ; else goto ; >       : > > >       { >         { >           $ret0 = 1; >           D.2725 = $ret0; >           // predicted unlikely by early return (on trees) predictor. >           return D.2725; >         } >       } >       : >       { >         { >           $ret0 = 0; >           D.2725 = $ret0; >           // predicted unlikely by early return (on trees) predictor. >           return D.2725; >         } >       } >     } >   } > } > > Where as D (and C) is more-or-less as you would expect: > > int fn (int a, int b, int c) > > > { >   int D.7895; > >   if (a != 0) goto ; else goto ; >   : >   if (b != 0) goto ; else goto ; >   : >   if (c != 0) goto ; else goto ; >   : >   D.7895 = a; >   // predicted unlikely by early return (on trees) predictor. >   return D.7895; >   : >   D.7895 = b * c; >   // predicted unlikely by early return (on trees) predictor. >   return D.7895; > } > > Clearly the decision inference algorithm is unable to properly instrument to Go program for condition coverage because of the use of temporaries in the emitted GIMPLE. The question is: is this intentional and/or required from Go's semantics or could it be considered a defect? Is emitting the GIMPLE without the use of temporaries feasible at all? > > Thanks, > Jørgen > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598165.html