From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19773 invoked by alias); 17 May 2007 10:15:42 -0000 Received: (qmail 19762 invoked by uid 22791); 17 May 2007 10:15:40 -0000 X-Spam-Check-By: sourceware.org Received: from wr-out-0506.google.com (HELO wr-out-0506.google.com) (64.233.184.224) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 17 May 2007 10:15:34 +0000 Received: by wr-out-0506.google.com with SMTP id 57so476026wri for ; Thu, 17 May 2007 03:15:32 -0700 (PDT) Received: by 10.67.115.19 with SMTP id s19mr170461ugm.1179396931591; Thu, 17 May 2007 03:15:31 -0700 (PDT) Received: by 10.67.16.4 with HTTP; Thu, 17 May 2007 03:15:31 -0700 (PDT) Message-ID: <84fc9c000705170315g15b30422ga7884f0779c17003@mail.gmail.com> Date: Thu, 17 May 2007 10:15:00 -0000 From: "Richard Guenther" To: "Kaveh R. GHAZI" Subject: Re: [PATCH]: PR middle-end/30250, use MPFR for lgamma_r/gamma_r Cc: gcc-patches@gcc.gnu.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-05/txt/msg01117.txt.bz2 On 5/7/07, Kaveh R. GHAZI wrote: > This patch partly addresses PR middle-end/30250. It uses MPFR to > evaluate the reentrant lgamma_r/gamma_r builtins at compile-time when > supplied with constant args. The reentrant versions supply signgam as > a pointer parameter, and they were slightly easier to implement than > doing the regular lgamma functions, so I did them first. (The plain > lgamma/gamma patch will come hopefully soon.) > > The patch requires several others to apply cleanly: > http://gcc.gnu.org/ml/gcc-patches/2007-04/msg01624.html > http://gcc.gnu.org/ml/gcc-patches/2007-04/msg01663.html > http://gcc.gnu.org/ml/gcc-patches/2007-05/msg00297.html > http://gcc.gnu.org/ml/gcc-patches/2007-05/msg00320.html > > Patch below tested on sparc-sun-solaris2.10 in conjuction with the > above four patches, no regressions and the new testcases all pass. I > also ran a preliminary version of my plain lgamma/gamma patch against > the FP accuracy testsuite to check whether MPFR's lgamma function was > producing correct results back to GCC. It was, all inputs generated > "perfect" results. > > Okay for mainline? > > Thanks, > --Kaveh > > :ADDPATCH middle-end: > > > 2007-05-07 Kaveh R. Ghazi > > PR middle-end/30250 > * builtins.c (do_mpfr_lgamma_r): New. > (fold_builtin_2): Handle builtin gamma_r/lgamma_r. > * tree.h (CASE_FLT_FN_REENT): New. > > testsuite: > * gcc.dg/torture/builtin-math-2.c: Add gamma_r/lgamma_r tests. > * gcc.dg/torture/builtin-math-4.c: Likewise. > > diff -rup orig/egcc-SVN20070505/gcc/builtins.c egcc-SVN20070505/gcc/builtins.c > --- orig/egcc-SVN20070505/gcc/builtins.c 2007-05-06 23:43:01.621873788 -0400 > +++ egcc-SVN20070505/gcc/builtins.c 2007-05-07 00:55:32.966335476 -0400 > @@ -234,6 +234,7 @@ static tree do_mpfr_bessel_n (tree, tree > int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t), > const REAL_VALUE_TYPE *, bool); > static tree do_mpfr_remquo (tree, tree, tree); > +static tree do_mpfr_lgamma_r (tree, tree, tree); > #endif > > /* Return true if NODE should be considered for inline expansion regardless > @@ -9862,6 +9863,13 @@ fold_builtin_2 (tree fndecl, tree arg0, > && validate_arg(arg1, REAL_TYPE)) > return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder); > break; > + > + CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */ > + CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */ > + if (validate_arg (arg0, REAL_TYPE) > + && validate_arg(arg1, POINTER_TYPE)) > + return do_mpfr_lgamma_r (arg0, arg1, type); > + break; > #endif > > CASE_FLT_FN (BUILT_IN_ATAN2): > @@ -12616,4 +12624,66 @@ do_mpfr_remquo (tree arg0, tree arg1, tr > } > return result; > } > + > +/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the > + resulting value as a tree with type TYPE. The mpfr precision is > + set to the precision of TYPE. We assume that this mpfr function > + returns zero if the result could be calculated exactly within the > + requested precision. In addition, the integer pointer represented > + by ARG_SG will be dereferenced and set to the appropriate signgam > + (-1,1) value. */ > + > +static tree > +do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type) > +{ > + tree result = NULL_TREE; > + > + STRIP_NOPS (arg); > + > + /* To proceed, MPFR must exactly represent the target floating point > + format, which only happens when the target base equals two. */ > + if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2 > + && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)) > + { > + const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg); > + > + /* In addition to NaN and Inf, the argument cannot be zero or a > + negative integer. */ > + if (!real_isnan (ra) && !real_isinf (ra) > + && ra->cl != rvc_zero > + && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type)))) > + { > + const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p; > + int inexact, sg; > + mpfr_t m; > + tree result_lg; > + > + mpfr_init2 (m, prec); > + mpfr_from_real (m, ra, GMP_RNDN); > + mpfr_clear_flags (); > + inexact = mpfr_lgamma (m, &sg, m, GMP_RNDN); > + result_lg = do_mpfr_ckconv (m, type, inexact); > + mpfr_clear (m); > + if (result_lg) > + { > + /* Dereference the arg_sg pointer argument. */ > + arg_sg = build_fold_indirect_ref (arg_sg); > + /* Proceed iff a valid pointer type was passed in. */ > + if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sg)) == integer_type_node) This check should be done earlier based on the pointed to type of the argument. Ok with this change. Please make sure to XFAIL testcases that rely on new mpfr. Thanks, Richard. :REVIEWMAIL: