Commit 9b054b08 by Richard Sandiford Committed by Richard Sandiford

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
parent 6696de8a
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> 2015-10-11 Jan Hubicka <hubicka@ucw.cz>
revert: revert:
...@@ -309,12 +309,19 @@ along with GCC; see the file COPYING3. If not see ...@@ -309,12 +309,19 @@ along with GCC; see the file COPYING3. If not see
&& TYPE_OVERFLOW_UNDEFINED (type)) && TYPE_OVERFLOW_UNDEFINED (type))
@0))) @0)))
/* Simplify cos (-x) -> cos (x). */
(for op (negate abs) (for op (negate abs)
(for coss (COS COSH) /* Simplify cos(-x) and cos(|x|) -> cos(x). Similarly for cosh. */
(simplify (for coss (COS COSH)
(coss (op @0)) (simplify
(coss @0)))) (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. */ /* X % Y is smaller than Y. */
(for cmp (lt ge) (for cmp (lt ge)
......
...@@ -4997,6 +4997,24 @@ real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode) ...@@ -4997,6 +4997,24 @@ real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode)
return real_identical (c, &cint); 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 /* Write into BUF the maximum representable finite floating-point
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex 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 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, ...@@ -467,7 +467,8 @@ extern void real_round (REAL_VALUE_TYPE *, machine_mode,
extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
/* Check whether the real constant value given is an integer. */ /* 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 /* Write into BUF the maximum representable finite floating-point
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment