+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:
&& 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)
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
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