aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.cc
diff options
context:
space:
mode:
authorRaoni Fassina Firmino <raoni@linux.ibm.com>2022-01-13 14:08:53 -0300
committerSegher Boessenkool <segher@kernel.crashing.org>2022-01-24 17:00:11 +0000
commit4343f5e256791a5abaaef29fe1f831a03bab129e (patch)
tree5847305e8cfd8ad62d664399b54252788735ee65 /gcc/builtins.cc
parentb1aa2a3cf1ba233ccd5a49fde85a2ca7e5f620e9 (diff)
downloadgcc-4343f5e256791a5abaaef29fe1f831a03bab129e.zip
gcc-4343f5e256791a5abaaef29fe1f831a03bab129e.tar.gz
gcc-4343f5e256791a5abaaef29fe1f831a03bab129e.tar.bz2
rtl: builtins: (not just) rs6000: Add builtins for fegetround, feclearexcept and feraiseexcept [PR94193]
This optimizations were originally in glibc, but was removed and suggested that they were a good fit as gcc builtins[1]. feclearexcept and feraiseexcept were extended (in comparison to the glibc version) to accept any combination of the accepted flags, not limited to just one flag bit at a time anymore. The builtin expanders needs knowledge of the target libc's FE_* values, so they are limited to expand only to suitable libcs. [1] https://sourceware.org/legacy-ml/libc-alpha/2020-03/msg00047.html https://sourceware.org/legacy-ml/libc-alpha/2020-03/msg00080.html 2020-08-13 Raoni Fassina Firmino <raoni@linux.ibm.com> gcc/ PR target/94193 * builtins.cc (expand_builtin_fegetround): New function. (expand_builtin_feclear_feraise_except): New function. (expand_builtin): Add cases for BUILT_IN_FEGETROUND, BUILT_IN_FECLEAREXCEPT and BUILT_IN_FERAISEEXCEPT. * config/rs6000/rs6000.md (fegetroundsi): New pattern. (feclearexceptsi): New Pattern. (feraiseexceptsi): New Pattern. * doc/extend.texi: Add a new introductory paragraph about the new builtins. * doc/md.texi: (fegetround@var{m}): Document new optab. (feclearexcept@var{m}): Document new optab. (feraiseexcept@var{m}): Document new optab. * optabs.def (fegetround_optab): New optab. (feclearexcept_optab): New optab. (feraiseexcept_optab): New optab. gcc/testsuite/ PR target/94193 * gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-1.c: New test. * gcc.target/powerpc/builtin-feclearexcept-feraiseexcept-2.c: New test. * gcc.target/powerpc/builtin-fegetround.c: New test. Signed-off-by: Raoni Fassina Firmino <raoni@linux.ibm.com>
Diffstat (limited to 'gcc/builtins.cc')
-rw-r--r--gcc/builtins.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index bf07341..e842080 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -119,6 +119,9 @@ static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
static rtx expand_builtin_interclass_mathfn (tree, rtx);
static rtx expand_builtin_sincos (tree);
+static rtx expand_builtin_fegetround (tree, rtx, machine_mode);
+static rtx expand_builtin_feclear_feraise_except (tree, rtx, machine_mode,
+ optab);
static rtx expand_builtin_cexpi (tree, rtx);
static rtx expand_builtin_int_roundingfn (tree, rtx);
static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
@@ -2555,6 +2558,59 @@ expand_builtin_sincos (tree exp)
return const0_rtx;
}
+/* Expand call EXP to the fegetround builtin (from C99 fenv.h), returning the
+ result and setting it in TARGET. Otherwise return NULL_RTX on failure. */
+static rtx
+expand_builtin_fegetround (tree exp, rtx target, machine_mode target_mode)
+{
+ if (!validate_arglist (exp, VOID_TYPE))
+ return NULL_RTX;
+
+ insn_code icode = direct_optab_handler (fegetround_optab, SImode);
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ if (target == 0
+ || GET_MODE (target) != target_mode
+ || !(*insn_data[icode].operand[0].predicate) (target, target_mode))
+ target = gen_reg_rtx (target_mode);
+
+ rtx pat = GEN_FCN (icode) (target);
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ return target;
+}
+
+/* Expand call EXP to either feclearexcept or feraiseexcept builtins (from C99
+ fenv.h), returning the result and setting it in TARGET. Otherwise return
+ NULL_RTX on failure. */
+static rtx
+expand_builtin_feclear_feraise_except (tree exp, rtx target,
+ machine_mode target_mode, optab op_optab)
+{
+ if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+ rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
+
+ insn_code icode = direct_optab_handler (op_optab, SImode);
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ if (target == 0
+ || GET_MODE (target) != target_mode
+ || !(*insn_data[icode].operand[0].predicate) (target, target_mode))
+ target = gen_reg_rtx (target_mode);
+
+ rtx pat = GEN_FCN (icode) (target, op0);
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ return target;
+}
+
/* Expand a call to the internal cexpi builtin to the sincos math function.
EXP is the expression that is a call to the builtin function; if convenient,
the result should be placed in TARGET. */
@@ -7056,6 +7112,26 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
return target;
break;
+ case BUILT_IN_FEGETROUND:
+ target = expand_builtin_fegetround (exp, target, target_mode);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FECLEAREXCEPT:
+ target = expand_builtin_feclear_feraise_except (exp, target, target_mode,
+ feclearexcept_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FERAISEEXCEPT:
+ target = expand_builtin_feclear_feraise_except (exp, target, target_mode,
+ feraiseexcept_optab);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_APPLY_ARGS:
return expand_builtin_apply_args ();