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:
Richard Sandiford 2015-10-13 07:34:41 +00:00 committed by Richard Sandiford
parent 6696de8a7f
commit 9b054b0881
4 changed files with 39 additions and 6 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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