We should use GMP/MPFR from inside builtins.c to resolve things like e.g. cos(0.12345) at compile-time. Need to figure out: 1. Whether a certain minimum version of GMP/MPFR is required to avoid known bugs, etc. 2. Whether we should include GMP/MPFR in the svn archive like we do for intl and zlib. 3. Whether GMP/MPFR works on all the platforms/configurations that GCC supports. Are we ready to require a GMP/MPFR port for every port of GCC? 4. If we don't do #2 and there is no system GMP/MPFR or the system lib is too old, or if we trip over #3 and can't have GMP/MPFR, then what? Do we require the user to go get/port it, or silently eliminate this optimization during the build process?
Confirmed. > 3. Whether GMP/MPFR works on all the platforms/configurations that GCC > supports. Are we ready to require a GMP/MPFR port for every port of GCC? As far as I know there is GMP port to all hosts that support GCC and nobody has complained they cannot use gfortran because GMP was not ported yet.
(In reply to comment #0) > > 1. Whether a certain minimum version of GMP/MPFR is required to avoid known > bugs, etc. See my recent patch to toplevel configure.in. THe minimum required versions should be gmp-4.1.x and mpfr-2.2.0. > 2. Whether we should include GMP/MPFR in the svn archive like we do for intl > and zlib. I think that gmp and mpfr would need to be imported into GCC. If you read the gmp webpage, it often contains warnings about using newer versions of GCC to gmp because of bugs. > 3. Whether GMP/MPFR works on all the platforms/configurations that GCC > supports. Are we ready to require a GMP/MPFR port for every port of GCC? > > 4. If we don't do #2 and there is no system GMP/MPFR or the system lib is too > old, or if we trip over #3 and can't have GMP/MPFR, then what? Do we require > the user to go get/port it, or silently eliminate this optimization during the > build process? I could be mistaken, but I believe one can configure gmp for a generic library that does not use any machine (ie., cpu) specific assembly. If you haven't read fortran/{arith.c,simplify.c}, then I'd suggest that you take a look to see what gmp/mpfr can do.
(In reply to comment #2) > (In reply to comment #0) > > > > 1. Whether a certain minimum version of GMP/MPFR is required to avoid known > > bugs, etc. > See my recent patch to toplevel configure.in. THe minimum required > versions should be gmp-4.1.x and mpfr-2.2.0. I see that, but when configure detects the "broken" mpfr, it just prints out a message and proceeds happily. It doesn't disable anything. (???) > If you haven't read fortran/{arith.c,simplify.c}, then I'd suggest > that you take a look to see what gmp/mpfr can do. I looked through those and read through the mpfr docs so I think I have a good idea of what mpfr can do. My main area of concern right now is converting between gcc's REAL_VALUE_TYPE and mpfr_t. I found gfc_conv_mpfr_to_tree() in trans-const.c which uses a string as an intermediate type, is that the most efficient way to convert? Also where is the function that does the reverse, i.e. tree or REAL_VALUE_TYPE to mpfr_t?
(In reply to comment #3) > (In reply to comment #2) >> (In reply to comment #0) >>> >>> 1. Whether a certain minimum version of GMP/MPFR is required to >>> avoid known bugs, etc. >> See my recent patch to toplevel configure.in. THe minimum required >> versions should be gmp-4.1.x and mpfr-2.2.0. > > I see that, but when configure detects the "broken" mpfr, it just prints > out a message and proceeds happily. It doesn't disable anything. (???) It's simply a warning to a user that there are known problems with the version of MPFR on the system. gfortran will work correctly with the buggy mpfr with the exception of some corner cases and PRs that I've fixed using newer features. In particular, there are problems with the old hackish way that gfortran handled subnormal numbers. gfortran also uses functions that are in 2.2.0 that are not available in some of the older versions. See simplify.c(gfc_simplify_nearest). >> If you haven't read fortran/{arith.c,simplify.c}, then I'd suggest >> that you take a look to see what gmp/mpfr can do. > > I looked through those and read through the mpfr docs so I think I have a good > idea of what mpfr can do. My main area of concern right now is converting > between gcc's REAL_VALUE_TYPE and mpfr_t. I found gfc_conv_mpfr_to_tree() in > trans-const.c which uses a string as an intermediate type, is that the most > efficient way to convert? I didn't write that function, and so I have experimented with a replacement. There is mpfr_get_ld(), which converts to a long double. If the data type never exceeds the properties of long double, then one may be able to use mpfr_get_ld() and then fold_convert() the result to the proper type. > Also where is the function that does the reverse, > i.e. tree or REAL_VALUE_TYPE to mpfr_t? gfortran doesn't have a need of going in the opposite direction. gmp/mpfr are used in the frontend for the internal representation of data types. By the time gfortran reaches the functions in trans-*.c, it has done all the constant folding and manipulation of the data types that it can. The trans-*.c functions simply convert gfortran's black and red trees into the tree-ssa form.
(In reply to comment #4) > (In reply to comment #3) > > (In reply to comment #2) > >> (In reply to comment #0) > >>> > > idea of what mpfr can do. My main area of concern right now is converting > > between gcc's REAL_VALUE_TYPE and mpfr_t. I found gfc_conv_mpfr_to_tree() in > > trans-const.c which uses a string as an intermediate type, is that the most > > efficient way to convert? > I didn't write that function, and so I have experimented with a replacement. > There is mpfr_get_ld(), which converts to a long double. If the data type > never exceeds the properties of long double, then one may be able to > use mpfr_get_ld() and then fold_convert() the result to the proper type. I think using long double defeats the whole purpose of using mpfr. We're supposed to avoid relying on the properties of the host's floating point for cross-compilers where the target format is different. Otherwise I could simply call out to e.g. cosl() on the host and avoid the whole mpfr thing (okay okay, assuming cosl() and the rest of c99 math functions exist... which they don't always, but my point about target long double remains.) I was hoping there was an easy was to extract the exponent and mantissa from one of (REAL_VALUE_TYPE/mpft_t) and put them back into the other in a way that preserves everything clean in both directions. > > Also where is the function that does the reverse, > > i.e. tree or REAL_VALUE_TYPE to mpfr_t? > gfortran doesn't have a need of going in the opposite direction. > gmp/mpfr are used in the frontend for the internal representation > of data types. By the time gfortran reaches the functions in > trans-*.c, it has done all the constant folding and manipulation > of the data types that it can. The trans-*.c functions simply > convert gfortran's black and red trees into the tree-ssa form. Okay I hacked up something in the other direction using strings again. If someone comes up with something better, then great. But it's not strictly necessary. I can put the two conversion functions into real.[ch].
> > There is mpfr_get_ld(), which converts to a long double. If the data type > > never exceeds the properties of long double, then one may be able to > > use mpfr_get_ld() and then fold_convert() the result to the proper type. > > I think using long double defeats the whole purpose of using mpfr. It appears you misread what I wrote (or meant to write). "If the data type never exceeds the properties of long double" applies to a cross compiler as well where "data type" is on the target and "long double" is on the host. > We're > supposed to avoid relying on the properties of the host's floating point for > cross-compilers where the target format is different. The host's long double is simply an intermediate representation of the value. It is the responsibility of the fold_convert to get the right target representation. This is no different than using strings as the intermediate. > I was hoping there was an easy was to extract the exponent and mantissa from > one of (REAL_VALUE_TYPE/mpft_t) and put them back into the other in a way that > preserves everything clean in both directions. See trans-intrinsics.c (prepare_arg_info), although I'm get ready to submit a patch that removes that function. > > > Also where is the function that does the reverse, > > > i.e. tree or REAL_VALUE_TYPE to mpfr_t? > > gfortran doesn't have a need of going in the opposite direction. > > gmp/mpfr are used in the frontend for the internal representation > > of data types. By the time gfortran reaches the functions in > > trans-*.c, it has done all the constant folding and manipulation > > of the data types that it can. The trans-*.c functions simply > > convert gfortran's black and red trees into the tree-ssa form. > > Okay I hacked up something in the other direction using strings again. If > someone comes up with something better, then great. But it's not strictly > necessary. I can put the two conversion functions into real.[ch]. I would be interested in seeing the functions because gfortran currently can't constant fold a TRANSFER() of the form real, parameter :: x = transfer(1234,x) This is a bitwise copy of the integer 1234 into x. In gfortran 1235 is a gmp mpz_t type and x is an mpfr mpfr_t type. Emulating the bitwise copy will require strings manipulations.
(In reply to comment #6) > > > There is mpfr_get_ld(), which converts to a long double. If the data type > > > never exceeds the properties of long double, then one may be able to > > > use mpfr_get_ld() and then fold_convert() the result to the proper type. > > > > I think using long double defeats the whole purpose of using mpfr. > It appears you misread what I wrote (or meant to write). "If the data > type never exceeds the properties of long double" applies to a cross > compiler as well where "data type" is on the target and "long double" > is on the host. > > We're > > supposed to avoid relying on the properties of the host's floating point for > > cross-compilers where the target format is different. > The host's long double is simply an intermediate representation of the > value. It is the responsibility of the fold_convert to get the right > target representation. This is no different than using strings as the > intermediate. I want the optimization to work always, not just in certain host/target combinations. So I'll use strings, no big deal.
Patch posted here: http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00360.html Need to decide whether we're including GMP/MPFR in GCC repo or we need configure goo to detect if we have it.
I decided to explore including GMP/MPFR in the GCC tree. Dependency PR 29405 opened to track that enhancement.
No longer relying on PR29405. Instead we'll force the person building GCC to acquire GMP/MPFR themselves.
Updated patch posted here: http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00757.html
Third patch revision posted here: http://gcc.gnu.org/ml/gcc-patches/2006-10/msg01039.html
Subject: Bug 29335 Author: ghazi Date: Mon Oct 23 20:24:55 2006 New Revision: 117983 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117983 Log: PR middle-end/29335 * builtins.c (fold_builtin_sin, fold_builtin_cos, fold_builtin_tan): Fold all constant arguments. Take a "type" argument as necessary. (do_mpfr_arg1): New. * real.c, real.h (real_from_mpfr, mpfr_from_real): New. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/real.c trunk/gcc/real.h
Subject: Bug 29335 Author: ghazi Date: Tue Oct 24 17:44:36 2006 New Revision: 118009 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118009 Log: PR middle-end/29335 * builtins.c (fold_builtin_sin, fold_builtin_atan): Remove. (do_mpfr_arg1): Add `min', `max' and `inclusive' arguments. Update all callers. (BUILT_IN_SIN, BUILT_IN_ATAN): Handle in main switch. (BUILT_IN_ASIN, BUILT_IN_ACOS, BUILT_IN_ATAN, BUILT_IN_ASINH, BUILT_IN_ACOSH, BUILT_IN_ATANH, BUILT_IN_SINH, BUILT_IN_COSH, BUILT_IN_TANH): Calculate compile-time arguments using MPFR. testsuite: * gcc.dg/torture/builtin-math-3.c: New test. Added: trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 29335 Author: ghazi Date: Wed Oct 25 20:44:09 2006 New Revision: 118042 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118042 Log: PR middle-end/29335 * builtins.c (fold_builtin_cbrt, fold_builtin_logarithm): Calculate compile-time constants using MPFR. (fold_builtin_1): Likewise handle BUILT_IN_ERF, BUILT_IN_ERFC, BUILT_IN_EXPM1 and BUILT_IN_LOG1P. testsuite: * gcc.dg/torture/builtin-math-2.c (TESTIT): Use new helper macro. Add checks for log, log2, log10 and log1p. * gcc.dg/torture/builtin-math-3.c: Add checks for -0.0 everywhere we already test 0.0. Add checks for expm1, log, log2, log10, log1p, cbrt, erf and erfc. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/torture/builtin-math-2.c trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
I'm getting wierd NaN results when I hook up __builtin_lgamma to mpfr_lngamma. I can expose the problem using a standlone C program calling mpfr like so. Results are first, C testcase is second. Now I know lgamma/mpfr_lngamma are both documented to barf on negative integers. But as you can see, I'm passing x.5 in every case. Seems like any time "x" is an even number I get a NaN. I wonder if this is a bug in mpfr, or my mistake? (I tried mpfr-2.2.0 with and without the cumulative patch. I got the problem in both cases.) Can anyone else reproduce this? lgamma(-4.50) = -2.813084 mpfr_lngamma(-4.50) = @NaN@ lgamma(-3.50) = -1.309007 mpfr_lngamma(-3.50) = -1.3090066849930420 lgamma(-2.50) = -0.056244 mpfr_lngamma(-2.50) = @NaN@ lgamma(-1.50) = 0.860047 mpfr_lngamma(-1.50) = 8.6004701537648098e-1 lgamma(-0.50) = 1.265512 mpfr_lngamma(-0.50) = @NaN@ #include <stdio.h> #include <math.h> #include <gmp.h> #include <mpfr.h> #define TESTIT(X) do { \ printf ("lgamma(%.2f) = %f\n", (X), gamma(X)); \ mpfr_set_d(m, (X), GMP_RNDN); \ mpfr_lngamma(m, m, GMP_RNDN); \ printf ("mpfr_lngamma(%.2f) = ", (X)); \ mpfr_out_str (stdout, 10, 0, m, GMP_RNDN); \ putc ('\n', stdout); \ putc ('\n', stdout); \ } while (0) int main() { mpfr_t m; mpfr_init2(m, 53); TESTIT(-4.5); TESTIT(-3.5); TESTIT(-2.5); TESTIT(-1.5); TESTIT(-0.5); mpfr_clear(m); return 0; }
Subject: Re: transcendental functions with constant arguments should be resolved at compile-time On Sat, Oct 28, 2006 at 03:20:11AM -0000, ghazi at gcc dot gnu dot org wrote: > > > ------- Comment #16 from ghazi at gcc dot gnu dot org 2006-10-28 03:20 ------- > I'm getting wierd NaN results when I hook up __builtin_lgamma to mpfr_lngamma. > I can expose the problem using a standlone C program calling mpfr like so. > Results are first, C testcase is second. Now I know lgamma/mpfr_lngamma are > both documented to barf on negative integers. But as you can see, I'm passing > x.5 in every case. Seems like any time "x" is an even number I get a NaN. I > wonder if this is a bug in mpfr, or my mistake? (I tried mpfr-2.2.0 with and > without the cumulative patch. I got the problem in both cases.) Can anyone > else reproduce this? > > lgamma(-4.50) = -2.813084 > mpfr_lngamma(-4.50) = @NaN@ > Yes, I can reproduce the NaN. In fact, any negative value gives a NaN.
(In reply to comment #17) > Yes, I can reproduce the NaN. In fact, any negative value > gives a NaN. Not any negative value, but in lngamma.c: /* if x < 0 and -2k-1 <= x <= -2k, then lngamma(x) = NaN */ probably because the gamma value is negative. This is because MPFR defines lngamma as log(gamma(x)) while the C standard defines it as log|gamma(x)|. I wonder if this should be regarded as a bug or if a new function (say, mpfr_lgamma) should be defined in MPFR (in which case, not before 2.3.0). Do other standards (other languages) define such a function, either as log(gamma(x)) or as log|gamma(x)|? Also, warning! The mpfr_erfc is incomplete for x >= 4096: There is an infinite loop in the 2.2 branch. This problem is now detected in the trunk, and until this is completely fixed, a NaN is returned with the MPFR erange flag set. This should be in the 2.2 branch in a few days (and a preversion of MPFR 2.2.1 will come several days after that).
(In reply to comment #18) > (In reply to comment #17) > > Yes, I can reproduce the NaN. In fact, any negative value > > gives a NaN. > Not any negative value, but in lngamma.c: > /* if x < 0 and -2k-1 <= x <= -2k, then lngamma(x) = NaN */ > probably because the gamma value is negative. This is because MPFR defines > lngamma as log(gamma(x)) while the C standard defines it as log|gamma(x)|. I > wonder if this should be regarded as a bug or if a new function (say, > mpfr_lgamma) should be defined in MPFR (in which case, not before 2.3.0). The documenation in MPFR says: -- Function: int mpfr_lngamma (mpfr_t ROP, mpfr_t OP, mp_rnd_t RND) Set ROP to the value of the Gamma function on OP, and its logarithm respectively, rounded in the direction RND. When OP is a negative integer, NaN is returned. It only talked about negative integers, and I glossed over the fact that it left out the absolute value that C does. So it was pilot error, but I think a clarification would help. Many times in the docs MPFR takes pains to follow the C99 standard, e.g. the inputs to atan2 or pow. Where you deviate from it should also be noted. Or you could consider it a bug and fix it. :-) Anyway, I think I can hand wrap mpfr_log(mpfr_abs(mpfr_gamma)) myself right? > Also, warning! The mpfr_erfc is incomplete for x >= 4096: There is an infinite > loop in the 2.2 branch. This problem is now detected in the trunk, and until > this is completely fixed, a NaN is returned with the MPFR erange flag set. This > should be in the 2.2 branch in a few days (and a preversion of MPFR 2.2.1 will > come several days after that). If it returns NaN for now that's fine since GCC avoids any transformation that returns NaN or Inf. Glad to hear a new version is coming out. If you make a prerelease tarball available somewhere I'd like to try it with mainline GCC.
(In reply to comment #19) > The documenation in MPFR says: > -- Function: int mpfr_lngamma (mpfr_t ROP, mpfr_t OP, mp_rnd_t RND) > Set ROP to the value of the Gamma function on OP, and its > logarithm respectively, rounded in the direction RND. When OP is > a negative integer, NaN is returned. > > It only talked about negative integers, AFAIK, this was mainly for Gamma(negative integer). But this is also true for lngamma(negative integer). But the point is that if gamma(x) is negative, then lngamma(x) is NaN since the logarithm of a negative value is NaN. But that's why the C standard defines lgamma as log|gamma(x)| instead of log(gamma(x)). > and I glossed over the fact that it > left out the absolute value that C does. So it was pilot error, but I think a > clarification would help. Many times in the docs MPFR takes pains to follow > the C99 standard, e.g. the inputs to atan2 or pow. Where you deviate from it > should also be noted. I agree. And I think that none of the MPFR developers were aware of this problem (I didn't notice the difference when I was looking for C functions that were missing in MPFR). I posted a mail about that on the MPFR mailing-list. > Or you could consider it a bug and fix it. :-) I think this is the best solution, in particular because this would change only NaN values. > Anyway, I think I can hand wrap mpfr_log(mpfr_abs(mpfr_gamma)) myself right? Probably not a good idea, because I think that mpfr_gamma may overflow, though the final result may be in the double-precision range. > Glad to hear a new version is coming out. If you make a prerelease tarball > available somewhere I'd like to try it with mainline GCC. OK, I hope I won't forget to announce it in the gcc dev mailing-list.
(In reply to comment #20) > I agree. And I think that none of the MPFR developers were aware of this > problem (I didn't notice the difference when I was looking for C functions > that were missing in MPFR). Since you mentioned C functions missing in MPFR, what are your plans for the Bessel functions? I'd like to hook up builtins j0/j1/jn/y0/y1/yn. Thanks.
(In reply to comment #21) > Since you mentioned C functions missing in MPFR, what are your plans for the > Bessel functions? I'd like to hook up builtins j0/j1/jn/y0/y1/yn. Thanks. They're in the TODO, but there are no plans yet to implement them.
Subject: Bug 29335 Author: ghazi Date: Sun Oct 29 02:02:10 2006 New Revision: 118129 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118129 Log: PR middle-end/29335 * builtins.c (do_mpfr_arg2, fold_builtin_hypot): New. (fold_builtin_pow): Evaluate constant arguments at compile-time using MPFR. (fold_builtin_1): Handle BUILT_IN_ATAN2 and BUILT_IN_HYPOT. (do_mpfr_ckconv): New helper function. (do_mpfr_arg1): Use do_mpfr_ckconv. (do_mpfr_arg2): New. testsuite: * gcc.dg/builtins-20.c: Add tests for hypot. * gcc.dg/torture/builtin-math-2.c (TESTIT2): New. Add tests for two-argument builtins. * gcc.dg/torture/builtin-math-3.c (TESTIT_R): Renamed from TESTIT2. Update all callers. (TESTIT2, TESTIT2_R): New helper macros. Add testcases for pow, hypot and atan2. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/builtins-20.c trunk/gcc/testsuite/gcc.dg/torture/builtin-math-2.c trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
Subject: Bug 29335 Author: ghazi Date: Mon Oct 30 20:21:59 2006 New Revision: 118200 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118200 Log: PR middle-end/29335 * builtins.c (fold_builtin_1): Evaluate tgamma using MPFR. testsuite: * gcc.dg/torture/builtin-math-2.c: Add tgamma tests. * gcc.dg/torture/builtin-math-3.c: Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/torture/builtin-math-2.c trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
(In reply to comment #18) > (In reply to comment #17) > This is because MPFR defines > lngamma as log(gamma(x)) while the C standard defines it as log|gamma(x)|. I > wonder if this should be regarded as a bug or if a new function (say, > mpfr_lgamma) should be defined in MPFR (in which case, not before 2.3.0). Do > other standards (other languages) define such a function, either as > log(gamma(x)) or as log|gamma(x)|? As I think about it more, I'm leaning toward having a new function mpfr_lgamma. This is because if we want this mpfr function to mimic the behavior of lgamma, we need some mechanism to retrieve the value of "signgam". So maybe the interface you suggested at the bottom of this link would be best where we retrieve an int* from mpfr_lgamma to determine "signgam": http://sympa.loria.fr/wwsympa/arc/mpfr/2006-10/msg00033.html
(In reply to comment #25) > As I think about it more, I'm leaning toward having a new function mpfr_lgamma. > This is because if we want this mpfr function to mimic the behavior of lgamma, > we need some mechanism to retrieve the value of "signgam". So maybe the > interface you suggested at the bottom of this link would be best where we > retrieve an int* from mpfr_lgamma to determine "signgam": > http://sympa.loria.fr/wwsympa/arc/mpfr/2006-10/msg00033.html Yes, it's true that it is useful to have this value. But determining it separately is quite easy, without taking a noticeable additional time in average.
(In reply to comment #26) > Yes, it's true that it is useful to have this value. But determining it > separately is quite easy, without taking a noticeable additional time in > average. It's likely that I'll end up doing it, so would you please tell me how? Thanks.
(In reply to comment #27) > It's likely that I'll end up doing it, so would you please tell me how? According to the C rationale (I haven't checked), the sign of gamma(x) is -1 if [iff] x < 0 && remainder(floor(x), 2) != 0. But if x is a non-positive integer, the sign of gamma(x) isn't defined. Handle these cases first. The test x < 0 is easy to do. In MPFR, you can compute floor(x) (or trunc(x)) with the precision min(PREC(x),max(EXP(x),MPFR_PREC_MIN)), but then, there's no direct function to decide whether the result is even or odd (I thought we added this, but this isn't the case). The solution can be to divide x by 2 (this is exact, except in case of underflow) and call mpfr_frac directly. If the result is between -0.5 and 0, then gamma(x) is negative. If the result is between -1 and -0.5, then gamma(x) is positive. So, a 2-bit precision for mpfr_frac should be sufficient (as -0.5 is representable in this precision), but choose a directed rounding (not GMP_RNDN) for that. Then you can just do a comparison with -0.5; the case of equality with -0.5 depends on the chosen rounding (if you obtain -0.5, then it is an inexact result since x is not an integer). For instance, if you choose GMP_RNDZ, then a result > -0.5 means that gamma(x) is negative, and a result <= -0.5 means that gamma(x) is positive.
Subject: Bug 29335 Author: ghazi Date: Thu Nov 2 03:20:49 2006 New Revision: 118409 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118409 Log: PR middle-end/29335 * builtins.c (do_mpfr_sincos): New. (fold_builtin_1): Use it to fold builtin sincos. testsuite: * gcc.dg/torture/builtin-math-3.c: Fix semicolons. (TESTIT_2P, TESTIT_2P_R): New macros. Test sincos. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
(In reply to comment #28) > (In reply to comment #27) > > It's likely that I'll end up doing it, so would you please tell me how? > According to the C rationale (I haven't checked), the sign of gamma(x) is -1 if > [iff] x < 0 && remainder(floor(x), 2) != 0. But if x is a non-positive integer, > the sign of gamma(x) isn't defined. Handle these cases first. > The test x < 0 is easy to do. In MPFR, you can compute floor(x) (or trunc(x)) > with the precision min(PREC(x),max(EXP(x),MPFR_PREC_MIN)), but then, there's no > direct function to decide whether the result is even or odd (I thought we added > this, but this isn't the case). The solution can be to divide x by 2 (this is > exact, except in case of underflow) and call mpfr_frac directly. If the result > is between -0.5 and 0, then gamma(x) is negative. If the result is between -1 > and -0.5, then gamma(x) is positive. So, a 2-bit precision for mpfr_frac should > be sufficient (as -0.5 is representable in this precision), but choose a > directed rounding (not GMP_RNDN) for that. Then you can just do a comparison > with -0.5; the case of equality with -0.5 depends on the chosen rounding (if > you obtain -0.5, then it is an inexact result since x is not an integer). For > instance, if you choose GMP_RNDZ, then a result > -0.5 means that gamma(x) is > negative, and a result <= -0.5 means that gamma(x) is positive. Vincent, thank you for the detailed instructions. I also read your two possible solutions posted here: http://sympa.loria.fr/wwsympa/arc/mpfr/2006-10/msg00036.html I could be satisfied with either solution from that message. However in the case of choice 1, I feel the calculation of signgam should be provided from a function call in the library rather than forcing each user to write a routine to calculate it. IMHO, I'd rather leave the math to the mathematicians. :-) E.g. you could add a function mpfr_signgam() that figures out the value for the user and thereby leave the interface for mpfr_lngamma() unchanged. Choice 2 also solves the issue by providing the int* parameter. Thanks.
(In reply to comment #30) So, I don't think a mpfr_signgam alone would really be useful. So, I think that choice 2 would be better.
(In reply to comment #31) > (In reply to comment #30) > So, I don't think a mpfr_signgam alone would really be useful. So, I think that > choice 2 would be better. Okay, sounds fine. Would this make it into 2.2.1 or 2.3? And do you have any very rough timeframe for each release so I can plan accordingly for gcc? Thanks.
(In reply to comment #32) > (In reply to comment #31) > > (In reply to comment #30) > > So, I don't think a mpfr_signgam alone would really be useful. So, I think that > > choice 2 would be better. > > Okay, sounds fine. Would this make it into 2.2.1 or 2.3? For compatibility reasons (i.e. the 2.2.x versions must have the same interface), this can only be in 2.3.0. > And do you have any very rough timeframe for each release so I can plan > accordingly for gcc? A pre-release of 2.2.1 should be there soon; there are still bugs being fixed (they will be ported to the 2.2 branch once this is complete). I don't know about 2.3.0; probably in a few months, because there currently aren't many differences from the 2.2 branch.
(In reply to comment #33) > > Okay, sounds fine. Would this make it into 2.2.1 or 2.3? > For compatibility reasons (i.e. the 2.2.x versions must have the same > interface), this can only be in 2.3.0. > > And do you have any very rough timeframe for each release so I can plan > > accordingly for gcc? > A pre-release of 2.2.1 should be there soon; there are still bugs being fixed > (they will be ported to the 2.2 branch once this is complete). > I don't know about 2.3.0; probably in a few months, because there currently > aren't many differences from the 2.2 branch. Well, maybe if the Bessel functions were added to 2.3.0 it would be sufficiently different from 2.2.x to warrent a release. See comment#22. :-)
Mine, obviously. Almost done, targetted to gcc-4.3.
Subject: Bug 29335 Author: ghazi Date: Tue Dec 26 19:03:17 2006 New Revision: 120211 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120211 Log: PR middle-end/29335 * builtins.c (do_mpfr_arg1, do_mpfr_arg2, do_mpfr_arg3, do_mpfr_sincos): Ensure target base equals two. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c
Done. Remaining functions (Bessel & lgamma) await implementation in MPFR and marked for PR30250 & PR30251.
Subject: Bug 29335 Author: ghazi Date: Sat Jan 20 00:33:00 2007 New Revision: 120993 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120993 Log: PR middle-end/29335 * builtins.c (fold_builtin_1): Handle builtin fdim. testsuite: * gcc.dg/torture/builtin-math-3.c: Test fdim. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
Subject: Bug 29335 Author: ghazi Date: Wed Jan 31 15:06:19 2007 New Revision: 121423 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=121423 Log: PR middle-end/29335 * builtins.c (fold_builtin_sqrt): Use MPFR for constant args. testsuite: * gcc.dg/torture/builtin-math-2.c: Add sqrt cases. * gcc.dg/torture/builtin-math-3.c: Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/torture/builtin-math-2.c trunk/gcc/testsuite/gcc.dg/torture/builtin-math-3.c
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Marked for reference. Resolved as fixed @bugzilla.