To...
To: gcc-patches@gcc.gnu.org Subject: Add an extra pow rule to match.pd From: Richard Sandiford <richard.sandiford@arm.com> Gcc: private.sent --text follows this line-- Simplify pow(|x|,y) and pow(-x,y) to pow(x,y) if y is an even integer. At the moment this duplicates a case in fold_builtin_pow, but an upcoming patch will move all the fold_builtin_pow rules to match.pd. I'm doing this one early to fix a regression in builtin-10.c for soft-float ARM. gcc/ * real.h (real_isinteger): Declare. * real.c (real_isinteger): New function. * match.pd: Simplify pow(|x|,y) and pow(-x,y) to pow(x,y) if y is an even integer. From-SVN: r228750
This commit is contained in:
parent
6696de8a7f
commit
9b054b0881
|
@ -1,3 +1,10 @@
|
|||
2015-10-13 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* real.h (real_isinteger): Declare.
|
||||
* real.c (real_isinteger): New function.
|
||||
* match.pd: Simplify pow(|x|,y) and pow(-x,y) to pow(x,y)
|
||||
if y is an even integer.
|
||||
|
||||
2015-10-11 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
revert:
|
||||
|
|
17
gcc/match.pd
17
gcc/match.pd
|
@ -309,12 +309,19 @@ along with GCC; see the file COPYING3. If not see
|
|||
&& TYPE_OVERFLOW_UNDEFINED (type))
|
||||
@0)))
|
||||
|
||||
/* Simplify cos (-x) -> cos (x). */
|
||||
(for op (negate abs)
|
||||
(for coss (COS COSH)
|
||||
(simplify
|
||||
(coss (op @0))
|
||||
(coss @0))))
|
||||
/* Simplify cos(-x) and cos(|x|) -> cos(x). Similarly for cosh. */
|
||||
(for coss (COS COSH)
|
||||
(simplify
|
||||
(coss (op @0))
|
||||
(coss @0)))
|
||||
/* Simplify pow(-x, y) and pow(|x|,y) -> pow(x,y) if y is an even integer. */
|
||||
(for pows (POW)
|
||||
(simplify
|
||||
(pows (op @0) REAL_CST@1)
|
||||
(with { HOST_WIDE_INT n; }
|
||||
(if (real_isinteger (&TREE_REAL_CST (@1), &n) && (n & 1) == 0)
|
||||
(pows @0 @1))))))
|
||||
|
||||
/* X % Y is smaller than Y. */
|
||||
(for cmp (lt ge)
|
||||
|
|
18
gcc/real.c
18
gcc/real.c
|
@ -4997,6 +4997,24 @@ real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode)
|
|||
return real_identical (c, &cint);
|
||||
}
|
||||
|
||||
/* Check whether C is an integer that fits in a HOST_WIDE_INT,
|
||||
storing it in *INT_OUT if so. */
|
||||
|
||||
bool
|
||||
real_isinteger (const REAL_VALUE_TYPE *c, HOST_WIDE_INT *int_out)
|
||||
{
|
||||
REAL_VALUE_TYPE cint;
|
||||
|
||||
HOST_WIDE_INT n = real_to_integer (c);
|
||||
real_from_integer (&cint, VOIDmode, n, SIGNED);
|
||||
if (real_identical (c, &cint))
|
||||
{
|
||||
*int_out = n;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Write into BUF the maximum representable finite floating-point
|
||||
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
|
||||
float string. LEN is the size of BUF, and the buffer must be large
|
||||
|
|
|
@ -467,7 +467,8 @@ extern void real_round (REAL_VALUE_TYPE *, machine_mode,
|
|||
extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
|
||||
|
||||
/* Check whether the real constant value given is an integer. */
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode);
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *, machine_mode);
|
||||
extern bool real_isinteger (const REAL_VALUE_TYPE *, HOST_WIDE_INT *);
|
||||
|
||||
/* Write into BUF the maximum representable finite floating-point
|
||||
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
|
||||
|
|
Loading…
Reference in New Issue