Here's a three line patch to implement constant folding for fmod, fmodf and fmodl, which resolves an enhancement request from 2012.
The following patch has been tested on x86_64-pc-linux-gnu with a make bootstrap and make -k check with no new failures. Ok for mainline? 2020-06-08 Roger Sayle <ro...@nextmovesoftware.com> gcc/ChangeLog PR middle-end/53267 * fold-const-call.c (fold_const_call_sss) [CASE_CFN_FMOD]: Support evaluation of fmod/fmodf/fmodl at compile-time. gcc/testsuite/ChangeLog * gcc.dg/builtins-70.c: New test. Roger -- Roger Sayle NextMove Software Cambridge, UK
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index a1d70b6..d6cb9b1 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -1375,6 +1375,9 @@ fold_const_call_sss (real_value *result, combined_fn fn, CASE_CFN_FDIM: return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format); + CASE_CFN_FMOD: + return do_mpfr_arg2 (result, mpfr_fmod, arg0, arg1, format); + CASE_CFN_HYPOT: return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
/* Copyright (C) 2021 Free Software Foundation. Check that constant folding of built-in fmod functions doesn't break anything and produces the expected results. /* { dg-do link } */ /* { dg-options "-O2 -ffast-math" } */ extern void link_error(void); extern double fmod(double,double); extern float fmodf(float,float); extern long double fmodl(long double,long double); int main() { if (fmod (6.5, 2.3) < 1.8999 || fmod (6.5, 2.3) > 1.9001) link_error (); if (fmod (-6.5, 2.3) < -1.9001 || fmod (-6.5, 2.3) > -1.8999) link_error (); if (fmod (6.5, -2.3) < 1.8999 || fmod (6.5, -2.3) > 1.9001) link_error (); if (fmod (-6.5, -2.3) < -1.9001 || fmod (-6.5, -2.3) > -1.8999) link_error (); if (fmodf (6.5f, 2.3f) < 1.8999f || fmodf (6.5f, 2.3f) > 1.9001f) link_error (); if (fmodf (-6.5f, 2.3f) < -1.9001f || fmodf (-6.5f, 2.3f) > -1.8999f) link_error (); if (fmodf (6.5f, -2.3f) < 1.8999f || fmodf (6.5f, -2.3f) > 1.9001f) link_error (); if (fmodf (-6.5f, -2.3f) < -1.9001f || fmodf (-6.5f, -2.3f) > -1.8999f) link_error (); if (fmodl (6.5l, 2.3l) < 1.8999l || fmod (6.5l, 2.3l) > 1.9001l) link_error (); if (fmodl (-6.5l, 2.3l) < -1.9001l || fmod (-6.5l, 2.3l) > -1.8999l) link_error (); if (fmodl (6.5l, -2.3l) < 1.8999l || fmod (6.5l, -2.3l) > 1.9001l) link_error (); if (fmodl (-6.5l, -2.3l) < -1.9001l || fmod (-6.5l, -2.3l) > -1.8999l) link_error (); return 0; }