From patchwork Mon Jan 28 14:25:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 216222 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 750532C0080 for ; Tue, 29 Jan 2013 01:25:32 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1359987933; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=qmbo3XSWU1t76xJTTkzf qfJ43yg=; b=BO5daukC55+ztctvgZ/hBCP0+NCyApvyq1Cif8W/3RFdMsAhD0jS lPlLOZhNNkQRnaGGI809/XEZ4jUjh9E8uhba6VnVuzpbvdIQOWQYusAM/6hWC0DD 4MO6E7a3ZkGOuie2NKSLscMtsklldw09u+4wf1ZsevW/DAj87UDCWX8= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=EBT8OsQVWF7Q2YJobJ5CxmKIH7ZsTK9ePaRLJMd5lBNFBIJtXvxnFzLPlFPKK8 K+Ndbbr2VBCmkBs5VvuoLSh1zx5buklY8eKKb/edV0xr3Heo4sRkQi30uyw5wGYU kZmM6ebxuHXhCq7O1SzfGZO1i6JMSIwJHJSQW/ApLn2T8=; Received: (qmail 12971 invoked by alias); 28 Jan 2013 14:25:26 -0000 Received: (qmail 12938 invoked by uid 22791); 28 Jan 2013 14:25:23 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_SPAMHAUS_DROP, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 28 Jan 2013 14:25:14 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r0SEP8uD031913 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 28 Jan 2013 09:25:12 -0500 Received: from zalov.redhat.com (vpn1-6-106.ams2.redhat.com [10.36.6.106]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r0SEP6Rr013949 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 28 Jan 2013 09:25:07 -0500 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.redhat.com (8.14.5/8.14.5) with ESMTP id r0SEP5gT017722; Mon, 28 Jan 2013 15:25:05 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r0SEP4JB017721; Mon, 28 Jan 2013 15:25:04 +0100 Date: Mon, 28 Jan 2013 15:25:04 +0100 From: Jakub Jelinek To: Richard Biener , "William J. Schmidt" Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix up pow folding (PR tree-optimization/56125) Message-ID: <20130128142504.GH4385@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 Hi! gimple_expand_builtin_pow last two optimizations rely on earlier optimizations in the same function to be performed, e.g. folding pow (x, c) for n = 2c into sqrt(x) * powi(x, n / 2) is only correct for c which isn't an integer (otherwise the sqrt(x) factor would need to be skipped), but they actually do not check this. E.g. the pow (x, n) where n is integer is optimized only if: && ((n >= -1 && n <= 2) || (flag_unsafe_math_optimizations && optimize_insn_for_speed_p () && powi_cost (n) <= POWI_MAX_MULTS))) and as in the testcase the function is called, it isn't optimized and we fall through till the above mentioned optimization which blindly assumes that c isn't an integer. Fixed by both checking that c isn't an integer (and for the last optimization also that 2c isn't an integer), and also not doing the -> sqrt(x) * powi(x, n / 2) resp. 1.0 / sqrt(x) * powi(x, abs(n) / 2) optimization for -Os or cold functions, at least __attribute__((cold)) double foo (double x, double n) { return __builtin_pow (x, -1.5); } is smaller when expanded as pow call both on x86_64 and on powerpc (with -Os -ffast-math). Even just the c*_is_int tests alone could be enough to fix the bug, so if you say want to enable it for -Os even with c 1.5, but not for negative values which add another operation, it can be adjusted. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-01-28 Jakub Jelinek PR tree-optimization/56125 * tree-ssa-math-opts.c (gimple_expand_builtin_pow): Don't optimize pow(x,c) into sqrt(x) * powi(x, n/2) or 1.0 / (sqrt(x) * powi(x, abs(n/2))) if c is an integer or when optimizing for size. Don't optimize pow(x,c) into powi(x, n/3) * powi(cbrt(x), n%3) or 1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)) if 2c is an integer. * gcc.dg/pr56125.c: New test. Jakub --- gcc/tree-ssa-math-opts.c.jj 2013-01-11 09:02:48.000000000 +0100 +++ gcc/tree-ssa-math-opts.c 2013-01-28 10:56:40.105950483 +0100 @@ -1110,7 +1110,7 @@ gimple_expand_builtin_pow (gimple_stmt_i HOST_WIDE_INT n; tree type, sqrtfn, cbrtfn, sqrt_arg0, sqrt_sqrt, result, cbrt_x, powi_cbrt_x; enum machine_mode mode; - bool hw_sqrt_exists; + bool hw_sqrt_exists, c_is_int, c2_is_int; /* If the exponent isn't a constant, there's nothing of interest to be done. */ @@ -1122,8 +1122,9 @@ gimple_expand_builtin_pow (gimple_stmt_i c = TREE_REAL_CST (arg1); n = real_to_integer (&c); real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); + c_is_int = real_identical (&c, &cint); - if (real_identical (&c, &cint) + if (c_is_int && ((n >= -1 && n <= 2) || (flag_unsafe_math_optimizations && optimize_insn_for_speed_p () @@ -1221,7 +1222,8 @@ gimple_expand_builtin_pow (gimple_stmt_i return build_and_insert_call (gsi, loc, cbrtfn, sqrt_arg0); } - /* Optimize pow(x,c), where n = 2c for some nonzero integer n, into + /* Optimize pow(x,c), where n = 2c for some nonzero integer n + and c not an integer, into sqrt(x) * powi(x, n/2), n > 0; 1.0 / (sqrt(x) * powi(x, abs(n/2))), n < 0. @@ -1230,10 +1232,13 @@ gimple_expand_builtin_pow (gimple_stmt_i real_arithmetic (&c2, MULT_EXPR, &c, &dconst2); n = real_to_integer (&c2); real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0); + c2_is_int = real_identical (&c2, &cint); if (flag_unsafe_math_optimizations && sqrtfn - && real_identical (&c2, &cint)) + && c2_is_int + && !c_is_int + && optimize_function_for_speed_p (cfun)) { tree powi_x_ndiv2 = NULL_TREE; @@ -1286,6 +1291,7 @@ gimple_expand_builtin_pow (gimple_stmt_i && cbrtfn && (gimple_val_nonnegative_real_p (arg0) || !HONOR_NANS (mode)) && real_identical (&c2, &c) + && !c2_is_int && optimize_function_for_speed_p (cfun) && powi_cost (n / 3) <= POWI_MAX_MULTS) { --- gcc/testsuite/gcc.dg/pr56125.c.jj 2013-01-28 11:00:04.359814742 +0100 +++ gcc/testsuite/gcc.dg/pr56125.c 2013-01-28 11:00:55.048532118 +0100 @@ -0,0 +1,21 @@ +/* PR tree-optimization/56125 */ +/* { dg-do run } */ +/* { dg-options "-O2 -ffast-math" } */ + +extern void abort (void); +extern double fabs (double); + +__attribute__((cold)) double +foo (double x, double n) +{ + double u = x / (n * n); + return u; +} + +int +main () +{ + if (fabs (foo (29, 2) - 7.25) > 0.001) + abort (); + return 0; +}