From patchwork Thu Apr 29 08:03:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 1471574 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FW7NN3mY9z9sW5 for ; Thu, 29 Apr 2021 18:05:40 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 553073A3E936; Thu, 29 Apr 2021 08:04:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [IPv6:2620:20:4000:0:a9e:1ff:fe9b:1d1]) by sourceware.org (Postfix) with ESMTP id 1D82F3A19037 for ; Thu, 29 Apr 2021 08:03:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1D82F3A19037 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=derodat@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 4437C561C7; Thu, 29 Apr 2021 04:03:48 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id t1LF5JBzi5Rw; Thu, 29 Apr 2021 04:03:48 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [205.232.38.10]) by rock.gnat.com (Postfix) with ESMTP id 1EEDC561C6; Thu, 29 Apr 2021 04:03:48 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id 1D13E193; Thu, 29 Apr 2021 04:03:48 -0400 (EDT) Date: Thu, 29 Apr 2021 04:03:48 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Subject: [Ada] Tree inconsistency between -O0 and -O1 Message-ID: <20210429080348.GA134064@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_NUMSUBJECT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Arnaud Charlet Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The expansion performed in Expand_N_If_Statement only at -O1 and above can create inconsistencies in the tree that can cause trouble when compiling different files with different optimization levels. This is visible in particular in GNAT LLVM when generating C code on ACATS test cc50a01. Fixed by only doing the transformation for internally generated nodes, but systematically. This way we preserve the original control flow for user code and always simplify internally generated trees which was the original motivation of this change (simplify some discriminant checks). Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * exp_ch5.adb (Expand_N_If_Statement): Only perform the simplification on return True/False for internal nodes when -fpreserve-control-flow is not set. diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -3788,62 +3788,58 @@ package body Exp_Ch5 is -- return not (expression); - -- Only do these optimizations if we are at least at -O1 level and - -- do not do them if control flow optimizations are suppressed. + -- Do these optimizations only for internally generated code and only + -- when -fpreserve-control-flow isn't set, to preserve the original + -- source control flow. - if Optimization_Level > 0 + if not Comes_From_Source (N) and then not Opt.Suppress_Control_Flow_Optimizations + and then Nkind (N) = N_If_Statement + and then No (Elsif_Parts (N)) + and then Present (Else_Statements (N)) + and then List_Length (Then_Statements (N)) = 1 + and then List_Length (Else_Statements (N)) = 1 then - if Nkind (N) = N_If_Statement - and then No (Elsif_Parts (N)) - and then Present (Else_Statements (N)) - and then List_Length (Then_Statements (N)) = 1 - and then List_Length (Else_Statements (N)) = 1 - then - declare - Then_Stm : constant Node_Id := First (Then_Statements (N)); - Else_Stm : constant Node_Id := First (Else_Statements (N)); + declare + Then_Stm : constant Node_Id := First (Then_Statements (N)); + Else_Stm : constant Node_Id := First (Else_Statements (N)); - begin - if Nkind (Then_Stm) = N_Simple_Return_Statement + Then_Expr : Node_Id; + Else_Expr : Node_Id; + + begin + if Nkind (Then_Stm) = N_Simple_Return_Statement + and then + Nkind (Else_Stm) = N_Simple_Return_Statement + then + Then_Expr := Expression (Then_Stm); + Else_Expr := Expression (Else_Stm); + + if Nkind (Then_Expr) in N_Expanded_Name | N_Identifier and then - Nkind (Else_Stm) = N_Simple_Return_Statement + Nkind (Else_Expr) in N_Expanded_Name | N_Identifier then - declare - Then_Expr : constant Node_Id := Expression (Then_Stm); - Else_Expr : constant Node_Id := Expression (Else_Stm); + if Entity (Then_Expr) = Standard_True + and then Entity (Else_Expr) = Standard_False + then + Rewrite (N, + Make_Simple_Return_Statement (Loc, + Expression => Relocate_Node (Condition (N)))); + Analyze (N); - begin - if Nkind (Then_Expr) in N_Expanded_Name | N_Identifier - and then - Nkind (Else_Expr) in N_Expanded_Name | N_Identifier - then - if Entity (Then_Expr) = Standard_True - and then Entity (Else_Expr) = Standard_False - then - Rewrite (N, - Make_Simple_Return_Statement (Loc, - Expression => Relocate_Node (Condition (N)))); - Analyze (N); - return; - - elsif Entity (Then_Expr) = Standard_False - and then Entity (Else_Expr) = Standard_True - then - Rewrite (N, - Make_Simple_Return_Statement (Loc, - Expression => - Make_Op_Not (Loc, - Right_Opnd => - Relocate_Node (Condition (N))))); - Analyze (N); - return; - end if; - end if; - end; + elsif Entity (Then_Expr) = Standard_False + and then Entity (Else_Expr) = Standard_True + then + Rewrite (N, + Make_Simple_Return_Statement (Loc, + Expression => + Make_Op_Not (Loc, + Right_Opnd => Relocate_Node (Condition (N))))); + Analyze (N); + end if; end if; - end; - end if; + end if; + end; end if; end Expand_N_If_Statement;