1 /* Constant folding for calls to built-in and internal functions.
2    Copyright (C) 1988-2019 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "realmpfr.h"
24 #include "tree.h"
25 #include "stor-layout.h"
26 #include "options.h"
27 #include "fold-const.h"
28 #include "fold-const-call.h"
29 #include "case-cfn-macros.h"
30 #include "tm.h" /* For C[LT]Z_DEFINED_AT_ZERO.  */
31 #include "builtins.h"
32 #include "gimple-expr.h"
33 #include "tree-vector-builder.h"
34 
35 /* Functions that test for certain constant types, abstracting away the
36    decision about whether to check for overflow.  */
37 
38 static inline bool
integer_cst_p(tree t)39 integer_cst_p (tree t)
40 {
41   return TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t);
42 }
43 
44 static inline bool
real_cst_p(tree t)45 real_cst_p (tree t)
46 {
47   return TREE_CODE (t) == REAL_CST && !TREE_OVERFLOW (t);
48 }
49 
50 static inline bool
complex_cst_p(tree t)51 complex_cst_p (tree t)
52 {
53   return TREE_CODE (t) == COMPLEX_CST;
54 }
55 
56 /* Return true if ARG is a constant in the range of the host size_t.
57    Store it in *SIZE_OUT if so.  */
58 
59 static inline bool
host_size_t_cst_p(tree t,size_t * size_out)60 host_size_t_cst_p (tree t, size_t *size_out)
61 {
62   if (types_compatible_p (size_type_node, TREE_TYPE (t))
63       && integer_cst_p (t)
64       && (wi::min_precision (wi::to_wide (t), UNSIGNED)
65 	  <= sizeof (size_t) * CHAR_BIT))
66     {
67       *size_out = tree_to_uhwi (t);
68       return true;
69     }
70   return false;
71 }
72 
73 /* RES is the result of a comparison in which < 0 means "less", 0 means
74    "equal" and > 0 means "more".  Canonicalize it to -1, 0 or 1 and
75    return it in type TYPE.  */
76 
77 tree
build_cmp_result(tree type,int res)78 build_cmp_result (tree type, int res)
79 {
80   return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
81 }
82 
83 /* M is the result of trying to constant-fold an expression (starting
84    with clear MPFR flags) and INEXACT says whether the result in M is
85    exact or inexact.  Return true if M can be used as a constant-folded
86    result in format FORMAT, storing the value in *RESULT if so.  */
87 
88 static bool
do_mpfr_ckconv(real_value * result,mpfr_srcptr m,bool inexact,const real_format * format)89 do_mpfr_ckconv (real_value *result, mpfr_srcptr m, bool inexact,
90 		const real_format *format)
91 {
92   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
93      overflow/underflow occurred.  If -frounding-math, proceed iff the
94      result of calling FUNC was exact.  */
95   if (!mpfr_number_p (m)
96       || mpfr_overflow_p ()
97       || mpfr_underflow_p ()
98       || (flag_rounding_math && inexact))
99     return false;
100 
101   REAL_VALUE_TYPE tmp;
102   real_from_mpfr (&tmp, m, format, GMP_RNDN);
103 
104   /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values.
105      If the REAL_VALUE_TYPE is zero but the mpft_t is not, then we
106      underflowed in the conversion.  */
107   if (!real_isfinite (&tmp)
108       || ((tmp.cl == rvc_zero) != (mpfr_zero_p (m) != 0)))
109     return false;
110 
111   real_convert (result, format, &tmp);
112   return real_identical (result, &tmp);
113 }
114 
115 /* Try to evaluate:
116 
117       *RESULT = f (*ARG)
118 
119    in format FORMAT, given that FUNC is the MPFR implementation of f.
120    Return true on success.  */
121 
122 static bool
do_mpfr_arg1(real_value * result,int (* func)(mpfr_ptr,mpfr_srcptr,mpfr_rnd_t),const real_value * arg,const real_format * format)123 do_mpfr_arg1 (real_value *result,
124 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
125 	      const real_value *arg, const real_format *format)
126 {
127   /* To proceed, MPFR must exactly represent the target floating point
128      format, which only happens when the target base equals two.  */
129   if (format->b != 2 || !real_isfinite (arg))
130     return false;
131 
132   int prec = format->p;
133   mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
134   mpfr_t m;
135 
136   mpfr_init2 (m, prec);
137   mpfr_from_real (m, arg, GMP_RNDN);
138   mpfr_clear_flags ();
139   bool inexact = func (m, m, rnd);
140   bool ok = do_mpfr_ckconv (result, m, inexact, format);
141   mpfr_clear (m);
142 
143   return ok;
144 }
145 
146 /* Try to evaluate:
147 
148       *RESULT_SIN = sin (*ARG);
149       *RESULT_COS = cos (*ARG);
150 
151    for format FORMAT.  Return true on success.  */
152 
153 static bool
do_mpfr_sincos(real_value * result_sin,real_value * result_cos,const real_value * arg,const real_format * format)154 do_mpfr_sincos (real_value *result_sin, real_value *result_cos,
155 		const real_value *arg, const real_format *format)
156 {
157   /* To proceed, MPFR must exactly represent the target floating point
158      format, which only happens when the target base equals two.  */
159   if (format->b != 2 || !real_isfinite (arg))
160     return false;
161 
162   int prec = format->p;
163   mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
164   mpfr_t m, ms, mc;
165 
166   mpfr_inits2 (prec, m, ms, mc, NULL);
167   mpfr_from_real (m, arg, GMP_RNDN);
168   mpfr_clear_flags ();
169   bool inexact = mpfr_sin_cos (ms, mc, m, rnd);
170   bool ok = (do_mpfr_ckconv (result_sin, ms, inexact, format)
171 	     && do_mpfr_ckconv (result_cos, mc, inexact, format));
172   mpfr_clears (m, ms, mc, NULL);
173 
174   return ok;
175 }
176 
177 /* Try to evaluate:
178 
179       *RESULT = f (*ARG0, *ARG1)
180 
181    in format FORMAT, given that FUNC is the MPFR implementation of f.
182    Return true on success.  */
183 
184 static bool
do_mpfr_arg2(real_value * result,int (* func)(mpfr_ptr,mpfr_srcptr,mpfr_srcptr,mpfr_rnd_t),const real_value * arg0,const real_value * arg1,const real_format * format)185 do_mpfr_arg2 (real_value *result,
186 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t),
187 	      const real_value *arg0, const real_value *arg1,
188 	      const real_format *format)
189 {
190   /* To proceed, MPFR must exactly represent the target floating point
191      format, which only happens when the target base equals two.  */
192   if (format->b != 2 || !real_isfinite (arg0) || !real_isfinite (arg1))
193     return false;
194 
195   int prec = format->p;
196   mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
197   mpfr_t m0, m1;
198 
199   mpfr_inits2 (prec, m0, m1, NULL);
200   mpfr_from_real (m0, arg0, GMP_RNDN);
201   mpfr_from_real (m1, arg1, GMP_RNDN);
202   mpfr_clear_flags ();
203   bool inexact = func (m0, m0, m1, rnd);
204   bool ok = do_mpfr_ckconv (result, m0, inexact, format);
205   mpfr_clears (m0, m1, NULL);
206 
207   return ok;
208 }
209 
210 /* Try to evaluate:
211 
212       *RESULT = f (ARG0, *ARG1)
213 
214    in format FORMAT, given that FUNC is the MPFR implementation of f.
215    Return true on success.  */
216 
217 static bool
do_mpfr_arg2(real_value * result,int (* func)(mpfr_ptr,long,mpfr_srcptr,mp_rnd_t),const wide_int_ref & arg0,const real_value * arg1,const real_format * format)218 do_mpfr_arg2 (real_value *result,
219 	      int (*func) (mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
220 	      const wide_int_ref &arg0, const real_value *arg1,
221 	      const real_format *format)
222 {
223   if (format->b != 2 || !real_isfinite (arg1))
224     return false;
225 
226   int prec = format->p;
227   mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
228   mpfr_t m;
229 
230   mpfr_init2 (m, prec);
231   mpfr_from_real (m, arg1, GMP_RNDN);
232   mpfr_clear_flags ();
233   bool inexact = func (m, arg0.to_shwi (), m, rnd);
234   bool ok = do_mpfr_ckconv (result, m, inexact, format);
235   mpfr_clear (m);
236 
237   return ok;
238 }
239 
240 /* Try to evaluate:
241 
242       *RESULT = f (*ARG0, *ARG1, *ARG2)
243 
244    in format FORMAT, given that FUNC is the MPFR implementation of f.
245    Return true on success.  */
246 
247 static bool
do_mpfr_arg3(real_value * result,int (* func)(mpfr_ptr,mpfr_srcptr,mpfr_srcptr,mpfr_srcptr,mpfr_rnd_t),const real_value * arg0,const real_value * arg1,const real_value * arg2,const real_format * format)248 do_mpfr_arg3 (real_value *result,
249 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
250 			   mpfr_srcptr, mpfr_rnd_t),
251 	      const real_value *arg0, const real_value *arg1,
252 	      const real_value *arg2, const real_format *format)
253 {
254   /* To proceed, MPFR must exactly represent the target floating point
255      format, which only happens when the target base equals two.  */
256   if (format->b != 2
257       || !real_isfinite (arg0)
258       || !real_isfinite (arg1)
259       || !real_isfinite (arg2))
260     return false;
261 
262   int prec = format->p;
263   mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
264   mpfr_t m0, m1, m2;
265 
266   mpfr_inits2 (prec, m0, m1, m2, NULL);
267   mpfr_from_real (m0, arg0, GMP_RNDN);
268   mpfr_from_real (m1, arg1, GMP_RNDN);
269   mpfr_from_real (m2, arg2, GMP_RNDN);
270   mpfr_clear_flags ();
271   bool inexact = func (m0, m0, m1, m2, rnd);
272   bool ok = do_mpfr_ckconv (result, m0, inexact, format);
273   mpfr_clears (m0, m1, m2, NULL);
274 
275   return ok;
276 }
277 
278 /* M is the result of trying to constant-fold an expression (starting
279    with clear MPFR flags) and INEXACT says whether the result in M is
280    exact or inexact.  Return true if M can be used as a constant-folded
281    result in which the real and imaginary parts have format FORMAT.
282    Store those parts in *RESULT_REAL and *RESULT_IMAG if so.  */
283 
284 static bool
do_mpc_ckconv(real_value * result_real,real_value * result_imag,mpc_srcptr m,bool inexact,const real_format * format)285 do_mpc_ckconv (real_value *result_real, real_value *result_imag,
286 	       mpc_srcptr m, bool inexact, const real_format *format)
287 {
288   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
289      overflow/underflow occurred.  If -frounding-math, proceed iff the
290      result of calling FUNC was exact.  */
291   if (!mpfr_number_p (mpc_realref (m))
292       || !mpfr_number_p (mpc_imagref (m))
293       || mpfr_overflow_p ()
294       || mpfr_underflow_p ()
295       || (flag_rounding_math && inexact))
296     return false;
297 
298   REAL_VALUE_TYPE tmp_real, tmp_imag;
299   real_from_mpfr (&tmp_real, mpc_realref (m), format, GMP_RNDN);
300   real_from_mpfr (&tmp_imag, mpc_imagref (m), format, GMP_RNDN);
301 
302   /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values.
303      If the REAL_VALUE_TYPE is zero but the mpft_t is not, then we
304      underflowed in the conversion.  */
305   if (!real_isfinite (&tmp_real)
306       || !real_isfinite (&tmp_imag)
307       || (tmp_real.cl == rvc_zero) != (mpfr_zero_p (mpc_realref (m)) != 0)
308       || (tmp_imag.cl == rvc_zero) != (mpfr_zero_p (mpc_imagref (m)) != 0))
309     return false;
310 
311   real_convert (result_real, format, &tmp_real);
312   real_convert (result_imag, format, &tmp_imag);
313 
314   return (real_identical (result_real, &tmp_real)
315 	  && real_identical (result_imag, &tmp_imag));
316 }
317 
318 /* Try to evaluate:
319 
320       RESULT = f (ARG)
321 
322    in format FORMAT, given that FUNC is the mpc implementation of f.
323    Return true on success.  Both RESULT and ARG are represented as
324    real and imaginary pairs.  */
325 
326 static bool
do_mpc_arg1(real_value * result_real,real_value * result_imag,int (* func)(mpc_ptr,mpc_srcptr,mpc_rnd_t),const real_value * arg_real,const real_value * arg_imag,const real_format * format)327 do_mpc_arg1 (real_value *result_real, real_value *result_imag,
328 	     int (*func) (mpc_ptr, mpc_srcptr, mpc_rnd_t),
329 	     const real_value *arg_real, const real_value *arg_imag,
330 	     const real_format *format)
331 {
332   /* To proceed, MPFR must exactly represent the target floating point
333      format, which only happens when the target base equals two.  */
334   if (format->b != 2
335       || !real_isfinite (arg_real)
336       || !real_isfinite (arg_imag))
337     return false;
338 
339   int prec = format->p;
340   mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
341   mpc_t m;
342 
343   mpc_init2 (m, prec);
344   mpfr_from_real (mpc_realref (m), arg_real, GMP_RNDN);
345   mpfr_from_real (mpc_imagref (m), arg_imag, GMP_RNDN);
346   mpfr_clear_flags ();
347   bool inexact = func (m, m, crnd);
348   bool ok = do_mpc_ckconv (result_real, result_imag, m, inexact, format);
349   mpc_clear (m);
350 
351   return ok;
352 }
353 
354 /* Try to evaluate:
355 
356       RESULT = f (ARG0, ARG1)
357 
358    in format FORMAT, given that FUNC is the mpc implementation of f.
359    Return true on success.  RESULT, ARG0 and ARG1 are represented as
360    real and imaginary pairs.  */
361 
362 static bool
do_mpc_arg2(real_value * result_real,real_value * result_imag,int (* func)(mpc_ptr,mpc_srcptr,mpc_srcptr,mpc_rnd_t),const real_value * arg0_real,const real_value * arg0_imag,const real_value * arg1_real,const real_value * arg1_imag,const real_format * format)363 do_mpc_arg2 (real_value *result_real, real_value *result_imag,
364 	     int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t),
365 	     const real_value *arg0_real, const real_value *arg0_imag,
366 	     const real_value *arg1_real, const real_value *arg1_imag,
367 	     const real_format *format)
368 {
369   if (!real_isfinite (arg0_real)
370       || !real_isfinite (arg0_imag)
371       || !real_isfinite (arg1_real)
372       || !real_isfinite (arg1_imag))
373     return false;
374 
375   int prec = format->p;
376   mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
377   mpc_t m0, m1;
378 
379   mpc_init2 (m0, prec);
380   mpc_init2 (m1, prec);
381   mpfr_from_real (mpc_realref (m0), arg0_real, GMP_RNDN);
382   mpfr_from_real (mpc_imagref (m0), arg0_imag, GMP_RNDN);
383   mpfr_from_real (mpc_realref (m1), arg1_real, GMP_RNDN);
384   mpfr_from_real (mpc_imagref (m1), arg1_imag, GMP_RNDN);
385   mpfr_clear_flags ();
386   bool inexact = func (m0, m0, m1, crnd);
387   bool ok = do_mpc_ckconv (result_real, result_imag, m0, inexact, format);
388   mpc_clear (m0);
389   mpc_clear (m1);
390 
391   return ok;
392 }
393 
394 /* Try to evaluate:
395 
396       *RESULT = logb (*ARG)
397 
398    in format FORMAT.  Return true on success.  */
399 
400 static bool
fold_const_logb(real_value * result,const real_value * arg,const real_format * format)401 fold_const_logb (real_value *result, const real_value *arg,
402 		 const real_format *format)
403 {
404   switch (arg->cl)
405     {
406     case rvc_nan:
407       /* If arg is +-NaN, then return it.  */
408       *result = *arg;
409       return true;
410 
411     case rvc_inf:
412       /* If arg is +-Inf, then return +Inf.  */
413       *result = *arg;
414       result->sign = 0;
415       return true;
416 
417     case rvc_zero:
418       /* Zero may set errno and/or raise an exception.  */
419       return false;
420 
421     case rvc_normal:
422       /* For normal numbers, proceed iff radix == 2.  In GCC,
423 	 normalized significands are in the range [0.5, 1.0).  We
424 	 want the exponent as if they were [1.0, 2.0) so get the
425 	 exponent and subtract 1.  */
426       if (format->b == 2)
427 	{
428 	  real_from_integer (result, format, REAL_EXP (arg) - 1, SIGNED);
429 	  return true;
430 	}
431       return false;
432     }
433   gcc_unreachable ();
434 }
435 
436 /* Try to evaluate:
437 
438       *RESULT = significand (*ARG)
439 
440    in format FORMAT.  Return true on success.  */
441 
442 static bool
fold_const_significand(real_value * result,const real_value * arg,const real_format * format)443 fold_const_significand (real_value *result, const real_value *arg,
444 			const real_format *format)
445 {
446   switch (arg->cl)
447     {
448     case rvc_zero:
449     case rvc_nan:
450     case rvc_inf:
451       /* If arg is +-0, +-Inf or +-NaN, then return it.  */
452       *result = *arg;
453       return true;
454 
455     case rvc_normal:
456       /* For normal numbers, proceed iff radix == 2.  */
457       if (format->b == 2)
458 	{
459 	  *result = *arg;
460 	  /* In GCC, normalized significands are in the range [0.5, 1.0).
461 	     We want them to be [1.0, 2.0) so set the exponent to 1.  */
462 	  SET_REAL_EXP (result, 1);
463 	  return true;
464 	}
465       return false;
466     }
467   gcc_unreachable ();
468 }
469 
470 /* Try to evaluate:
471 
472       *RESULT = f (*ARG)
473 
474    where FORMAT is the format of *ARG and PRECISION is the number of
475    significant bits in the result.  Return true on success.  */
476 
477 static bool
fold_const_conversion(wide_int * result,void (* fn)(real_value *,format_helper,const real_value *),const real_value * arg,unsigned int precision,const real_format * format)478 fold_const_conversion (wide_int *result,
479 		       void (*fn) (real_value *, format_helper,
480 				   const real_value *),
481 		       const real_value *arg, unsigned int precision,
482 		       const real_format *format)
483 {
484   if (!real_isfinite (arg))
485     return false;
486 
487   real_value rounded;
488   fn (&rounded, format, arg);
489 
490   bool fail = false;
491   *result = real_to_integer (&rounded, &fail, precision);
492   return !fail;
493 }
494 
495 /* Try to evaluate:
496 
497       *RESULT = pow (*ARG0, *ARG1)
498 
499    in format FORMAT.  Return true on success.  */
500 
501 static bool
fold_const_pow(real_value * result,const real_value * arg0,const real_value * arg1,const real_format * format)502 fold_const_pow (real_value *result, const real_value *arg0,
503 		const real_value *arg1, const real_format *format)
504 {
505   if (do_mpfr_arg2 (result, mpfr_pow, arg0, arg1, format))
506     return true;
507 
508   /* Check for an integer exponent.  */
509   REAL_VALUE_TYPE cint1;
510   HOST_WIDE_INT n1 = real_to_integer (arg1);
511   real_from_integer (&cint1, VOIDmode, n1, SIGNED);
512   /* Attempt to evaluate pow at compile-time, unless this should
513      raise an exception.  */
514   if (real_identical (arg1, &cint1)
515       && (n1 > 0
516 	  || (!flag_trapping_math && !flag_errno_math)
517 	  || !real_equal (arg0, &dconst0)))
518     {
519       bool inexact = real_powi (result, format, arg0, n1);
520       /* Avoid the folding if flag_signaling_nans is on.  */
521       if (flag_unsafe_math_optimizations
522 	  || (!inexact
523 	      && !(flag_signaling_nans
524 	           && REAL_VALUE_ISSIGNALING_NAN (*arg0))))
525 	return true;
526     }
527 
528   return false;
529 }
530 
531 /* Try to evaluate:
532 
533       *RESULT = nextafter (*ARG0, *ARG1)
534 
535    or
536 
537       *RESULT = nexttoward (*ARG0, *ARG1)
538 
539    in format FORMAT.  Return true on success.  */
540 
541 static bool
fold_const_nextafter(real_value * result,const real_value * arg0,const real_value * arg1,const real_format * format)542 fold_const_nextafter (real_value *result, const real_value *arg0,
543 		      const real_value *arg1, const real_format *format)
544 {
545   if (REAL_VALUE_ISSIGNALING_NAN (*arg0)
546       || REAL_VALUE_ISSIGNALING_NAN (*arg1))
547     return false;
548 
549   /* Don't handle composite modes, nor decimal, nor modes without
550      inf or denorm at least for now.  */
551   if (format->pnan < format->p
552       || format->b == 10
553       || !format->has_inf
554       || !format->has_denorm)
555     return false;
556 
557   if (real_nextafter (result, format, arg0, arg1)
558       /* If raising underflow or overflow and setting errno to ERANGE,
559 	 fail if we care about those side-effects.  */
560       && (flag_trapping_math || flag_errno_math))
561     return false;
562   /* Similarly for nextafter (0, 1) raising underflow.  */
563   else if (flag_trapping_math
564 	   && arg0->cl == rvc_zero
565 	   && result->cl != rvc_zero)
566     return false;
567 
568   real_convert (result, format, result);
569 
570   return true;
571 }
572 
573 /* Try to evaluate:
574 
575       *RESULT = ldexp (*ARG0, ARG1)
576 
577    in format FORMAT.  Return true on success.  */
578 
579 static bool
fold_const_builtin_load_exponent(real_value * result,const real_value * arg0,const wide_int_ref & arg1,const real_format * format)580 fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
581 				  const wide_int_ref &arg1,
582 				  const real_format *format)
583 {
584   /* Bound the maximum adjustment to twice the range of the
585      mode's valid exponents.  Use abs to ensure the range is
586      positive as a sanity check.  */
587   int max_exp_adj = 2 * labs (format->emax - format->emin);
588 
589   /* The requested adjustment must be inside this range.  This
590      is a preliminary cap to avoid things like overflow, we
591      may still fail to compute the result for other reasons.  */
592   if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj))
593     return false;
594 
595   /* Don't perform operation if we honor signaling NaNs and
596      operand is a signaling NaN.  */
597   if (!flag_unsafe_math_optimizations
598       && flag_signaling_nans
599       && REAL_VALUE_ISSIGNALING_NAN (*arg0))
600     return false;
601 
602   REAL_VALUE_TYPE initial_result;
603   real_ldexp (&initial_result, arg0, arg1.to_shwi ());
604 
605   /* Ensure we didn't overflow.  */
606   if (real_isinf (&initial_result))
607     return false;
608 
609   /* Only proceed if the target mode can hold the
610      resulting value.  */
611   *result = real_value_truncate (format, initial_result);
612   return real_equal (&initial_result, result);
613 }
614 
615 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG and
616    return type TYPE.  QUIET is true if a quiet rather than signalling
617    NaN is required.  */
618 
619 static tree
fold_const_builtin_nan(tree type,tree arg,bool quiet)620 fold_const_builtin_nan (tree type, tree arg, bool quiet)
621 {
622   REAL_VALUE_TYPE real;
623   const char *str = c_getstr (arg);
624   if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
625     return build_real (type, real);
626   return NULL_TREE;
627 }
628 
629 /* Fold a call to IFN_REDUC_<CODE> (ARG), returning a value of type TYPE.  */
630 
631 static tree
fold_const_reduction(tree type,tree arg,tree_code code)632 fold_const_reduction (tree type, tree arg, tree_code code)
633 {
634   unsigned HOST_WIDE_INT nelts;
635   if (TREE_CODE (arg) != VECTOR_CST
636       || !VECTOR_CST_NELTS (arg).is_constant (&nelts))
637     return NULL_TREE;
638 
639   tree res = VECTOR_CST_ELT (arg, 0);
640   for (unsigned HOST_WIDE_INT i = 1; i < nelts; i++)
641     {
642       res = const_binop (code, type, res, VECTOR_CST_ELT (arg, i));
643       if (res == NULL_TREE || !CONSTANT_CLASS_P (res))
644 	return NULL_TREE;
645     }
646   return res;
647 }
648 
649 /* Fold a call to IFN_VEC_CONVERT (ARG) returning TYPE.  */
650 
651 static tree
fold_const_vec_convert(tree ret_type,tree arg)652 fold_const_vec_convert (tree ret_type, tree arg)
653 {
654   enum tree_code code = NOP_EXPR;
655   tree arg_type = TREE_TYPE (arg);
656   if (TREE_CODE (arg) != VECTOR_CST)
657     return NULL_TREE;
658 
659   gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type));
660 
661   if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
662       && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type)))
663     code = FIX_TRUNC_EXPR;
664   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
665 	   && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type)))
666     code = FLOAT_EXPR;
667 
668   /* We can't handle steps directly when extending, since the
669      values need to wrap at the original precision first.  */
670   bool step_ok_p
671     = (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
672        && INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
673        && (TYPE_PRECISION (TREE_TYPE (ret_type))
674 	   <= TYPE_PRECISION (TREE_TYPE (arg_type))));
675   tree_vector_builder elts;
676   if (!elts.new_unary_operation (ret_type, arg, step_ok_p))
677     return NULL_TREE;
678 
679   unsigned int count = elts.encoded_nelts ();
680   for (unsigned int i = 0; i < count; ++i)
681     {
682       tree elt = fold_unary (code, TREE_TYPE (ret_type),
683 			     VECTOR_CST_ELT (arg, i));
684       if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
685 	return NULL_TREE;
686       elts.quick_push (elt);
687     }
688 
689   return elts.build ();
690 }
691 
692 /* Try to evaluate:
693 
694       *RESULT = FN (*ARG)
695 
696    in format FORMAT.  Return true on success.  */
697 
698 static bool
fold_const_call_ss(real_value * result,combined_fn fn,const real_value * arg,const real_format * format)699 fold_const_call_ss (real_value *result, combined_fn fn,
700 		    const real_value *arg, const real_format *format)
701 {
702   switch (fn)
703     {
704     CASE_CFN_SQRT:
705     CASE_CFN_SQRT_FN:
706       return (real_compare (GE_EXPR, arg, &dconst0)
707 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
708 
709     CASE_CFN_CBRT:
710       return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
711 
712     CASE_CFN_ASIN:
713       return (real_compare (GE_EXPR, arg, &dconstm1)
714 	      && real_compare (LE_EXPR, arg, &dconst1)
715 	      && do_mpfr_arg1 (result, mpfr_asin, arg, format));
716 
717     CASE_CFN_ACOS:
718       return (real_compare (GE_EXPR, arg, &dconstm1)
719 	      && real_compare (LE_EXPR, arg, &dconst1)
720 	      && do_mpfr_arg1 (result, mpfr_acos, arg, format));
721 
722     CASE_CFN_ATAN:
723       return do_mpfr_arg1 (result, mpfr_atan, arg, format);
724 
725     CASE_CFN_ASINH:
726       return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
727 
728     CASE_CFN_ACOSH:
729       return (real_compare (GE_EXPR, arg, &dconst1)
730 	      && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
731 
732     CASE_CFN_ATANH:
733       return (real_compare (GE_EXPR, arg, &dconstm1)
734 	      && real_compare (LE_EXPR, arg, &dconst1)
735 	      && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
736 
737     CASE_CFN_SIN:
738       return do_mpfr_arg1 (result, mpfr_sin, arg, format);
739 
740     CASE_CFN_COS:
741       return do_mpfr_arg1 (result, mpfr_cos, arg, format);
742 
743     CASE_CFN_TAN:
744       return do_mpfr_arg1 (result, mpfr_tan, arg, format);
745 
746     CASE_CFN_SINH:
747       return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
748 
749     CASE_CFN_COSH:
750       return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
751 
752     CASE_CFN_TANH:
753       return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
754 
755     CASE_CFN_ERF:
756       return do_mpfr_arg1 (result, mpfr_erf, arg, format);
757 
758     CASE_CFN_ERFC:
759       return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
760 
761     CASE_CFN_TGAMMA:
762       return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
763 
764     CASE_CFN_EXP:
765       return do_mpfr_arg1 (result, mpfr_exp, arg, format);
766 
767     CASE_CFN_EXP2:
768       return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
769 
770     CASE_CFN_EXP10:
771     CASE_CFN_POW10:
772       return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
773 
774     CASE_CFN_EXPM1:
775       return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
776 
777     CASE_CFN_LOG:
778       return (real_compare (GT_EXPR, arg, &dconst0)
779 	      && do_mpfr_arg1 (result, mpfr_log, arg, format));
780 
781     CASE_CFN_LOG2:
782       return (real_compare (GT_EXPR, arg, &dconst0)
783 	      && do_mpfr_arg1 (result, mpfr_log2, arg, format));
784 
785     CASE_CFN_LOG10:
786       return (real_compare (GT_EXPR, arg, &dconst0)
787 	      && do_mpfr_arg1 (result, mpfr_log10, arg, format));
788 
789     CASE_CFN_LOG1P:
790       return (real_compare (GT_EXPR, arg, &dconstm1)
791 	      && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
792 
793     CASE_CFN_J0:
794       return do_mpfr_arg1 (result, mpfr_j0, arg, format);
795 
796     CASE_CFN_J1:
797       return do_mpfr_arg1 (result, mpfr_j1, arg, format);
798 
799     CASE_CFN_Y0:
800       return (real_compare (GT_EXPR, arg, &dconst0)
801 	      && do_mpfr_arg1 (result, mpfr_y0, arg, format));
802 
803     CASE_CFN_Y1:
804       return (real_compare (GT_EXPR, arg, &dconst0)
805 	      && do_mpfr_arg1 (result, mpfr_y1, arg, format));
806 
807     CASE_CFN_FLOOR:
808     CASE_CFN_FLOOR_FN:
809       if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
810 	{
811 	  real_floor (result, format, arg);
812 	  return true;
813 	}
814       return false;
815 
816     CASE_CFN_CEIL:
817     CASE_CFN_CEIL_FN:
818       if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
819 	{
820 	  real_ceil (result, format, arg);
821 	  return true;
822 	}
823       return false;
824 
825     CASE_CFN_TRUNC:
826     CASE_CFN_TRUNC_FN:
827       real_trunc (result, format, arg);
828       return true;
829 
830     CASE_CFN_ROUND:
831     CASE_CFN_ROUND_FN:
832       if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
833 	{
834 	  real_round (result, format, arg);
835 	  return true;
836 	}
837       return false;
838 
839     CASE_CFN_LOGB:
840       return fold_const_logb (result, arg, format);
841 
842     CASE_CFN_SIGNIFICAND:
843       return fold_const_significand (result, arg, format);
844 
845     default:
846       return false;
847     }
848 }
849 
850 /* Try to evaluate:
851 
852       *RESULT = FN (*ARG)
853 
854    where FORMAT is the format of ARG and PRECISION is the number of
855    significant bits in the result.  Return true on success.  */
856 
857 static bool
fold_const_call_ss(wide_int * result,combined_fn fn,const real_value * arg,unsigned int precision,const real_format * format)858 fold_const_call_ss (wide_int *result, combined_fn fn,
859 		    const real_value *arg, unsigned int precision,
860 		    const real_format *format)
861 {
862   switch (fn)
863     {
864     CASE_CFN_SIGNBIT:
865       if (real_isneg (arg))
866 	*result = wi::one (precision);
867       else
868 	*result = wi::zero (precision);
869       return true;
870 
871     CASE_CFN_ILOGB:
872       /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
873 	 Proceed iff radix == 2.  In GCC, normalized significands are in
874 	 the range [0.5, 1.0).  We want the exponent as if they were
875 	 [1.0, 2.0) so get the exponent and subtract 1.  */
876       if (arg->cl == rvc_normal && format->b == 2)
877 	{
878 	  *result = wi::shwi (REAL_EXP (arg) - 1, precision);
879 	  return true;
880 	}
881       return false;
882 
883     CASE_CFN_ICEIL:
884     CASE_CFN_LCEIL:
885     CASE_CFN_LLCEIL:
886       return fold_const_conversion (result, real_ceil, arg,
887 				    precision, format);
888 
889     CASE_CFN_LFLOOR:
890     CASE_CFN_IFLOOR:
891     CASE_CFN_LLFLOOR:
892       return fold_const_conversion (result, real_floor, arg,
893 				    precision, format);
894 
895     CASE_CFN_IROUND:
896     CASE_CFN_LROUND:
897     CASE_CFN_LLROUND:
898       return fold_const_conversion (result, real_round, arg,
899 				    precision, format);
900 
901     CASE_CFN_IRINT:
902     CASE_CFN_LRINT:
903     CASE_CFN_LLRINT:
904       /* Not yet folded to a constant.  */
905       return false;
906 
907     CASE_CFN_FINITE:
908     case CFN_BUILT_IN_FINITED32:
909     case CFN_BUILT_IN_FINITED64:
910     case CFN_BUILT_IN_FINITED128:
911     case CFN_BUILT_IN_ISFINITE:
912       *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
913       return true;
914 
915     CASE_CFN_ISINF:
916     case CFN_BUILT_IN_ISINFD32:
917     case CFN_BUILT_IN_ISINFD64:
918     case CFN_BUILT_IN_ISINFD128:
919       if (real_isinf (arg))
920 	*result = wi::shwi (arg->sign ? -1 : 1, precision);
921       else
922 	*result = wi::shwi (0, precision);
923       return true;
924 
925     CASE_CFN_ISNAN:
926     case CFN_BUILT_IN_ISNAND32:
927     case CFN_BUILT_IN_ISNAND64:
928     case CFN_BUILT_IN_ISNAND128:
929       *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
930       return true;
931 
932     default:
933       return false;
934     }
935 }
936 
937 /* Try to evaluate:
938 
939       *RESULT = FN (ARG)
940 
941    where ARG_TYPE is the type of ARG and PRECISION is the number of bits
942    in the result.  Return true on success.  */
943 
944 static bool
fold_const_call_ss(wide_int * result,combined_fn fn,const wide_int_ref & arg,unsigned int precision,tree arg_type)945 fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
946 		    unsigned int precision, tree arg_type)
947 {
948   switch (fn)
949     {
950     CASE_CFN_FFS:
951       *result = wi::shwi (wi::ffs (arg), precision);
952       return true;
953 
954     CASE_CFN_CLZ:
955       {
956 	int tmp;
957 	if (wi::ne_p (arg, 0))
958 	  tmp = wi::clz (arg);
959 	else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
960 					     tmp))
961 	  tmp = TYPE_PRECISION (arg_type);
962 	*result = wi::shwi (tmp, precision);
963 	return true;
964       }
965 
966     CASE_CFN_CTZ:
967       {
968 	int tmp;
969 	if (wi::ne_p (arg, 0))
970 	  tmp = wi::ctz (arg);
971 	else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
972 					     tmp))
973 	  tmp = TYPE_PRECISION (arg_type);
974 	*result = wi::shwi (tmp, precision);
975 	return true;
976       }
977 
978     CASE_CFN_CLRSB:
979       *result = wi::shwi (wi::clrsb (arg), precision);
980       return true;
981 
982     CASE_CFN_POPCOUNT:
983       *result = wi::shwi (wi::popcount (arg), precision);
984       return true;
985 
986     CASE_CFN_PARITY:
987       *result = wi::shwi (wi::parity (arg), precision);
988       return true;
989 
990     case CFN_BUILT_IN_BSWAP16:
991     case CFN_BUILT_IN_BSWAP32:
992     case CFN_BUILT_IN_BSWAP64:
993       *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
994       return true;
995 
996     default:
997       return false;
998     }
999 }
1000 
1001 /* Try to evaluate:
1002 
1003       RESULT = FN (*ARG)
1004 
1005    where FORMAT is the format of ARG and of the real and imaginary parts
1006    of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively.  Return
1007    true on success.  */
1008 
1009 static bool
fold_const_call_cs(real_value * result_real,real_value * result_imag,combined_fn fn,const real_value * arg,const real_format * format)1010 fold_const_call_cs (real_value *result_real, real_value *result_imag,
1011 		    combined_fn fn, const real_value *arg,
1012 		    const real_format *format)
1013 {
1014   switch (fn)
1015     {
1016     CASE_CFN_CEXPI:
1017       /* cexpi(x+yi) = cos(x)+sin(y)*i.  */
1018       return do_mpfr_sincos (result_imag, result_real, arg, format);
1019 
1020     default:
1021       return false;
1022     }
1023 }
1024 
1025 /* Try to evaluate:
1026 
1027       *RESULT = fn (ARG)
1028 
1029    where FORMAT is the format of RESULT and of the real and imaginary parts
1030    of ARG, passed as ARG_REAL and ARG_IMAG respectively.  Return true on
1031    success.  */
1032 
1033 static bool
fold_const_call_sc(real_value * result,combined_fn fn,const real_value * arg_real,const real_value * arg_imag,const real_format * format)1034 fold_const_call_sc (real_value *result, combined_fn fn,
1035 		    const real_value *arg_real, const real_value *arg_imag,
1036 		    const real_format *format)
1037 {
1038   switch (fn)
1039     {
1040     CASE_CFN_CABS:
1041       return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
1042 
1043     default:
1044       return false;
1045     }
1046 }
1047 
1048 /* Try to evaluate:
1049 
1050       RESULT = fn (ARG)
1051 
1052    where FORMAT is the format of the real and imaginary parts of RESULT
1053    (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
1054    Return true on success.  */
1055 
1056 static bool
fold_const_call_cc(real_value * result_real,real_value * result_imag,combined_fn fn,const real_value * arg_real,const real_value * arg_imag,const real_format * format)1057 fold_const_call_cc (real_value *result_real, real_value *result_imag,
1058 		    combined_fn fn, const real_value *arg_real,
1059 		    const real_value *arg_imag, const real_format *format)
1060 {
1061   switch (fn)
1062     {
1063     CASE_CFN_CCOS:
1064       return do_mpc_arg1 (result_real, result_imag, mpc_cos,
1065 			  arg_real, arg_imag, format);
1066 
1067     CASE_CFN_CCOSH:
1068       return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
1069 			  arg_real, arg_imag, format);
1070 
1071     CASE_CFN_CPROJ:
1072       if (real_isinf (arg_real) || real_isinf (arg_imag))
1073 	{
1074 	  real_inf (result_real);
1075 	  *result_imag = dconst0;
1076 	  result_imag->sign = arg_imag->sign;
1077 	}
1078       else
1079 	{
1080 	  *result_real = *arg_real;
1081 	  *result_imag = *arg_imag;
1082 	}
1083       return true;
1084 
1085     CASE_CFN_CSIN:
1086       return do_mpc_arg1 (result_real, result_imag, mpc_sin,
1087 			  arg_real, arg_imag, format);
1088 
1089     CASE_CFN_CSINH:
1090       return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
1091 			  arg_real, arg_imag, format);
1092 
1093     CASE_CFN_CTAN:
1094       return do_mpc_arg1 (result_real, result_imag, mpc_tan,
1095 			  arg_real, arg_imag, format);
1096 
1097     CASE_CFN_CTANH:
1098       return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
1099 			  arg_real, arg_imag, format);
1100 
1101     CASE_CFN_CLOG:
1102       return do_mpc_arg1 (result_real, result_imag, mpc_log,
1103 			  arg_real, arg_imag, format);
1104 
1105     CASE_CFN_CSQRT:
1106       return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
1107 			  arg_real, arg_imag, format);
1108 
1109     CASE_CFN_CASIN:
1110       return do_mpc_arg1 (result_real, result_imag, mpc_asin,
1111 			  arg_real, arg_imag, format);
1112 
1113     CASE_CFN_CACOS:
1114       return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1115 			  arg_real, arg_imag, format);
1116 
1117     CASE_CFN_CATAN:
1118       return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1119 			  arg_real, arg_imag, format);
1120 
1121     CASE_CFN_CASINH:
1122       return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1123 			  arg_real, arg_imag, format);
1124 
1125     CASE_CFN_CACOSH:
1126       return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1127 			  arg_real, arg_imag, format);
1128 
1129     CASE_CFN_CATANH:
1130       return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1131 			  arg_real, arg_imag, format);
1132 
1133     CASE_CFN_CEXP:
1134       return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1135 			  arg_real, arg_imag, format);
1136 
1137     default:
1138       return false;
1139     }
1140 }
1141 
1142 /* Subroutine of fold_const_call, with the same interface.  Handle cases
1143    where the arguments and result are numerical.  */
1144 
1145 static tree
fold_const_call_1(combined_fn fn,tree type,tree arg)1146 fold_const_call_1 (combined_fn fn, tree type, tree arg)
1147 {
1148   machine_mode mode = TYPE_MODE (type);
1149   machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1150 
1151   if (integer_cst_p (arg))
1152     {
1153       if (SCALAR_INT_MODE_P (mode))
1154 	{
1155 	  wide_int result;
1156 	  if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
1157 				  TYPE_PRECISION (type), TREE_TYPE (arg)))
1158 	    return wide_int_to_tree (type, result);
1159 	}
1160       return NULL_TREE;
1161     }
1162 
1163   if (real_cst_p (arg))
1164     {
1165       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1166       if (mode == arg_mode)
1167 	{
1168 	  /* real -> real.  */
1169 	  REAL_VALUE_TYPE result;
1170 	  if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1171 				  REAL_MODE_FORMAT (mode)))
1172 	    return build_real (type, result);
1173 	}
1174       else if (COMPLEX_MODE_P (mode)
1175 	       && GET_MODE_INNER (mode) == arg_mode)
1176 	{
1177 	  /* real -> complex real.  */
1178 	  REAL_VALUE_TYPE result_real, result_imag;
1179 	  if (fold_const_call_cs (&result_real, &result_imag, fn,
1180 				  TREE_REAL_CST_PTR (arg),
1181 				  REAL_MODE_FORMAT (arg_mode)))
1182 	    return build_complex (type,
1183 				  build_real (TREE_TYPE (type), result_real),
1184 				  build_real (TREE_TYPE (type), result_imag));
1185 	}
1186       else if (INTEGRAL_TYPE_P (type))
1187 	{
1188 	  /* real -> int.  */
1189 	  wide_int result;
1190 	  if (fold_const_call_ss (&result, fn,
1191 				  TREE_REAL_CST_PTR (arg),
1192 				  TYPE_PRECISION (type),
1193 				  REAL_MODE_FORMAT (arg_mode)))
1194 	    return wide_int_to_tree (type, result);
1195 	}
1196       return NULL_TREE;
1197     }
1198 
1199   if (complex_cst_p (arg))
1200     {
1201       gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1202       machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1203       tree argr = TREE_REALPART (arg);
1204       tree argi = TREE_IMAGPART (arg);
1205       if (mode == arg_mode
1206 	  && real_cst_p (argr)
1207 	  && real_cst_p (argi))
1208 	{
1209 	  /* complex real -> complex real.  */
1210 	  REAL_VALUE_TYPE result_real, result_imag;
1211 	  if (fold_const_call_cc (&result_real, &result_imag, fn,
1212 				  TREE_REAL_CST_PTR (argr),
1213 				  TREE_REAL_CST_PTR (argi),
1214 				  REAL_MODE_FORMAT (inner_mode)))
1215 	    return build_complex (type,
1216 				  build_real (TREE_TYPE (type), result_real),
1217 				  build_real (TREE_TYPE (type), result_imag));
1218 	}
1219       if (mode == inner_mode
1220 	  && real_cst_p (argr)
1221 	  && real_cst_p (argi))
1222 	{
1223 	  /* complex real -> real.  */
1224 	  REAL_VALUE_TYPE result;
1225 	  if (fold_const_call_sc (&result, fn,
1226 				  TREE_REAL_CST_PTR (argr),
1227 				  TREE_REAL_CST_PTR (argi),
1228 				  REAL_MODE_FORMAT (inner_mode)))
1229 	    return build_real (type, result);
1230 	}
1231       return NULL_TREE;
1232     }
1233 
1234   return NULL_TREE;
1235 }
1236 
1237 /* Try to fold FN (ARG) to a constant.  Return the constant on success,
1238    otherwise return null.  TYPE is the type of the return value.  */
1239 
1240 tree
fold_const_call(combined_fn fn,tree type,tree arg)1241 fold_const_call (combined_fn fn, tree type, tree arg)
1242 {
1243   switch (fn)
1244     {
1245     case CFN_BUILT_IN_STRLEN:
1246       if (const char *str = c_getstr (arg))
1247 	return build_int_cst (type, strlen (str));
1248       return NULL_TREE;
1249 
1250     CASE_CFN_NAN:
1251     CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1252     case CFN_BUILT_IN_NAND32:
1253     case CFN_BUILT_IN_NAND64:
1254     case CFN_BUILT_IN_NAND128:
1255       return fold_const_builtin_nan (type, arg, true);
1256 
1257     CASE_CFN_NANS:
1258     CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1259       return fold_const_builtin_nan (type, arg, false);
1260 
1261     case CFN_REDUC_PLUS:
1262       return fold_const_reduction (type, arg, PLUS_EXPR);
1263 
1264     case CFN_REDUC_MAX:
1265       return fold_const_reduction (type, arg, MAX_EXPR);
1266 
1267     case CFN_REDUC_MIN:
1268       return fold_const_reduction (type, arg, MIN_EXPR);
1269 
1270     case CFN_REDUC_AND:
1271       return fold_const_reduction (type, arg, BIT_AND_EXPR);
1272 
1273     case CFN_REDUC_IOR:
1274       return fold_const_reduction (type, arg, BIT_IOR_EXPR);
1275 
1276     case CFN_REDUC_XOR:
1277       return fold_const_reduction (type, arg, BIT_XOR_EXPR);
1278 
1279     case CFN_VEC_CONVERT:
1280       return fold_const_vec_convert (type, arg);
1281 
1282     default:
1283       return fold_const_call_1 (fn, type, arg);
1284     }
1285 }
1286 
1287 /* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value
1288    of type TYPE.  */
1289 
1290 static tree
fold_const_fold_left(tree type,tree arg0,tree arg1,tree_code code)1291 fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
1292 {
1293   if (TREE_CODE (arg1) != VECTOR_CST)
1294     return NULL_TREE;
1295 
1296   unsigned HOST_WIDE_INT nelts;
1297   if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts))
1298     return NULL_TREE;
1299 
1300   for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++)
1301     {
1302       arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i));
1303       if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0))
1304 	return NULL_TREE;
1305     }
1306   return arg0;
1307 }
1308 
1309 /* Try to evaluate:
1310 
1311       *RESULT = FN (*ARG0, *ARG1)
1312 
1313    in format FORMAT.  Return true on success.  */
1314 
1315 static bool
fold_const_call_sss(real_value * result,combined_fn fn,const real_value * arg0,const real_value * arg1,const real_format * format)1316 fold_const_call_sss (real_value *result, combined_fn fn,
1317 		     const real_value *arg0, const real_value *arg1,
1318 		     const real_format *format)
1319 {
1320   switch (fn)
1321     {
1322     CASE_CFN_DREM:
1323     CASE_CFN_REMAINDER:
1324       return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1325 
1326     CASE_CFN_ATAN2:
1327       return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1328 
1329     CASE_CFN_FDIM:
1330       return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1331 
1332     CASE_CFN_HYPOT:
1333       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1334 
1335     CASE_CFN_COPYSIGN:
1336     CASE_CFN_COPYSIGN_FN:
1337       *result = *arg0;
1338       real_copysign (result, arg1);
1339       return true;
1340 
1341     CASE_CFN_FMIN:
1342     CASE_CFN_FMIN_FN:
1343       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1344 
1345     CASE_CFN_FMAX:
1346     CASE_CFN_FMAX_FN:
1347       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1348 
1349     CASE_CFN_POW:
1350       return fold_const_pow (result, arg0, arg1, format);
1351 
1352     CASE_CFN_NEXTAFTER:
1353     CASE_CFN_NEXTTOWARD:
1354       return fold_const_nextafter (result, arg0, arg1, format);
1355 
1356     default:
1357       return false;
1358     }
1359 }
1360 
1361 /* Try to evaluate:
1362 
1363       *RESULT = FN (*ARG0, ARG1)
1364 
1365    where FORMAT is the format of *RESULT and *ARG0.  Return true on
1366    success.  */
1367 
1368 static bool
fold_const_call_sss(real_value * result,combined_fn fn,const real_value * arg0,const wide_int_ref & arg1,const real_format * format)1369 fold_const_call_sss (real_value *result, combined_fn fn,
1370 		     const real_value *arg0, const wide_int_ref &arg1,
1371 		     const real_format *format)
1372 {
1373   switch (fn)
1374     {
1375     CASE_CFN_LDEXP:
1376       return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1377 
1378     CASE_CFN_SCALBN:
1379     CASE_CFN_SCALBLN:
1380       return (format->b == 2
1381 	      && fold_const_builtin_load_exponent (result, arg0, arg1,
1382 						   format));
1383 
1384     CASE_CFN_POWI:
1385       /* Avoid the folding if flag_signaling_nans is on and
1386          operand is a signaling NaN.  */
1387       if (!flag_unsafe_math_optimizations
1388 	  && flag_signaling_nans
1389 	  && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1390         return false;
1391 
1392       real_powi (result, format, arg0, arg1.to_shwi ());
1393       return true;
1394 
1395     default:
1396       return false;
1397     }
1398 }
1399 
1400 /* Try to evaluate:
1401 
1402       *RESULT = FN (ARG0, *ARG1)
1403 
1404    where FORMAT is the format of *RESULT and *ARG1.  Return true on
1405    success.  */
1406 
1407 static bool
fold_const_call_sss(real_value * result,combined_fn fn,const wide_int_ref & arg0,const real_value * arg1,const real_format * format)1408 fold_const_call_sss (real_value *result, combined_fn fn,
1409 		     const wide_int_ref &arg0, const real_value *arg1,
1410 		     const real_format *format)
1411 {
1412   switch (fn)
1413     {
1414     CASE_CFN_JN:
1415       return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1416 
1417     CASE_CFN_YN:
1418       return (real_compare (GT_EXPR, arg1, &dconst0)
1419 	      && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1420 
1421     default:
1422       return false;
1423     }
1424 }
1425 
1426 /* Try to evaluate:
1427 
1428       RESULT = fn (ARG0, ARG1)
1429 
1430    where FORMAT is the format of the real and imaginary parts of RESULT
1431    (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1432    and of ARG1 (ARG1_REAL and ARG1_IMAG).  Return true on success.  */
1433 
1434 static bool
fold_const_call_ccc(real_value * result_real,real_value * result_imag,combined_fn fn,const real_value * arg0_real,const real_value * arg0_imag,const real_value * arg1_real,const real_value * arg1_imag,const real_format * format)1435 fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1436 		     combined_fn fn, const real_value *arg0_real,
1437 		     const real_value *arg0_imag, const real_value *arg1_real,
1438 		     const real_value *arg1_imag, const real_format *format)
1439 {
1440   switch (fn)
1441     {
1442     CASE_CFN_CPOW:
1443       return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1444 			  arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1445 
1446     default:
1447       return false;
1448     }
1449 }
1450 
1451 /* Subroutine of fold_const_call, with the same interface.  Handle cases
1452    where the arguments and result are numerical.  */
1453 
1454 static tree
fold_const_call_1(combined_fn fn,tree type,tree arg0,tree arg1)1455 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
1456 {
1457   machine_mode mode = TYPE_MODE (type);
1458   machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1459   machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1460 
1461   if (mode == arg0_mode
1462       && real_cst_p (arg0)
1463       && real_cst_p (arg1))
1464     {
1465       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1466       REAL_VALUE_TYPE result;
1467       if (arg0_mode == arg1_mode)
1468 	{
1469 	  /* real, real -> real.  */
1470 	  if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1471 				   TREE_REAL_CST_PTR (arg1),
1472 				   REAL_MODE_FORMAT (mode)))
1473 	    return build_real (type, result);
1474 	}
1475       else if (arg1_mode == TYPE_MODE (long_double_type_node))
1476 	switch (fn)
1477 	  {
1478 	  CASE_CFN_NEXTTOWARD:
1479 	    /* real, long double -> real.  */
1480 	    if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1481 				     TREE_REAL_CST_PTR (arg1),
1482 				     REAL_MODE_FORMAT (mode)))
1483 	      return build_real (type, result);
1484 	    break;
1485 	  default:
1486 	    break;
1487 	  }
1488       return NULL_TREE;
1489     }
1490 
1491   if (real_cst_p (arg0)
1492       && integer_cst_p (arg1))
1493     {
1494       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1495       if (mode == arg0_mode)
1496 	{
1497 	  /* real, int -> real.  */
1498 	  REAL_VALUE_TYPE result;
1499 	  if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1500 				   wi::to_wide (arg1),
1501 				   REAL_MODE_FORMAT (mode)))
1502 	    return build_real (type, result);
1503 	}
1504       return NULL_TREE;
1505     }
1506 
1507   if (integer_cst_p (arg0)
1508       && real_cst_p (arg1))
1509     {
1510       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1511       if (mode == arg1_mode)
1512 	{
1513 	  /* int, real -> real.  */
1514 	  REAL_VALUE_TYPE result;
1515 	  if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
1516 				   TREE_REAL_CST_PTR (arg1),
1517 				   REAL_MODE_FORMAT (mode)))
1518 	    return build_real (type, result);
1519 	}
1520       return NULL_TREE;
1521     }
1522 
1523   if (arg0_mode == arg1_mode
1524       && complex_cst_p (arg0)
1525       && complex_cst_p (arg1))
1526     {
1527       gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1528       machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1529       tree arg0r = TREE_REALPART (arg0);
1530       tree arg0i = TREE_IMAGPART (arg0);
1531       tree arg1r = TREE_REALPART (arg1);
1532       tree arg1i = TREE_IMAGPART (arg1);
1533       if (mode == arg0_mode
1534 	  && real_cst_p (arg0r)
1535 	  && real_cst_p (arg0i)
1536 	  && real_cst_p (arg1r)
1537 	  && real_cst_p (arg1i))
1538 	{
1539 	  /* complex real, complex real -> complex real.  */
1540 	  REAL_VALUE_TYPE result_real, result_imag;
1541 	  if (fold_const_call_ccc (&result_real, &result_imag, fn,
1542 				   TREE_REAL_CST_PTR (arg0r),
1543 				   TREE_REAL_CST_PTR (arg0i),
1544 				   TREE_REAL_CST_PTR (arg1r),
1545 				   TREE_REAL_CST_PTR (arg1i),
1546 				   REAL_MODE_FORMAT (inner_mode)))
1547 	    return build_complex (type,
1548 				  build_real (TREE_TYPE (type), result_real),
1549 				  build_real (TREE_TYPE (type), result_imag));
1550 	}
1551       return NULL_TREE;
1552     }
1553 
1554   return NULL_TREE;
1555 }
1556 
1557 /* Try to fold FN (ARG0, ARG1) to a constant.  Return the constant on success,
1558    otherwise return null.  TYPE is the type of the return value.  */
1559 
1560 tree
fold_const_call(combined_fn fn,tree type,tree arg0,tree arg1)1561 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1562 {
1563   const char *p0, *p1;
1564   char c;
1565   switch (fn)
1566     {
1567     case CFN_BUILT_IN_STRSPN:
1568       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1569 	return build_int_cst (type, strspn (p0, p1));
1570       return NULL_TREE;
1571 
1572     case CFN_BUILT_IN_STRCSPN:
1573       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1574 	return build_int_cst (type, strcspn (p0, p1));
1575       return NULL_TREE;
1576 
1577     case CFN_BUILT_IN_STRCMP:
1578       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1579 	return build_cmp_result (type, strcmp (p0, p1));
1580       return NULL_TREE;
1581 
1582     case CFN_BUILT_IN_STRCASECMP:
1583       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1584 	{
1585 	  int r = strcmp (p0, p1);
1586 	  if (r == 0)
1587 	    return build_cmp_result (type, r);
1588 	}
1589       return NULL_TREE;
1590 
1591     case CFN_BUILT_IN_INDEX:
1592     case CFN_BUILT_IN_STRCHR:
1593       if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1594 	{
1595 	  const char *r = strchr (p0, c);
1596 	  if (r == NULL)
1597 	    return build_int_cst (type, 0);
1598 	  return fold_convert (type,
1599 			       fold_build_pointer_plus_hwi (arg0, r - p0));
1600 	}
1601       return NULL_TREE;
1602 
1603     case CFN_BUILT_IN_RINDEX:
1604     case CFN_BUILT_IN_STRRCHR:
1605       if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1606 	{
1607 	  const char *r = strrchr (p0, c);
1608 	  if (r == NULL)
1609 	    return build_int_cst (type, 0);
1610 	  return fold_convert (type,
1611 			       fold_build_pointer_plus_hwi (arg0, r - p0));
1612 	}
1613       return NULL_TREE;
1614 
1615     case CFN_BUILT_IN_STRSTR:
1616       if ((p1 = c_getstr (arg1)))
1617 	{
1618 	  if ((p0 = c_getstr (arg0)))
1619 	    {
1620 	      const char *r = strstr (p0, p1);
1621 	      if (r == NULL)
1622 		return build_int_cst (type, 0);
1623 	      return fold_convert (type,
1624 				   fold_build_pointer_plus_hwi (arg0, r - p0));
1625 	    }
1626 	  if (*p1 == '\0')
1627 	    return fold_convert (type, arg0);
1628 	}
1629       return NULL_TREE;
1630 
1631     case CFN_FOLD_LEFT_PLUS:
1632       return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
1633 
1634     default:
1635       return fold_const_call_1 (fn, type, arg0, arg1);
1636     }
1637 }
1638 
1639 /* Try to evaluate:
1640 
1641       *RESULT = FN (*ARG0, *ARG1, *ARG2)
1642 
1643    in format FORMAT.  Return true on success.  */
1644 
1645 static bool
fold_const_call_ssss(real_value * result,combined_fn fn,const real_value * arg0,const real_value * arg1,const real_value * arg2,const real_format * format)1646 fold_const_call_ssss (real_value *result, combined_fn fn,
1647 		      const real_value *arg0, const real_value *arg1,
1648 		      const real_value *arg2, const real_format *format)
1649 {
1650   switch (fn)
1651     {
1652     CASE_CFN_FMA:
1653     CASE_CFN_FMA_FN:
1654       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1655 
1656     case CFN_FMS:
1657       {
1658 	real_value new_arg2 = real_value_negate (arg2);
1659 	return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, &new_arg2, format);
1660       }
1661 
1662     case CFN_FNMA:
1663       {
1664 	real_value new_arg0 = real_value_negate (arg0);
1665 	return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1, arg2, format);
1666       }
1667 
1668     case CFN_FNMS:
1669       {
1670 	real_value new_arg0 = real_value_negate (arg0);
1671 	real_value new_arg2 = real_value_negate (arg2);
1672 	return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1,
1673 			     &new_arg2, format);
1674       }
1675 
1676     default:
1677       return false;
1678     }
1679 }
1680 
1681 /* Subroutine of fold_const_call, with the same interface.  Handle cases
1682    where the arguments and result are numerical.  */
1683 
1684 static tree
fold_const_call_1(combined_fn fn,tree type,tree arg0,tree arg1,tree arg2)1685 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1686 {
1687   machine_mode mode = TYPE_MODE (type);
1688   machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1689   machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1690   machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1691 
1692   if (arg0_mode == arg1_mode
1693       && arg0_mode == arg2_mode
1694       && real_cst_p (arg0)
1695       && real_cst_p (arg1)
1696       && real_cst_p (arg2))
1697     {
1698       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1699       if (mode == arg0_mode)
1700 	{
1701 	  /* real, real, real -> real.  */
1702 	  REAL_VALUE_TYPE result;
1703 	  if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1704 				    TREE_REAL_CST_PTR (arg1),
1705 				    TREE_REAL_CST_PTR (arg2),
1706 				    REAL_MODE_FORMAT (mode)))
1707 	    return build_real (type, result);
1708 	}
1709       return NULL_TREE;
1710     }
1711 
1712   return NULL_TREE;
1713 }
1714 
1715 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant.  Return the constant on
1716    success, otherwise return null.  TYPE is the type of the return value.  */
1717 
1718 tree
fold_const_call(combined_fn fn,tree type,tree arg0,tree arg1,tree arg2)1719 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1720 {
1721   const char *p0, *p1;
1722   char c;
1723   unsigned HOST_WIDE_INT s0, s1;
1724   size_t s2 = 0;
1725   switch (fn)
1726     {
1727     case CFN_BUILT_IN_STRNCMP:
1728       if (!host_size_t_cst_p (arg2, &s2))
1729 	return NULL_TREE;
1730       if (s2 == 0
1731 	  && !TREE_SIDE_EFFECTS (arg0)
1732 	  && !TREE_SIDE_EFFECTS (arg1))
1733 	return build_int_cst (type, 0);
1734       else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1735 	return build_int_cst (type, strncmp (p0, p1, s2));
1736       return NULL_TREE;
1737 
1738     case CFN_BUILT_IN_STRNCASECMP:
1739       if (!host_size_t_cst_p (arg2, &s2))
1740 	return NULL_TREE;
1741       if (s2 == 0
1742 	  && !TREE_SIDE_EFFECTS (arg0)
1743 	  && !TREE_SIDE_EFFECTS (arg1))
1744 	return build_int_cst (type, 0);
1745       else if ((p0 = c_getstr (arg0))
1746 	       && (p1 = c_getstr (arg1))
1747 	       && strncmp (p0, p1, s2) == 0)
1748 	return build_int_cst (type, 0);
1749       return NULL_TREE;
1750 
1751     case CFN_BUILT_IN_BCMP:
1752     case CFN_BUILT_IN_MEMCMP:
1753       if (!host_size_t_cst_p (arg2, &s2))
1754 	return NULL_TREE;
1755       if (s2 == 0
1756 	  && !TREE_SIDE_EFFECTS (arg0)
1757 	  && !TREE_SIDE_EFFECTS (arg1))
1758 	return build_int_cst (type, 0);
1759       if ((p0 = c_getstr (arg0, &s0))
1760 	  && (p1 = c_getstr (arg1, &s1))
1761 	  && s2 <= s0
1762 	  && s2 <= s1)
1763 	return build_cmp_result (type, memcmp (p0, p1, s2));
1764       return NULL_TREE;
1765 
1766     case CFN_BUILT_IN_MEMCHR:
1767       if (!host_size_t_cst_p (arg2, &s2))
1768 	return NULL_TREE;
1769       if (s2 == 0
1770 	  && !TREE_SIDE_EFFECTS (arg0)
1771 	  && !TREE_SIDE_EFFECTS (arg1))
1772 	return build_int_cst (type, 0);
1773       if ((p0 = c_getstr (arg0, &s0))
1774 	  && s2 <= s0
1775 	  && target_char_cst_p (arg1, &c))
1776 	{
1777 	  const char *r = (const char *) memchr (p0, c, s2);
1778 	  if (r == NULL)
1779 	    return build_int_cst (type, 0);
1780 	  return fold_convert (type,
1781 			       fold_build_pointer_plus_hwi (arg0, r - p0));
1782 	}
1783       return NULL_TREE;
1784 
1785     default:
1786       return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1787     }
1788 }
1789