From patchwork Wed Jun 8 16:56:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Schmidt X-Patchwork-Id: 99507 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 29A7AB6F57 for ; Thu, 9 Jun 2011 02:58:12 +1000 (EST) Received: (qmail 12653 invoked by alias); 8 Jun 2011 16:58:09 -0000 Received: (qmail 12642 invoked by uid 22791); 8 Jun 2011 16:58:07 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL, BAYES_00, MAY_BE_FORGED, TW_HF, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e9.ny.us.ibm.com (HELO e9.ny.us.ibm.com) (32.97.182.139) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Jun 2011 16:57:53 +0000 Received: from d01relay02.pok.ibm.com (d01relay02.pok.ibm.com [9.56.227.234]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p58GRMPJ000969 for ; Wed, 8 Jun 2011 12:27:22 -0400 Received: from d03av05.boulder.ibm.com (d03av05.boulder.ibm.com [9.17.195.85]) by d01relay02.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p58Gv1uc313510 for ; Wed, 8 Jun 2011 12:57:12 -0400 Received: from d03av05.boulder.ibm.com (loopback [127.0.0.1]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p58GufJ9000361 for ; Wed, 8 Jun 2011 10:56:42 -0600 Received: from [9.10.86.209] (tepot-pc.rchland.ibm.com [9.10.86.209] (may be forged)) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p58GudS6032328; Wed, 8 Jun 2011 10:56:40 -0600 Subject: [PATCH] Fix PR lto/49302 From: "William J. Schmidt" To: gcc-patches@gcc.gnu.org Cc: richard.guenther@gmail.com Date: Wed, 08 Jun 2011 11:56:32 -0500 Message-Id: <1307552192.4798.55.camel@L3G5336.ibm.com> Mime-Version: 1.0 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 This patch adds code to the cse_sincos pass to expand builtin cabs (x) into sqrt (r*r + i*i), where r = realpart(x) and i = imagpart(x). This is usually handled by fold_builtin_cabs; however, PR49302 shows a case where compile flags of -O0 -flto combined with link flags of -O2 -ffast-math allow cabs to leak through. Test case gcc.dg/lto/20110201-1_0.c indicates that cabs is not guaranteed to be implemented in libm, so -lm is not specified for the test. This patch does not present a perfect solution, in that it will produce a builtin call to sqrt for targets that don't have a hardware sqrt instruction. Although sqrt should always be provided by libm, this test case will fail since -lm is not specified. Note that this is not new behavior introduced by the patch, so this is probably OK; it just restores what was happening prior to the pow/powi fixes for PR46728. The test case has been verified fixed on x86_64-linux, and verified to fail only with an unsatisfied reference to sqrt on powerpc64-linux. Bootstrapped and regtested on both platforms. OK for trunk? Thanks, Bill 2011-06-08 Bill Schmidt PR lto/49302 * tree-ssa-math-opts.c (build_and_insert_ref): New. (gimple_expand_builtin_cabs): New. (execute_cse_sincos): Add case for BUILT_IN_CABS. Index: gcc/tree-ssa-math-opts.c =================================================================== --- gcc/tree-ssa-math-opts.c (revision 174765) +++ gcc/tree-ssa-math-opts.c (working copy) @@ -1070,6 +1070,22 @@ build_and_insert_binop (gimple_stmt_iterator *gsi, return result; } +/* Build a gimple reference operation with the given CODE and argument + ARG, assigning the result to a new SSA name for variable TARGET. + Insert the statement prior to GSI's current position, and return + the fresh SSA name.*/ + +static inline tree +build_and_insert_ref (gimple_stmt_iterator *gsi, location_t loc, tree type, + tree target, enum tree_code code, tree arg0) +{ + tree result = make_ssa_name (target, NULL); + gimple stmt = gimple_build_assign (result, build1 (code, type, arg0)); + gimple_set_location (stmt, loc); + gsi_insert_before (gsi, stmt, GSI_SAME_STMT); + return result; +} + /* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI with location info LOC. If possible, create an equivalent and less expensive sequence of statements prior to GSI, and return an @@ -1306,6 +1322,41 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *g return NULL_TREE; } +/* ARG is the argument to a cabs builtin call in GSI with location info + LOC. Create a sequence of statements prior to GSI that calculates + sqrt(R*R + I*I), where R and I are the real and imaginary components + of ARG, respectively. Return an expression holding the result. */ + +static tree +gimple_expand_builtin_cabs (gimple_stmt_iterator *gsi, location_t loc, tree arg) +{ + tree target, real_part, imag_part, addend1, addend2, sum, result, sqrtfn; + tree type = TREE_TYPE (arg); + + gcc_assert (TREE_CODE (type) == COMPLEX_TYPE); + type = TREE_TYPE (type); + sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); + + if (!sqrtfn) + return NULL_TREE; + + target = create_tmp_var (type, "cabs"); + add_referenced_var (target); + + real_part = build_and_insert_ref (gsi, loc, type, target, + REALPART_EXPR, arg); + addend1 = build_and_insert_binop (gsi, loc, target, MULT_EXPR, + real_part, real_part); + imag_part = build_and_insert_ref (gsi, loc, type, target, + IMAGPART_EXPR, arg); + addend2 = build_and_insert_binop (gsi, loc, target, MULT_EXPR, + imag_part, imag_part); + sum = build_and_insert_binop (gsi, loc, target, PLUS_EXPR, addend1, addend2); + result = build_and_insert_call (gsi, loc, &target, sqrtfn, sum); + + return result; +} + /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1 on the SSA_NAME argument of each of them. Also expand powi(x,n) into an optimal number of multiplies, when n is a constant. */ @@ -1388,6 +1439,34 @@ execute_cse_sincos (void) } break; + CASE_FLT_FN (BUILT_IN_CABS): + /* This code is usually redundant with fold_builtin_cabs. + There is a possible edge case where compile flags + include -O0 -flto, while link flags include -O2 + -ffast-math. In this case, the fold does not occur + and cabs can leak through. Since it is not guaranteed + to be implemented in libm on all targets, we need to + lower it here. + + See test case gcc.dg/lto/20110201-1_0.c. */ + if (!flag_unsafe_math_optimizations + || !optimize_function_for_speed_p (cfun)) + break; + + arg0 = gimple_call_arg (stmt, 0); + loc = gimple_location (stmt); + result = gimple_expand_builtin_cabs (&gsi, loc, arg0); + + if (result) + { + tree lhs = gimple_get_lhs (stmt); + gimple new_stmt = gimple_build_assign (lhs, result); + gimple_set_location (new_stmt, loc); + unlink_stmt_vdef (stmt); + gsi_replace (&gsi, new_stmt, true); + } + break; + default:; } }