From patchwork Tue Oct 18 06:35:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 77920 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp732802qge; Mon, 17 Oct 2016 23:35:48 -0700 (PDT) X-Received: by 10.66.25.50 with SMTP id z18mr1654459paf.151.1476772548099; Mon, 17 Oct 2016 23:35:48 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id i5si34164661pfe.24.2016.10.17.23.35.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Oct 2016 23:35:48 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-438865-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-438865-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-438865-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=HYiaGG4oUZCuawWr Z5mwV59dF+Eh/UD7sSTAkFmuHEqeGexJcKgdYf4dgh0b6pA/SmkTRpJwQljQhOgH ND0j9lBQkokVevHupuSJrdQrnc3iR/j//XR+dwITXCDmf5sTZ71nwAFQG2oE+jjV VXo7KCQ02NHL3v+IH+NOGr3I7VA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=3TEByRJOIG6eZ8wysvy6UT HTAZo=; b=bGeEAzaWVgVljhKT1mOujznHlg5YXvC3e5WfpheFeJmt2fSYEdQg9W WB7vp6Dxf5xkFVNcs7gnyvHMr3xwJp1ToLobOtCtJlZUWpNz3C9ILzP29jdmNMcK JS9sACIi849iIv2c2aPfQyjgZBZVyVtvMxmE6301J95nPKDGtlrTk= Received: (qmail 69286 invoked by alias); 18 Oct 2016 06:35:27 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 69272 invoked by uid 89); 18 Oct 2016 06:35:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=2016-10-18, Boolean, _33, Hx-languages-length:4486 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 18 Oct 2016 06:35:16 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 509F5812EF for ; Tue, 18 Oct 2016 08:35:14 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mDxaT9_DaFJA for ; Tue, 18 Oct 2016 08:35:14 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 1EC26812EC for ; Tue, 18 Oct 2016 08:35:14 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix PHI optimization issue with boolean types Date: Tue, 18 Oct 2016 08:35:13 +0200 Message-ID: <10860828.opkyFOrRK6@polaris> User-Agent: KMail/4.14.10 (Linux/3.16.7-42-desktop; KDE/4.14.9; x86_64; ; ) MIME-Version: 1.0 Hi, this is a regression present on the mainline and 6 branch: the compiler now generates wrong code for the attached testcase at -O because of an internal conflict about boolean types. The sequence is as follows. In .mergephi3: boolean _22; p__enum res; : if (_22 != 0) goto ; else goto ; : : # res_17 = PHI <2(8), 0(9), 1(10)> is turned into: COND_EXPR in block 9 and PHI in block 11 converted to straightline code. PHI res_17 changed to factor conversion out from COND_EXPR. New stmt with CAST that defines res_17. boolean _33; : # _33 = PHI <2(8), _22(9)> res_17 = (p__enum) _33; [...] : if (res_17 != 0) goto ; else goto ; : _12 = res_17 == 2; _13 = (integer) _12 in .phiopt1. So boolean _33 can have value 2. Later forwprop3 propagates _33 into the uses of res_17: : if (_33 != 0) goto ; else goto ; : _12 = _33 == 2; _13 = (integer) _12; and DOM3 deduces: : _12 = 0; _13 = 0; because it computes that _33 has value 1 in BB 13 since it's a boolean. The problem was introduced by the new factor_out_conditional_conversion: /* If arg1 is an INTEGER_CST, fold it to new type. */ if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) && int_fits_type_p (arg1, TREE_TYPE (new_arg0))) { if (gimple_assign_cast_p (arg0_def_stmt)) new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); else return NULL; } else return NULL int_fits_type_p is documented as taking only INTEGER_TYPE, but is invoked on constant 2 and a BOOLEAN_TYPE and returns true. BOOLEAN_TYPE is special in Ada: it has precision 8 and range [0;255] so the outcome of int_fits_type_p is not unreasonable. But this goes against the various transformations applied to boolean types in the compiler, which all assume that they can only take values 0 or 1. Hence the attached fix (which should be a no-op except for Ada), tested on x86_64-suse-linux, OK for mainline and 6 branch? 2016-10-18 Eric Botcazou * tree.c (int_fits_type_p): Accept only 0 and 1 for boolean types. 2016-10-18 Eric Botcazou * gnat.dg/opt59.adb: New test. * gnat.dg/opt59_pkg.ad[sb]: New helper. -- Eric Botcazou Index: tree.c =================================================================== --- tree.c (revision 241294) +++ tree.c (working copy) @@ -9065,8 +9065,8 @@ get_narrower (tree op, int *unsignedp_pt return win; } -/* Returns true if integer constant C has a value that is permissible - for type TYPE (an INTEGER_TYPE). */ +/* Return true if integer constant C has a value that is permissible + for TYPE, an integral type. */ bool int_fits_type_p (const_tree c, const_tree type) @@ -9075,6 +9075,11 @@ int_fits_type_p (const_tree c, const_tre bool ok_for_low_bound, ok_for_high_bound; signop sgn_c = TYPE_SIGN (TREE_TYPE (c)); + /* Short-circuit boolean types since various transformations assume that + they can only take values 0 and 1. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) + return integer_zerop (c) || integer_onep (c); + retry: type_low_bound = TYPE_MIN_VALUE (type); type_high_bound = TYPE_MAX_VALUE (type);